001 package sale.multiwindow; 002 003 import java.awt.Component; 004 import java.awt.Graphics; 005 import java.awt.Image; 006 import java.awt.Rectangle; 007 import java.awt.event.MouseAdapter; 008 import java.awt.event.MouseEvent; 009 010 import javax.swing.ImageIcon; 011 import javax.swing.JTabbedPane; 012 013 import resource.util.ResourceManager; 014 015 /** 016 * A JTabbedPane which has a close ('X') icon on each tab. 017 * 018 * It is also possible to render the tabs unclosable, i.e. without an icon. 019 */ 020 public class IconTabbedPane extends JTabbedPane { 021 022 /** 023 * ID for Serialization. 024 */ 025 private static final long serialVersionUID = 5782825255690036127L; 026 027 /** 028 * Indicates whether the tabs can be closed or not. 029 */ 030 private boolean m_fAllowClose = true; 031 032 /** 033 * The tab whose close button has been clicked most recently. 034 */ 035 private int tabNumber; 036 037 /** 038 * The imageIcon to be used as close icon. 039 */ 040 protected static ImageIcon CLOSE_ICON = new ImageIcon(ResourceManager.getInstance().getResource( 041 ResourceManager.RESOURCE_GIF, "icon.icon_closetab_16x16")); 042 043 044 /** 045 * Creates an IconTabbedPane. A MouseListener is added tat listens to clicks on the close button if set. 046 * @param fAllowClose Indicates if close buttons should be set or not. 047 */ 048 public IconTabbedPane(boolean fAllowClose) { 049 super(); 050 m_fAllowClose = fAllowClose; 051 addMouseListener(new MouseAdapter() { 052 public void mouseClicked(MouseEvent e) { 053 if (getAllowClose()) { 054 tabNumber = getUI().tabForCoordinate(IconTabbedPane.this, e.getX(), e.getY()); 055 if (tabNumber < 0) { 056 return; 057 } 058 Rectangle rect = ((CloseTabIcon)getIconAt(tabNumber)).getBounds(); 059 if (rect.contains(e.getX(), e.getY())) { 060 getIconClicked(); 061 } 062 } 063 } 064 }); 065 } 066 067 /** 068 * Specifies a new close icon. Icons which are set on currently open tabs will not be changed 069 * automatically. 070 * @param iNewIcon the new ImageIcon to be used as close icon. 071 */ 072 public void setCloseIcon(ImageIcon iNewIcon) { 073 CLOSE_ICON = iNewIcon; 074 } 075 076 /** 077 * Creates an IconTabbedPane with close buttons set. Calls <code>IconTabbedPane(true)</code> 078 */ 079 public IconTabbedPane() { 080 this(true); 081 } 082 083 /** 084 * Adds a tab to the IconTabbedPane. Depending on whether closing is allowed or not a close icon 085 * will be set or not, respectively. 086 * @param title the component's title 087 * @param component the compoment to be added as tab 088 */ 089 public void addTab(String title, Component component) { 090 CloseTabIcon cti = getAllowClose() ? new CloseTabIcon(CLOSE_ICON) : null; 091 super.addTab(title, cti, component); 092 } 093 094 /*public void removeTabAt(final int i) { 095 096 try { 097 javax.swing.SwingUtilities.invokeAndWait(new Thread() { 098 public void run() { 099 IconTabbedPane.super.removeTabAt(i); 100 } 101 }); 102 } 103 catch (InvocationTargetException ex) { 104 } 105 catch (InterruptedException ex) { 106 } 107 //System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); 108 //super.removeTabAt(i); 109 }*/ 110 111 /** 112 * @return the index of the tab whose close icon has been clicked most recently 113 */ 114 public int getIconClicked() { 115 return tabNumber; 116 } 117 118 /** 119 * Specifies if closing of tabs should be permitted or not. 120 * @param fAllowClose 121 */ 122 public void setAllowClose(boolean fAllowClose) { 123 m_fAllowClose = fAllowClose; 124 } 125 126 /** 127 * @return if closing of tabs is allowed or not. 128 */ 129 public boolean getAllowClose() { 130 return m_fAllowClose; 131 } 132 133 /** 134 * Extends ImageIcon by method <code>getBounds</code> to make it possible to determine the coordinates of 135 * the icon on the screen. 136 */ 137 protected class CloseTabIcon extends ImageIcon { 138 private static final long serialVersionUID = -3548845199557231620L; 139 private int x_pos; 140 private int y_pos; 141 private int width; 142 private int height; 143 private ImageIcon imageIcon; 144 145 /** 146 * Creates a CloseTabIcon from an ImageIcon. 147 */ 148 public CloseTabIcon(ImageIcon icon) { 149 this.imageIcon = icon; 150 width = imageIcon.getIconWidth(); 151 height = imageIcon.getIconHeight(); 152 } 153 154 /** 155 * Returns the image of the ImageIcon. 156 */ 157 public Image getImage() { 158 return imageIcon.getImage(); 159 } 160 161 /** 162 * Paints the Icon. This method is usually not called directly. 163 */ 164 public void paintIcon(Component c, Graphics g, int x, int y) { 165 imageIcon.paintIcon(c, g, x, y); 166 this.x_pos = x; 167 this.y_pos = y; 168 } 169 170 /** 171 * Returns the icon's width. 172 */ 173 public int getIconWidth() { 174 return width; 175 } 176 177 /** 178 * Returns the icon's height. 179 */ 180 public int getIconHeight() { 181 return height; 182 } 183 184 /** 185 * Returns the position of the icon on the screen. Used to check for mouse clicks on the icon. 186 */ 187 public Rectangle getBounds() { 188 return new Rectangle(x_pos, y_pos, width, height); 189 } 190 } 191 192 } 193 194