Jan Oelker
Jan Oelker

Reputation: 884

Remove last tab of jtabbedpane

I am a bit confused, because I can't remove the last Tab of my JTabbedPane. I read this two questions: first question and second question. But it didnt helped to me. This is how my code looks like:

public void updateTabbedPane()
{
    // Remove the MouseListener
    tabbedPane.removeMouseListener(tabbedPaneMouseListener);

    // Remove all Tabs
    while (tabbedPane.getTabCount() > 0)
    {
        tabbedPane.remove(0);
    }

    // Sort the ArrayList
    Collections.sort(arrayList);

    // Add all Element to the JTabbedPane
    for (int i = 0; i < arrayList.size(); i++)
    {
        tabbedPane.addTab(arrayList.get(i).getName(),
                new JScrollPane(...);
    }

    // Add the MouseListiner to the JTabbedPane again
    tabbedPane.addMouseListener(tabbedPaneMouseListener);
}

I am using this method to add/remove a tab if an object was added/removed to the list. I also sort the ArrayList, because I want to have the tabs in an ascending order.

As said in the answers of the two questions, I removed the MouseListener before I remove the Tabs, but the last Tab is still visible in the end. I also tried to setVisible(), removeAll().

Any help is welcome!

Upvotes: 1

Views: 1546

Answers (2)

Jan Oelker
Jan Oelker

Reputation: 884

Thanks for your advices at Andrew Thompson and Andrew Mao.

@Mao: 1.) I am using the Swing GUI Thread. 2.) setVisible was just my last idea of fixing my problem :-P 3.) Of course in this way it would be more performant, but in this case I was a little bit dirty, because there wouldn't be more then three tabs at the same time. But I think I'm going to change it later on.

@Thompson: Because of the SSCCE, I created a project just for my problem (which you can see down below), to show my problem. But this project worked, so I compare the little steps of my test project with my real project and found a little mistake.

My problem was that I updated the tabs, before I removed the object of the ArrayList, so the GUI still showed the removed Object as a tab.

For anyone who is interested in my JTabbedPane test project:

import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class TabbedTest extends JFrame {

    private JTabbedPane tabbedPane = null;
    private MouseListener tabbedPaneMouseListener = null;
    private ArrayList<String> nameOfTab = new ArrayList<String>();
    private static int counter = 1;

    public TabbedTest() {
        setSize(500, 500);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(new GridLayout(0, 1));
        JPanel buttonPanel = new JPanel();

        JButton addButton = new JButton("add");
        addButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addElementToArrayList();
            }
        });
        JButton removeButton = new JButton("remove");
        removeButton.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeElementFromArrayList();
            }
        });

        tabbedPane = new JTabbedPane();
        tabbedPaneMouseListener = (new MouseAdapter() {

            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    if (e.getClickCount() == 1) {
                        System.out.println("Do Something");
                    }
                }
            }
        });
        tabbedPane.addMouseListener(tabbedPaneMouseListener);

        buttonPanel.add(addButton);
        buttonPanel.add(removeButton);
        add(buttonPanel);
        this.add(tabbedPane);
    }

    private void addElementToArrayList() {
        nameOfTab.add("" + counter++ + ". element");
        updateTabbedPane();
    }

    private void removeElementFromArrayList() {
        if (nameOfTab.size() > 0) {
            nameOfTab.remove(0);
        }
        updateTabbedPane();
    }

    public void updateTabbedPane() {
        tabbedPane.removeMouseListener(tabbedPaneMouseListener);
        while (tabbedPane.getTabCount() > 0) {
            tabbedPane.remove(0);
        }
        for (int i = 0; i < nameOfTab.size(); i++) {
            tabbedPane.addTab(nameOfTab.get(i), new JLabel(nameOfTab.get(i)));
        }
        tabbedPane.addMouseListener(tabbedPaneMouseListener);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new TabbedTest().setVisible(true);
            }
        });
    }
}

Upvotes: 2

Andrew Mao
Andrew Mao

Reputation: 36900

It seems like you may not be running this code in Swing's GUI thread. Is it inside a Runnable that is passed to SwingUtilities.invokeLater(...)? removeAll should work if that is the case.

Also, you shouldn't be using setVisible on components directly - you should be using setSelectedIndex or setSelectedComponent on the JTabbedPane.

Moreover, removing all the tabs and creating a new JScrollPane again for all but one of them seems horribly inefficient when the total order of the tabs doesn't change. Perhaps you should maintain a list in sorted order, such as a TreeSet, and just insert and remove a single tab at the appropriate index when there is an update.

Upvotes: 2

Related Questions