You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java AWT多选列表按选择顺序展示选中项功能异常调试求助

问题修复方案

原代码核心问题

  • removeElement方法存在致命语法错误:循环内ordered[i] = ordered[i++]同时对i做自增,导致数组元素移动逻辑完全失效,取消选中的项无法从有序记录数组中真正删除,后续重新选中时会被判定为已存在不会追加到队尾
  • 业务逻辑全部写在paint()方法中不合理:paint()是AWT框架用于界面重绘的回调,会被频繁触发,不适合存放选择顺序计算的业务逻辑
  • 变量命名不规范:l1、msg这类无意义命名可读性差,固定长度的数组ordered扩展性差
  • 数组遍历的边界逻辑存在漏洞,取消选中后索引调整会出现漏判

修复后可运行代码

import java.applet.Applet;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;

/*<applet code = "ListDemo" width = "500" height = "500"></applet>*/
public class ListDemo extends Applet implements ItemListener {
    // 变量命名语义化
    private List multiSelectList;
    // 按选择顺序存储选中项的索引,用ArrayList代替固定数组,无需自己实现增删逻辑
    private List<Integer> selectedOrder = new ArrayList<>();

    public void init() {
        // 第二个参数true表示允许多选
        multiSelectList = new List(3, true);
        multiSelectList.add("Java");
        multiSelectList.add("Advance Java");
        multiSelectList.add("OS");
        multiSelectList.add("Python");
        multiSelectList.add("JavaScript");
        multiSelectList.add("Data Structures");
        add(multiSelectList);
        multiSelectList.addItemListener(this);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        int changedIndex = (Integer) e.getItem();
        // 选中状态触发
        if (e.getStateChange() == ItemEvent.SELECTED) {
            // 先移除历史记录(避免重复,比如之前取消过再次选中的情况)
            selectedOrder.remove(Integer.valueOf(changedIndex));
            // 追加到末尾,保证顺序是最新选择的顺序
            selectedOrder.add(changedIndex);
        } 
        // 取消选中状态触发
        else if (e.getStateChange() == ItemEvent.DESELECTED) {
            // 直接从有序列表中移除该项
            selectedOrder.remove(Integer.valueOf(changedIndex));
        }
        // 触发重绘
        repaint();
    }

    @Override
    public void paint(Graphics g) {
        StringBuilder showMsg = new StringBuilder("The Selected Subjects are: ");
        // 按存储的顺序输出即可
        for (Integer index : selectedOrder) {
            String item = multiSelectList.getItem(index);
            showMsg.append(item).append(" ");
            // 同时打印到控制台
            System.out.println(item);
        }
        System.out.println("\n\n");
        g.drawString(showMsg.toString(), 10, 200);
    }
}

运行&优化说明

  • 仅支持Java 1.8及更早版本运行,执行命令:appletviewer ListDemo.java即可启动测试
  • 选中顺序完全遵循用户操作顺序:取消某一项后再次选中,该项会自动排在当前选中列表的末尾,符合需求
  • 代码规范优化点:
    1. 变量名全部语义化,方便后续维护
    2. 业务逻辑全部移到itemStateChanged回调中,仅在用户操作时计算一次,性能更优
    3. 用ArrayList替代固定长度数组,自动处理增删逻辑,避免手动操作数组的边界错误
    4. 用StringBuilder拼接字符串,性能优于字符串直接拼接

内容的提问来源于stack exchange,提问作者Cryptic Slays

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:06:00