需求如下:
      1、  需要在JComboBox 首次使用时加载本地系统盘符
      2、  因为本地系统盘符有可能增减(譬如插拔U盘),因此在每次使用JComboBox时更新列表问题:
      1、  在JComboBox 的哪个相应时间中加入代码
      2、  每次更新整个JComboBox 的model 还是只更新变化的部分。目前只会全部更新,谁会更新变化的部分一定要告诉我啊尝试过的方法
      1、  在ActionPerformed中添加 加载本地盘符代码————结果不起作用
      2、  在MousePressed中添加 加载本地盘符代码————结果能添加,但是每次自动选择第一个选项,通过强制setselectindex(-1) 后可以选择空现象,但是会自动激活ItemStateChanged,这个方法后面会用到
      3、   在ItemStateChanged 中添加更新列表代码————结果可以生效,但是因为MousePressed 设置index -1,所以虚添加代码屏蔽Item 为空。如果不设置index 为-1,则每次点击JComboBox,第一个Item为默认选择,所以不会触发ItemStateChanged 也就无法更新列表,无法完成需求。
虽然也现在也能够实现需求,但是在鼠标点击后会多运行一遍ItemStateChanged ,降低了程序效率,寻求更好的触发时间。另寻求根据盘符变化部分更新JComboBox 的内容的方法优化代码,提高执行效率
有经验的请赐教

解决方案 »

  1.   

    如果用itemstatechanged的话那效率最低, 因为假如用户不用鼠标而用上下键来选择盘符的话, 那每按一次上或者下都会触发itemstatechanged, 就是说都会更新一次盘符.
    用mousepress的会更新两次, 打开列表时一次, 选择完又一次. 加入你的JComboBox不是放在JFrame的第一位的话就建议你用FocusListener了, 缺点是只能在第一次点击或者Tab到JComboBox时更新盘符
    部分更新JComboBox内容的话用 removeItemAt 和 insertItemAt 就好了.写个例子给you.import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    public class Driver {
    static String[] list = {"c", "d", "e", "f"};
    static JComboBox box = new JComboBox(list);

    public static void main(String[] args) {
    JFrame f = new JFrame("JComboBoxTest");
    JTextField tf = new JTextField();

    box.setPreferredSize(new Dimension(200, 20));
    box.addFocusListener(new FocusListener() { @Override
    public void focusGained(FocusEvent e) {
    Object tmp = box.getItemAt(0);
    box.removeItemAt(0); //部分更新JComboBox
    box.insertItemAt(tmp, 2);
    } @Override
    public void focusLost(FocusEvent e) {

    }

    });

    f.add(tf);
    f.add(box, BorderLayout.SOUTH);
    f.pack();
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }
      

  2.   

    回1楼
    分析的不错,我用的触发事件是有问题
    FocusListener  可以实现,但是如果要弹出Dialog的话会出现死循环(如果光驱没插盘,我需要它弹出对话框提示——想想直接清空JTree也行,不过日后终归会遇到问题)
    对于部分更新部分:
    对于JComboBox 本身更新Item的方法我是知道的,问题是如何获得本地盘符与JComboBox内容不符的部分——需要更新的项譬如:
         1、初始       4个盘符:C D E F(F为U盘) 需要操作     加入JComboBox
        2、F 拔出     3个盘符:C D E        操作:   box.removeItemAt(0); 
        3、插入新设备 5个盘符:C D E F H   操作:    box.insertItemAt(F, 2);
                                                  box.insertItemAt(H, 3);
     
    如何判断盘符更新的部分,不会每次都和 JComboBox 内容比较一次吧,那我还不如每次都全部更新呢,毕竟Item 不多
      

  3.   

    或许有法子从系统挂钩中设置个Listener,当系统増、删 新硬件时触发不知道能不能实现 
      

  4.   

    弹出Dialog的话是lostFocus事件, 只要在lostFocus里加个停止循环的代码就好了解决这个问题要写个ComboModel, 很煎蛋的, 用ComboModel的话以后只要改变数组里的内容那JComboBox里的内容也会改变了, 不过最好改为用ArrayList, 用起来方便. 例子如下:import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.util.ArrayList;import javax.swing.ComboBoxModel;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.event.ListDataListener;
    public class Driver {
    static ArrayList<String> list;
    static JComboBox box;

    public static void main(String[] args) {
    JFrame f = new JFrame("JComboBoxTest");
    JTextField tf = new JTextField();

    list = new ArrayList<String>();

    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

    box = new JComboBox();

    box.setPreferredSize(new Dimension(200, 20));
    box.setModel(new ComboBoxModel() {

    private int selectedPos = 0; @Override
    public Object getSelectedItem() {
    return list.get(selectedPos);
    } @Override
    public void setSelectedItem(Object value) {
    selectedPos = list.indexOf(value);
    list.set(selectedPos, (String) value);

    } @Override
    public void addListDataListener(ListDataListener arg0) {

    } @Override
    public Object getElementAt(int pos) {
    return list.get(pos);
    } @Override
    public int getSize() {
    return list.size();
    } @Override
    public void removeListDataListener(ListDataListener arg0) {

    }

    });

    box.addFocusListener(new FocusListener() { @Override
    public void focusGained(FocusEvent e) {
    list.set(2, "z");
    } @Override
    public void focusLost(FocusEvent e) {

    } });

    f.add(tf);
    f.add(box, BorderLayout.SOUTH);
    f.pack();
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }
    这个就8会了....
      

  5.   

    改了改, 效果比较好, 改变的是输入框的内容 import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.util.ArrayList;

    import javax.swing.ComboBoxModel;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.event.ListDataListener;


    public class Driver {
    static ArrayList<String> list;
    static JComboBox box;
    static JTextField tf;

    public static void main(String[] args) {
    JFrame f = new JFrame("JComboBoxTest");
    tf = new JTextField();

    list = new ArrayList<String>();

    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

    box = new JComboBox();

    box.setPreferredSize(new Dimension(200, 20));
    box.setModel(new ComboBoxModel() {

    private int selectedPos = 0;

    @Override
    public Object getSelectedItem() {
    return list.get(selectedPos);
    }

    @Override
    public void setSelectedItem(Object value) {
    selectedPos = list.indexOf(value);
    list.set(selectedPos, (String) value);

    }

    @Override
    public void addListDataListener(ListDataListener arg0) {

    }

    @Override
    public Object getElementAt(int pos) {
    return list.get(pos);
    }

    @Override
    public int getSize() {
    return list.size();
    }

    @Override
    public void removeListDataListener(ListDataListener arg0) {

    }

    });

    box.addFocusListener(new FocusListener() {

    @Override
    public void focusGained(FocusEvent e) {
    list.set(2, tf.getText());
    }

    @Override
    public void focusLost(FocusEvent e) {

    }

    });

    f.add(tf);
    f.add(box, BorderLayout.SOUTH);
    f.pack();
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }