JComboBox选择失败

时间:2013-06-27 13:14:58

标签: java swing jcombobox

如果我尝试通过不同的线程选择JComboBox的元素,则会导致非常奇怪的行为,几乎每次都会选择列表的最后一个元素。这是一个错误还是一个愚蠢的错误?

package com.test;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Test3 extends JFrame {
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Test3 frame = new Test3();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Test3() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 200, 80);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    String[] select = { "0", "1", "2", "3", "4" };
    final JComboBox<String> jb = new JComboBox<String>(select);
    contentPane.add(jb, BorderLayout.NORTH);

    new Thread() {
        int i = 0;

        public void run() {
            while (true) {
                i++;
                if (i > 4)
                    i = 0;
                jb.setSelectedIndex(i);
                System.out.println("SELECT " + i);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();

    setContentPane(contentPane);
}}

此示例显示了一个简单的JComboBox,其中包含由String-Array内部给出的5个元素。 每隔3秒,定义的线程在

的帮助下选择下一个项目
jb.setSelectedIndex(i);

并且控制台也会打印选择。运行该代码会显示上述奇怪的行为:控制台每3秒钟计算0-4,JComboBox大部分时间选择列表中的最后一个..

2 个答案:

答案 0 :(得分:0)

感谢您的帮助, 我找到的最简单的解决方法是让Swing处理这个问题:

package com.test;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class Test3 extends JFrame {
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Test3 frame = new Test3();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Test3() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 200, 80);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    String[] select = { "0", "1", "2", "3", "4" };
    final JComboBox<String> jb = new JComboBox<String>(select);
    contentPane.add(jb, BorderLayout.NORTH);

    new Thread() {
        int i = 0;

        public void run() {
            while (true) {
                i++;
                if (i > 4)
                    i = 0;
                System.out.println("SELECT " + i);
                try {
                    Thread.sleep(3000);
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            public void run() {
                                jb.setSelectedIndex(i);
                            }
                        });
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
    setContentPane(contentPane);
   }
}

答案 1 :(得分:0)

您需要使用invokeLater()将 JCombobox 更新置于事件调度线程中:

public Test3() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 200, 80);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    String[] select = { "0", "1", "2", "3", "4" };
    final JComboBox<String> jb = new JComboBox<String>(select);
    contentPane.add(jb, BorderLayout.NORTH);

    new Thread() {
        int i = 0;

        @Override
        public void run() {
            while (true) {
                i++;
                if (i > 4)
                    i = 0;

                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        jb.setSelectedIndex(i);

                    }
                });

                System.out.println("SELECT " + i);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();

    setContentPane(contentPane);
}}