haz hazzz
haz hazzz

Reputation: 113

Java swing tabbed pane add tab exception

I have a Java swing application that creates and displays a tabbedpane and creates an update thread. The update thread when triggered needs to add a set of tabs with content but I am getting an exception now and again "Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException".

Is this something to do with adding tabs in a different thread? If so how do I add a tab to it in a thread safe way please??

Here is an example application that illustrates the problem

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);
    }
}

Upvotes: 0

Views: 402

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

Swing is not thread safe...

This means that you should never try to create or modify the UI from outside the context of the Event Dispatching Thread.

The likely issue is you've run into some kind of race condition. Take a look at Concurrency in Swing and How to use Swing Timers for more details

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);
            }
        });
    }
}

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

Take a look at Laying Out Components Within a Container for more details

Upvotes: 1

Related Questions