KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > swingwtx > custom > JClosableTabbedPane


1 /*
2    SwingWT
3    Copyright(c)2003-2004, R. Rawson-Tetley
4
5    For more information on distributing and using this program, please
6    see the accompanying "COPYING" file.
7
8    Contact me by electronic mail: bobintetley@users.sourceforge.net
9
10    $Log: JClosableTabbedPane.java,v $
11    Revision 1.14 2004/05/06 12:35:21 bobintetley
12    Parity with Swing constants for Binary Compatibility + fixes to JDesktopPane
13
14    Revision 1.13 2004/04/28 08:38:06 bobintetley
15    Hierarchy fixes, code cleanup for base classes, additional javadocs and use of flag to identify JComponent descendants with peers
16
17    Revision 1.12 2004/04/18 15:25:35 bobintetley
18    Updates to take advantage of new features
19
20    Revision 1.11 2004/04/18 14:59:42 bobintetley
21    Virtual table support (much much faster) and removal of deprecated API
22    for JClosableTabbedPane
23
24    Revision 1.10 2004/04/18 14:41:09 bobintetley
25    JClosableTabbedPane uses new CTabFolder in M8 (no longer need local copy)
26
27    Revision 1.9 2004/03/30 10:42:44 bobintetley
28    Many minor bug fixes, event improvements by Dan Naab. Full swing.Icon support
29
30    Revision 1.8 2004/03/18 14:42:10 bobintetley
31    Fix to Window hierarchy to match Swing, and fix to allow MDI apps
32       to work under SWT 2.x
33
34    Revision 1.7 2004/03/03 09:13:12 bobintetley
35    JList threading fixed and top level error handling
36
37    Revision 1.6 2004/02/27 16:52:58 bobintetley
38    Scrollpane activation fixes, modern tabbedpane usage for JClosableTabbedPane
39
40    Revision 1.5 2004/02/27 16:16:12 bobintetley
41    Threading fixes
42
43    Revision 1.4 2004/01/26 15:45:47 bobintetley
44    SwingSet fixes
45
46    Revision 1.3 2004/01/26 10:03:36 bobintetley
47    Fixed component painting, added overloaded TabbedPane add() methods
48
49    Revision 1.2 2004/01/26 09:50:11 bobintetley
50    Fix to tabbed pane cache
51
52    Revision 1.1 2004/01/20 07:38:05 bobintetley
53    Bug fixes and compatibility methods
54
55    Revision 1.7 2004/01/16 15:53:32 bobintetley
56    Many compatibility methods added to Container, Component, JInternalFrame,
57       UIManager, SwingUtilities, JTabbedPane, JPasswordField, JCheckBox
58       and JRadioButton.
59
60    Revision 1.6 2003/12/22 14:17:30 bobintetley
61    One-off timer method and better layout management for tabs
62
63    Revision 1.5 2003/12/18 09:37:33 bobintetley
64    Enabled support for JTabbedPane and JClosableTabbedPane (SWT doesn't
65    support, so a bit of magic in here)
66
67    Revision 1.4 2003/12/16 09:19:02 bobintetley
68    Various small fixes to match Swing more closely
69
70    Revision 1.3 2003/12/15 18:29:57 bobintetley
71    Changed setParent() method to setSwingWTParent() to avoid conflicts with applications
72
73    Revision 1.2 2003/12/14 09:13:38 bobintetley
74    Added CVS log to source headers
75
76 */

77
78
79 package swingwtx.custom;
80
81 import org.eclipse.swt.custom.*;
82 import org.eclipse.swt.widgets.*;
83 import org.eclipse.swt.*;
84
85 import swingwtx.swing.*;
86 import swingwtx.swing.event.*;
87 import swingwtx.custom.event.*;
88
89 import java.util.*;
90
91 /**
92  * Not really a swing component, but I map it here because I use it
93  * for JInternalFrame/JDesktopPane. It's basically JTabbedPane, but with
94  * closable buttons - something that Swing really ought to offer!
95  */

