001    package org.shiftone.jrat.desktop;
002    
003    import org.shiftone.jrat.util.Assert;
004    
005    import javax.swing.*;
006    import java.awt.*;
007    import java.awt.event.*;
008    
009    /**
010     * @author jeff@shiftone.org (Jeff Drost)
011     */
012    public class TabMouseListener extends MouseAdapter implements ActionListener {
013    
014        private JMenuItem newWindowMenuItem = new JMenuItem("New Window");
015        private JMenuItem closeMenuItem = new JMenuItem("Close");
016        private JMenuItem closeAllButMenuItem = new JMenuItem("Close All But This");
017        private JMenuItem closeAllMenuItem = new JMenuItem("Close All");
018    
019        protected JPopupMenu popup = new JPopupMenu();
020        protected JTabbedPane tabPane = null;
021        protected int index = -1;
022    
023    
024        public TabMouseListener(JTabbedPane tabPane) {
025            Assert.assertNotNull(tabPane);
026            this.tabPane = tabPane;
027    
028            popup.add(newWindowMenuItem);
029            popup.add(closeMenuItem);
030            popup.add(closeAllButMenuItem);
031            popup.add(closeAllMenuItem);
032    
033            newWindowMenuItem.addActionListener(this);
034            closeMenuItem.addActionListener(this);
035            closeAllButMenuItem.addActionListener(this);
036            closeAllMenuItem.addActionListener(this);
037    
038        }
039    
040    
041        public void mousePressed(MouseEvent e) {
042            maybeShowPopup(e);
043        }
044    
045    
046        public void mouseReleased(MouseEvent e) {
047            maybeShowPopup(e);
048        }
049    
050    
051        private void maybeShowPopup(MouseEvent e) {
052    
053            if (e.isPopupTrigger()) {
054                index = tabPane.indexAtLocation(e.getX(), e.getY());
055    
056                if (index != -1) {
057                    tabPane.setSelectedIndex(index);
058                    preShow();
059                    popup.show(e.getComponent(), e.getX(), e.getY());
060                }
061            }
062        }
063    
064        protected void preShow() {
065    
066            closeMenuItem.setEnabled(true);
067            closeAllMenuItem.setEnabled(true);
068            newWindowMenuItem.setEnabled(true);
069    
070            if (tabPane.getTabCount() == 1) {
071                closeAllButMenuItem.setEnabled(false);
072            } else {
073                closeAllButMenuItem.setEnabled(true);
074            }
075        }
076    
077    
078        public void actionPerformed(ActionEvent e) {
079    
080            if (e.getSource() == closeMenuItem) {
081                tabPane.remove(index);
082            } else if (e.getSource() == closeAllButMenuItem) {
083                closeAll(false);
084            } else if (e.getSource() == closeAllMenuItem) {
085                closeAll(true);
086            } else if (e.getSource() == newWindowMenuItem) {
087                spawn();
088            }
089        }
090    
091        public void spawn() {
092    
093            Component component = tabPane.getComponentAt(index);
094            String title = tabPane.getTitleAt(index);
095            tabPane.remove(component);
096    
097            JFrame frame = new SpawnedFrame(title, component);
098            // put it right on top
099            frame.setSize(tabPane.getSize());
100            frame.setLocation(tabPane.getLocationOnScreen());
101    
102            frame.setVisible(true);
103        }
104    
105        public void closeAll(boolean includeIndex) {
106    
107            for (int i = tabPane.getTabCount() - 1; i >= 0; i--) {
108                if ((includeIndex) || (i != index)) {
109                    tabPane.remove(i);
110                }
111            }
112        }
113    
114        private class SpawnedFrame extends JFrame {
115    
116            private final String title;
117            private final Component component;
118    
119            public SpawnedFrame(String title, Component component) throws HeadlessException {
120                super(title);
121                this.title = title;
122                this.component = component;
123    
124                getContentPane().setLayout(new BorderLayout());
125                getContentPane().add(component, BorderLayout.CENTER);
126    
127                // when the window is closed, put the component back in a tab
128                addWindowListener(new CloseAdapter());
129            }
130    
131            private class CloseAdapter extends WindowAdapter {
132                public void windowClosing(WindowEvent windowEvent) {
133                    getContentPane().removeAll();
134                    tabPane.addTab(title, component);
135                }
136            }
137        }
138    }