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