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 }