0

As the title suggests whats the best way to doc/undoc a tab from a JTabbedPane? Similar to how you can drag a tab in Chrome and it will open a new window, then dragging it back will place it back again?

user1724416
  • 914
  • 2
  • 11
  • 24

2 Answers2

2

That's not a simple question.

First, you need a trigger, something that you can identify that the tab is to be undocked. Remember, tabs can be reordered, so simply monitoring drag events won't be enough

Second, you need to some way to determine how to "re-dock" the tab if the window is closed (or even if you want to).

After that, it becomes as simple as removing the component from the tab and placing onto the a frame a visa-versa.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

I did this using a MouseMotionListener and MouseListener. This will just Undock when you drag a tab header by a significant distance and redock it when you close the undocked frame.

    import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTree;


public class DockableTabbedPane extends JTabbedPane {

    private DockableTabbedPane  DraggableTabbedPane;
    public DockableTabbedPane() {
        super();
        DraggableTabbedPane = this;
        TabDragListener tabDragger = new TabDragListener();
        this.addMouseListener(tabDragger);
        this.addMouseMotionListener(tabDragger);        
    }

    private class TabDragListener implements MouseListener, MouseMotionListener {

        Point p0,p0screen;

        Component current;
        String title;

        public void mousePressed(MouseEvent e) {
            p0 = e.getPoint();


            for (int i = 0; i < getTabCount(); i++) {
                Rectangle bounds = getBoundsAt(i);
                if (bounds.contains(p0)) {
                    current = DockableTabbedPane.this.getComponentAt(i);   
                    title =DockableTabbedPane.this.getTitleAt(i);
                    p0screen = getLocationOnScreen();
                }
            }
        };

        public void mouseDragged(MouseEvent e) {
            Point p = e.getPoint();
            JFrame frame;

            if (current != null) {
                // check for a significant  drag
                if( p.distance(p0)>20){

                    frame = undock(current,title);
                    current = null; 


                }
            }
        }



        public void mouseMoved(MouseEvent arg0) {}

        public void mouseClicked(MouseEvent arg0) {}

        public void mouseEntered(MouseEvent arg0) {}

        public void mouseExited(MouseEvent arg0) {}

        public void mouseReleased(MouseEvent arg0) {
            current=null;
            title =null;
        }
    }

    private UndockedFrame undock(Component current,String title) {


        Point p = current.getLocationOnScreen();
        remove(current);
        UndockedFrame frame = new UndockedFrame(current,title);

        p.translate(20, 20);
        frame.setLocation(p);
        frame.setVisible(true);
        fireStateChanged();
        return frame;    



    }

    private class UndockedFrame extends JFrame {
        Component current;
        String title;
        public UndockedFrame(Component current,String title) {
            this.current = current;

            this.setTitle(title);

            Container content = this.getContentPane();
            content.setLayout(new BorderLayout());
            content.add(current, BorderLayout.CENTER);
            this.setBounds(current.getBounds());
            this.addWindowListener(new UndockedFrameListener());
        }

        public void redock() {

            this.dispose();
            add(title, current);

        }
    }

    // Redock on close
    private class UndockedFrameListener extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            Window w = e.getWindow();
            if (w instanceof UndockedFrame) {
                UndockedFrame frame = (UndockedFrame)w;
                frame.redock();
            }
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        DockableTabbedPane pane = new DockableTabbedPane();
        pane.add(new JTree(), "Tree 0");
        pane.add(new JTextArea(" Hello"), "Tree 1");
        pane.add(new JFileChooser(), "Tree 2");
        pane.add(new JSpinner(), "Tree 3");
        pane.add(new JSlider(),"Tree 4");
        frame.getContentPane().add(pane);
        frame.setBounds(100, 100, 400, 400);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    }
}
Ace McCloud
  • 798
  • 9
  • 27