1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric (at) graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.gui; 22 23 import javax.swing.*; 24 import java.awt.*; 25 import java.awt.event.*; 26 27 28 /** 29 * This <code>Jpanel</code> is similar to a <code>JTabbedPane</code>. 30 * It uses buttons on the left-hand side to switch between panels. 31 * An image can be added below these buttons. 32 * Some methods are provided to switch between tabs. 33 * 34 * @author Eric Lafortune 35 */ 36 public class TabbedPane 37 extends JPanel 38 { 39 private final CardLayout cardLayout = new CardLayout(); 40 private final JPanel cardPanel = new JPanel(cardLayout); 41 private final ButtonGroup buttonGroup = new ButtonGroup(); 42 43 44 /** 45 * Creates a new TabbedPane. 46 */ 47 public TabbedPane() 48 { 49 GridBagLayout layout = new GridBagLayout(); 50 setLayout(layout); 51 52 GridBagConstraints cardConstraints = new GridBagConstraints(); 53 cardConstraints.gridx = 1; 54 cardConstraints.gridy = 0; 55 cardConstraints.gridheight = GridBagConstraints.REMAINDER; 56 cardConstraints.fill = GridBagConstraints.BOTH; 57 cardConstraints.weightx = 1.0; 58 cardConstraints.weighty = 1.0; 59 cardConstraints.anchor = GridBagConstraints.NORTHWEST; 60 61 add(cardPanel, cardConstraints); 62 } 63 64 65 /** 66 * Adds a component with a given title to the tabbed pane. 67 * 68 * @param title the title that will be used in the tab button. 69 * @param component the component that will be added as a tab. 70 */ 71 public Component add(final String title, Component component) 72 { 73 GridBagConstraints buttonConstraints = new GridBagConstraints(); 74 buttonConstraints.gridx = 0; 75 buttonConstraints.fill = GridBagConstraints.HORIZONTAL; 76 buttonConstraints.anchor = GridBagConstraints.NORTHWEST; 77 buttonConstraints.ipadx = 10; 78 buttonConstraints.ipady = 4; 79 80 JToggleButton button = new JToggleButton(title); 81 82 // Let the button react on the mouse press, instead of waiting for the 83 // mouse release. 84 button.setModel(new JToggleButton.ToggleButtonModel() 85 { 86 public void setPressed(boolean b) 87 { 88 if ((isPressed() == b) || !isEnabled()) 89 { 90 return; 91 } 92 93 if (!b && isArmed()) 94 { 95 setSelected(!this.isSelected()); 96 } 97 98 if (b) 99 { 100 stateMask |= PRESSED; 101 } 102 else 103 { 104 stateMask &= ~PRESSED; 105 } 106 107 fireStateChanged(); 108 109 if (isPressed()) 110 { 111 fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getActionCommand())); 112 } 113 } 114 115 }); 116 117 // Switch to the tab on a button press. 118 button.addActionListener(new ActionListener() 119 { 120 public void actionPerformed(ActionEvent e) 121 { 122 cardLayout.show(cardPanel, title); 123 } 124 }); 125 126 // Only one button can be selected at the same time. 127 buttonGroup.add(button); 128 129 // If this is the first tab, make sure its button is selected. 130 if (cardPanel.getComponentCount() == 0) 131 { 132 button.setSelected(true); 133 } 134 135 // Add the button and its panel. 136 add(button, buttonConstraints); 137 cardPanel.add(title, component); 138 139 return component; 140 } 141 142 143 /** 144 * Adds an image below the tab buttons, after all tabs have been added. 145 * The image will only be as visible as permitted by the available space. 146 * 147 * @param image the image. 148 * @return the component containing the image. 149 */ 150 public Component addImage(final Image image) 151 { 152 GridBagConstraints imageConstraints = new GridBagConstraints(); 153 imageConstraints.gridx = 0; 154 imageConstraints.weighty = 1.0; 155 imageConstraints.fill = GridBagConstraints.BOTH; 156 imageConstraints.anchor = GridBagConstraints.SOUTHWEST; 157 158 JButton component = new JButton(new ImageIcon(image)); 159 component.setFocusPainted(false); 160 component.setFocusable(false); 161 component.setRequestFocusEnabled(false); 162 component.setRolloverEnabled(false); 163 component.setMargin(new Insets(0, 0, 0, 0)); 164 component.setHorizontalAlignment(JButton.LEFT); 165 component.setVerticalAlignment(JButton.BOTTOM); 166 component.setPreferredSize(new Dimension(0, 0)); 167 168 add(component, imageConstraints); 169 170 return component; 171 } 172 173 174 /** 175 * Selects the first tab. 176 */ 177 public void first() 178 { 179 cardLayout.first(cardPanel); 180 updateButtonSelection(); 181 } 182 183 184 /** 185 * Selects the last tab. 186 */ 187 public void last() 188 { 189 cardLayout.last(cardPanel); 190 updateButtonSelection(); 191 } 192 193 194 /** 195 * Selects the previous tab. 196 */ 197 public void previous() 198 { 199 cardLayout.previous(cardPanel); 200 updateButtonSelection(); 201 } 202 203 204 /** 205 * Selects the next tab. 206 */ 207 public void next() 208 { 209 cardLayout.next(cardPanel); 210 updateButtonSelection(); 211 } 212 213 214 /** 215 * Lets the button selection reflect the currently visible panel. 216 */ 217 private void updateButtonSelection() 218 { 219 int count = cardPanel.getComponentCount(); 220 for (int index = 0 ; index < count ; index++) { 221 Component card = cardPanel.getComponent(index); 222 if (card.isShowing()) 223 { 224 JToggleButton button = (JToggleButton)getComponent(index+1); 225 button.setSelected(true); 226 } 227 } 228 } 229 } 230