0

Is there a way to switch components between tabs in JTabbedPane without creating new instances of these objects? Or any way to switch tabs?

When component is removed from JTabbedPane via .remove(idx) or .removeTabAt(idx) methods, the component is destroyed. Maybe there is a way to prevent destroying the object?

I am looking for a way to remove tab containing the component in order to add it back in nearest future but with some another index.

In other words, I just need to change the tab order. But it is important for me not to create new instances of components.

3 Answers3

3

JTabbedPane.removeTabAt will only remove the tab, but not the component you've placed inside the tab. So to move the tab for a particular component you just insert a new tab for the component at the new position with JTabbedPane.insertTab, which will implicitly remove the old one. Or you can remove it yourself and add it again later on. Both methods work fine:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class ReorderTabs {
    private static void addTab(final JTabbedPane tabbedPane, final String title) {
        final JPanel panel = new JPanel(new BorderLayout());

        JLabel content = new JLabel(title + " - content", JLabel.CENTER); 
        panel.add(content, BorderLayout.CENTER);

        JButton toFrontButton = new JButton("|<");
        toFrontButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                // Re-insert the component in a new tab at the front. The tabbed pane will remove the old tab.
                tabbedPane.insertTab(title, null, panel, null, 0);
            }
        });
        panel.add(toFrontButton, BorderLayout.WEST);

        JButton toBackButton = new JButton(">|");
        toBackButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Remove the component from the tab. The component will not be destroyed ...
                int index = tabbedPane.indexOfComponent(panel);
                tabbedPane.removeTabAt(index);

                // ... and can be added again (or inserted at an arbitrary index with insertTab).
                tabbedPane.addTab(title, panel);
            }
        });
        panel.add(toBackButton, BorderLayout.EAST);

        tabbedPane.addTab(title, panel);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JTabbedPane tabbedPane = new JTabbedPane();
                addTab(tabbedPane, "Tab #1");
                addTab(tabbedPane, "Tab #2");
                addTab(tabbedPane, "Tab #3");
                addTab(tabbedPane, "Tab #4");

                JFrame frame = new JFrame("Reorder Tabs Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tabbedPane, BorderLayout.CENTER);
                frame.setSize(400, 200);
                frame.setVisible(true);
            }
        });
    }
}
Andreas Mayer
  • 687
  • 5
  • 15
  • Added in getComponentAt (as the OP seems to have lost the original reference) and you have yourself an excellent answer ;) – MadProgrammer Feb 07 '13 at 19:22
0

you can hide the component if you don't want to remove them.

or you can switch the tabs using jtpan.setEnabledAt(int tab_index, boolean enabled).

to set the index use setSelectedIndex(int index)

to hide the component use componen.setVisible(false)

Arpit
  • 12,767
  • 3
  • 27
  • 40
0

What about this dirty hack?

public static void main (String [] args) throws Exception
{
    final JTabbedPane tabbedPane = new JTabbedPane ();
    tabbedPane.addTab ("A", new JButton ("A"));
    tabbedPane.addTab ("B", new JButton ("B"));
    tabbedPane.addTab ("C", new JButton ("C"));
    tabbedPane.addTab ("D", new JButton ("D"));
    JFrame frame = new JFrame ();
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    frame.getContentPane ().setLayout (new BorderLayout ());
    frame.getContentPane ().add (tabbedPane, BorderLayout.CENTER);
    frame.pack ();
    frame.setVisible (true);

    Field pagesField = JTabbedPane.class.getDeclaredField ("pages");
    pagesField.setAccessible (true);
    final List <Object> pages = (List <Object>)pagesField.get (tabbedPane);

    while (true)
    {
        Thread.sleep (1000);

        SwingUtilities.invokeLater (new Runnable()
        {
            @Override
            public void run ()
            {
                Object o = pages.get (0);

                for (int i = 1; i < pages.size (); i++)
                    pages.set (i - 1, pages.get (i));

                pages.set (pages.size () - 1, o);

                tabbedPane.setSelectedIndex ((tabbedPane.getSelectedIndex () + pages.size () - 1) % pages.size ());

                tabbedPane.invalidate ();
                tabbedPane.repaint ();
            }
        });
    }
}
Mikhail Vladimirov
  • 13,572
  • 1
  • 38
  • 40