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