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