96 public class JClosableTabbedPane extends JComponent implements SwingConstants {
97     
98     protected CTabFolder ppeer = null;
99     
100     /** Tab item cache until added to parent */
101     protected Vector tabs = new Vector();
102     protected Vector tabCloseListeners = new Vector();
103     protected int pTabPlacement = TOP;
104     protected Vector changeListeners = new Vector();
105     protected int pSelectedIndex = -1;
106     
107     /** Thread safe accessor */
108     private int iRetVal = 0;
109     private String JavaDoc sRetVal = "";
110     private Object JavaDoc retval;
111     
112     public JClosableTabbedPane() { }
113     
114     public void addChangeListener(ChangeListener l) {
115         changeListeners.add(l);
116     }
117     
118     public void removeChangeListener(ChangeListener l) {
119         changeListeners.remove(l);
120     }
121     
122     public void addTab(String JavaDoc title, swingwt.awt.Component component) {
123         addTab(title, null, component);
124     }
125     
126     public void addTab(String JavaDoc title, Icon icon, swingwt.awt.Component component) {
127         addTab(title, icon, component, null, true);
128     }
129     
130     public void addTab(final String JavaDoc title, final Icon icon, final swingwt.awt.Component component, final String JavaDoc tip) {
131         addTab(title, icon, component, tip, true);
132     }
133     
134     public void addTab(final String JavaDoc title, final Icon icon, final swingwt.awt.Component component, final String JavaDoc tip, final boolean enabled) {
135         addTab(title, icon, component, tip, enabled, false);
136     }
137     
138     public void addTab(final String JavaDoc title, final Icon icon, final swingwt.awt.Component component, final String JavaDoc tip, final boolean enabled, boolean fromcache) {
139         
140         if (!fromcache) {
141             // Create the cache entry
142
TabItemCache t = new TabItemCache();
143             t.title = title;
144             t.icon = icon;
145             t.component = component;
146             t.tip = tip;
147             t.enabled = enabled;
148             tabs.add(t);
149             t = null;
150         }
151         
152         final JClosableTabbedPane me = this;
153         SwingUtilities.invokeSync(new Runnable JavaDoc() {
154             public void run() {
155                 if (!SwingWTUtils.isSWTControlAvailable(ppeer)) return;
156
157                 CTabItem t = new CTabItem(ppeer, SWT.NONE);
158
159                 // Make sure the component contained by this
160
// TabItem gets created now
161
try {
162                     component.setSwingWTParent(me);
163                 }
164                 catch (Exception JavaDoc e) {
165                     e.printStackTrace();
166                 }
167
168                 if (title != null) t.setText(title);
169                 if (icon != null) t.setImage(SwingWTUtils.getSWTImageFromSwingIcon(me, icon));
170                 
171                 // Only display the component if it's enabled
172
if (component != null && enabled) t.setControl(component.getPeer());
173                 
174                 if (tip != null) t.setToolTipText(tip);
175                 t.setData("enabled", (enabled ? "true" : "false"));
176
177                 // Display the thing
178
postponeLayout();
179             }
180         });
181         
182     }
183     
184     public Icon getIconAt(final int index) {
185         if (ppeer == null) {
186             TabItemCache t = (TabItemCache) tabs.get(index);
187             return t.icon;
188         }
189         else {
190             SwingUtilities.invokeSync(new Runnable JavaDoc() {
191                 public void run() {
192                     swingwt.awt.Image image = new swingwt.awt.Image();
193                     image.image = ppeer.getItem(index).getImage();
194                     retval = new ImageIcon(image);
195                 }
196             });
197             return (Icon) retval;
198         }
199     }
200     public void setIconAt(final int index, final Icon icon) {
201         TabItemCache t = (TabItemCache) tabs.get(index);
202         t.icon = icon;
203         final JClosableTabbedPane pthis = this;
204         if (SwingWTUtils.isSWTControlAvailable(ppeer))
205             SwingUtilities.invokeSync(new Runnable JavaDoc() {
206                 public void run() {
207                     ppeer.getItem(index).setImage(SwingWTUtils.getSWTImageFromSwingIcon(pthis, icon));
208                 }
209             });
210     }
211     
212     public void addTabCloseListener(TabCloseListener l) {
213         tabCloseListeners.add(l);
214     }
215     
216     public void removeTabCloseListener(TabCloseListener l) {
217         tabCloseListeners.remove(l);
218     }
219
220     public void setEnabledAt(final int index, final boolean b) {
221         if (SwingWTUtils.isSWTControlAvailable(ppeer)) {
222             SwingUtilities.invokeSync(new Runnable JavaDoc() {
223                 public void run() {
224                     ppeer.getItem(index).setData("enabled", (b ? "true" : "false"));
225                     // If we're disabled - hide the tab's control. This is about all we
226
// can do with SWT.
227
if (!b)
228                         ppeer.getItem(index).setControl(null);
229                     else
230                         ppeer.getItem(index).setControl( ((TabItemCache) tabs.get(index)).component.getPeer() );
231                 }
232             });
233         }
234         else {
235             TabItemCache t = (TabItemCache) tabs.get(index);
236             t.enabled = b;
237         }
238     }
239     
240     public int getTabCount() {
241         if (!SwingWTUtils.isSWTControlAvailable(ppeer))
242             return tabs.size();
243         else {
244             SwingUtilities.invokeSync(new Runnable JavaDoc() {
245                 public void run() {
246                     iRetVal = ppeer.getItemCount();
247                 }
248             });
249             return iRetVal;
250         }
251     }
252
253     public int getSelectedIndex() {
254         if (SwingWTUtils.isSWTControlAvailable(ppeer)) {
255             SwingUtilities.invokeSync(new Runnable JavaDoc() {
256                 public void run() {
257                     iRetVal = ppeer.getSelectionIndex();
258                 }
259             });
260         }
261         else
262             iRetVal = -1;
263         return iRetVal;
264     }
265     
266     public swingwt.awt.Component getSelectedComponent() {
267         int i = getSelectedIndex();
268         if (i != -1)
269             return ((TabItemCache) tabs.get(i)).component;
270         else
271             return null;
272     }
273     
274     public void setSelectedIndex(final int index) {
275         pSelectedIndex = index;
276         if (SwingWTUtils.isSWTControlAvailable(ppeer))
277             SwingUtilities.invokeSync(new Runnable JavaDoc() {
278                 public void run() {
279                     ppeer.setSelection(index);
280                 }
281             });
282     }
283     
284     public void removeTabAt(final int index) {
285         if (SwingWTUtils.isSWTControlAvailable(ppeer)) {
286             SwingUtilities.invokeSync(new Runnable JavaDoc() {
287                 public void run() {
288                     tabs.removeElementAt(index);
289                     ppeer.getItem(index).dispose();
290                 }
291             });
292         }
293         else
294             tabs.removeElementAt(index);
295     }
296     
297     public String JavaDoc getTitleAt(final int index) {
298         if (SwingWTUtils.isSWTControlAvailable(ppeer)) {
299             SwingUtilities.invokeSync(new Runnable JavaDoc() {
300                 public void run() {
301                     sRetVal = ppeer.getItem(index).getText();
302                 }
303             });
304             return sRetVal;
305         }
306         else {
307             TabItemCache t = (TabItemCache) tabs.get(index);
308             return t.title;
309         }
310     }
311     public void setTitleAt(final int index, final String JavaDoc title) {
312         if (SwingWTUtils.isSWTControlAvailable(ppeer)) {
313             SwingUtilities.invokeSync(new Runnable JavaDoc() {
314                 public void run() {
315                     ppeer.getItem(index).setText(title);
316                 }
317             });
318         }
319         else {
320             TabItemCache t = (TabItemCache) tabs.get(index);
321             t.title = title;
322         }
323     }
324     public int getTabPlacement() { return pTabPlacement; }
325     public void setTabPlacement(int place) { pTabPlacement = place; }
326     
327     public Control getPeer() { return ppeer; }
328     
329     protected void processTabClosing(CTabFolderEvent e) {
330         // See which one matches!
331
CTabItem[] items = ppeer.getItems();
332         for (int i = 0; i < items.length; i++) {
333             if (e.item.equals(items[i])) {
334                 Iterator iter = tabCloseListeners.iterator();
335                 while (iter.hasNext()) {
336                     TabCloseListener l = (TabCloseListener) iter.next();
337                     e.doit = l.tabClosed(i);
338                 }
339             }
340         }
341     }
342     
343     /**
344      * Process change events - fired when the tab changes
345      */

346     protected void processChangeEvent(ChangeEvent e) {
347         Iterator i = changeListeners.iterator();
348         while (i.hasNext()) {
349             ChangeListener l = (ChangeListener) i.next();
350             l.stateChanged(e);
351         }
352     }
353     
354     protected void postponeLayout() {
355         SwingUtilities.invokeLater(new Runnable JavaDoc() {
356             public void run() {
357                 layoutTab();
358             }
359         });
360     }
361     
362     protected void layoutTab() {
363         
364         int i = ppeer.getSelectionIndex();
365         if (i < 0 || i >= ppeer.getItems().length) return;
366         
367         Control p = ppeer.getItem(ppeer.getSelectionIndex()).getControl();
368         if (p instanceof Composite)
369             ((Composite) p).layout(true);
370         else
371             p.redraw();
372     }
373     
374     
375     public void setSwingWTParent(swingwt.awt.Container parent) throws Exception JavaDoc {
376         descendantHasPeer = true;
377         ppeer = new CTabFolder(parent.getComposite(), SwingWTUtils.translateSwingAlignmentConstant(pTabPlacement));
378         peer = ppeer;
379         composite = ppeer;
380         this.parent = parent;
381         
382         // Add any cached items
383
if (tabs.size() > 0) {
384             Object JavaDoc[] tabso = tabs.toArray();
385             for (int i = 0; i < tabso.length; i++) {
386                 TabItemCache t = (TabItemCache) tabso[i];
387                 addTab(t.title, t.icon, t.component, t.tip, t.enabled, true);
388             }
389         }
390         
391         // Make sure the selected index is right
392
if (pSelectedIndex != -1)
393             ppeer.setSelection(pSelectedIndex);
394         
395         ppeer.setUnselectedCloseVisible(true);
396         ppeer.setUnselectedImageVisible(true);
397         ppeer.setBorderVisible(true);
398         
399         // Events
400
// -- Tab closing
401
ppeer.addCTabFolderListener(new CTabFolderAdapter() {
402         public void itemClosed(CTabFolderEvent event) {
403             processTabClosing(event);
404         }
405     });
406
407         // -- Tab is selected, may want to block it if we have it
408
// flagged as disabled.
409
final JClosableTabbedPane me = this;
410         ppeer.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
411             public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
412                 // We don't send events if the tab is disabled
413
if (checkTabEnabled(e)) {
414                     postponeLayout(); // Update layout of tab if we went to a new one
415
// Send change event
416
ChangeEvent ce = new ChangeEvent(me);
417                     processChangeEvent(ce);
418                 }
419             }
420             public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {}
421         });
422         
423         // Make sure whatever is selected gets displayed
424
if (ppeer.getItemCount() > 0)
425             postponeLayout();
426         
427     }
428     
429     /** Returns true if the tab is enabled according to the data set on it.
430      * This should be called from a selection event, determining whether
431      * the user is allowed to go to it or not.
432      */

433     protected boolean checkTabEnabled(org.eclipse.swt.events.SelectionEvent e) {
434         e.doit = (e.item.getData("enabled").toString().equals("true"));
435         return e.doit;
436     }
437     
438 }
439
440
Popular Tags