Java swing jtabbedpane添加标签异常

时间:2015-01-14 00:14:59

标签: java swing concurrency

我有一个Java swing应用程序,它创建并显示一个tabbedpane并创建一个更新线程。触发时更新线程需要添加一组包含内容的选项卡,但我现在又一次得到异常"线程中的异常" AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException&#34 ;.

这是否与在不同线程中添加标签有关?如果是这样,我如何以线程安全的方式添加标签???

以下是说明问题的示例应用程序

public class Example extends JFrame implements Runnable {

    private final JTabbedPane tabbedPane;
    private final Rectangle bounds;

    public Example() {
        super("Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        bounds = new Rectangle(0, 0, 500, 500);
        setBounds(bounds);
        setLayout(null);

        tabbedPane = new JTabbedPane();
        tabbedPane.setBounds(bounds);

        JPanel jp = new JPanel();
        jp.setLayout(null);
        jp.setBounds(bounds);
        jp.add(tabbedPane);
        add(jp);

        new Thread(this).start();
    }

    @Override
    public void run() {
        while (true) {
            for (int i = 0; i < 3; i++) {
                tabbedPane.addTab("NEW" + i, new JPanel());
                repaint();
            }

            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(Example.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public static void main(String[] args) {
        Example e = new Example();
        e.setVisible(true);
    }
}

1 个答案:

答案 0 :(得分:1)

Swing不是线程安全的......

这意味着您永远不应该尝试从事件调度线程的上下文之外创建或修改UI。

可能的问题是你遇到某种竞争条件。有关详细信息,请查看Concurrency in SwingHow to use Swing Timers

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;

public class Example extends JFrame {

    private final JTabbedPane tabbedPane;
    private final Rectangle bounds;

    public Example() {
        super("Example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        bounds = new Rectangle(0, 0, 500, 500);
        setBounds(bounds);
//      setLayout(null);

        tabbedPane = new JTabbedPane();
        tabbedPane.setBounds(bounds);

//      JPanel jp = new JPanel();
//      jp.setLayout(null);
//      jp.setBounds(bounds);
//      jp.add(tabbedPane);
//      add(jp);

        add(tabbedPane);

        Timer timer = new Timer(50, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < 3; i++) {
                    tabbedPane.addTab("NEW" + tabbedPane.getTabCount(), new JPanel());
                }
                tabbedPane.revalidate();
            }
        });
        timer.start();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Example e = new Example();
                e.setVisible(true);
            }
        });
    }
}

避免使用null布局,像素完美布局是现代ui设计中的一种幻觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来纠正

请查看Laying Out Components Within a Container了解详情