001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    
005    package graphlab.graph.ui;
006    
007    import javax.swing.*;
008    import javax.swing.plaf.basic.BasicButtonUI;
009    import java.awt.*;
010    import java.awt.event.*;
011    
012    /**
013     * Component to be used as tabComponent;
014     * Contains a JLabel to show the text and
015     * a JButton to close the tab it belongs to
016     */
017    public class ButtonTabComponent extends JPanel {
018        private final JTabbedPane pane;
019        public JLabel label;
020    
021        public ButtonTabComponent(final JTabbedPane pane) {
022            //unset default FlowLayout' gaps
023            super(new FlowLayout(FlowLayout.LEFT, 0, 0));
024            if (pane == null) {
025                throw new NullPointerException("TabbedPane is null");
026            }
027            this.pane = pane;
028            setOpaque(false);
029    
030            //make JLabel read titles from JTabbedPane
031            label = new JLabel() {
032                public String getText() {
033                    int i = pane.indexOfTabComponent(ButtonTabComponent.this);
034                    if (i != -1) {
035                        return pane.getTitleAt(i);
036                    }
037                    return null;
038                }
039            };
040    
041            add(label);
042            //add more space between the label and the button
043            label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
044            //tab button
045            JButton button = new TabButton();
046            add(button);
047            //add more space to the top of the component
048            setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
049        }
050    
051        private class TabButton extends JButton implements ActionListener {
052            public TabButton() {
053                int size = 17;
054                setPreferredSize(new Dimension(size, size));
055                setToolTipText("close this tab");
056                //Make the button looks the same for all Laf's
057                setUI(new BasicButtonUI());
058                //Make it transparent
059                setContentAreaFilled(false);
060                //No need to be focusable
061                setFocusable(false);
062                setBorder(BorderFactory.createEtchedBorder());
063                setBorderPainted(false);
064                //Making nice rollover effect
065                //we use the same listener for all buttons
066                addMouseListener(buttonMouseListener);
067                setRolloverEnabled(true);
068                //Close the proper tab by clicking the button
069                addActionListener(this);
070            }
071    
072            public void actionPerformed(ActionEvent e) {
073                int i = pane.indexOfTabComponent(ButtonTabComponent.this);
074                if (i != -1) {
075                    pane.remove(i);
076                }
077            }
078    
079            //we don't want to update UI for this button
080            public void updateUI() {
081            }
082    
083            //paint the cross
084            protected void paintComponent(Graphics g) {
085                super.paintComponent(g);
086                Graphics2D g2 = (Graphics2D) g.create();
087                //shift the image for pressed buttons
088                if (getModel().isPressed()) {
089                    g2.translate(1, 1);
090                }
091                g2.setStroke(new BasicStroke(2));
092                g2.setColor(Color.BLACK);
093                if (getModel().isRollover()) {
094                    g2.setColor(Color.MAGENTA);
095                }
096                int delta = 6;
097                g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
098                g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
099                g2.dispose();
100            }
101        }
102    
103        private final static MouseListener buttonMouseListener = new MouseAdapter() {
104            public void mouseEntered(MouseEvent e) {
105                Component component = e.getComponent();
106                if (component instanceof AbstractButton) {
107                    AbstractButton button = (AbstractButton) component;
108                    button.setBorderPainted(true);
109                }
110            }
111    
112            public void mouseExited(MouseEvent e) {
113                Component component = e.getComponent();
114                if (component instanceof AbstractButton) {
115                    AbstractButton button = (AbstractButton) component;
116                    button.setBorderPainted(false);
117                }
118            }
119        };
120    }