KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > tabcontrol > plaf > ToolbarTabDisplayerUI


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * ToolbarTabDisplayerUI.java
21  *
22  * Created on June 1, 2004, 12:31 AM
23  */

24
25 package org.netbeans.swing.tabcontrol.plaf;
26
27 import java.awt.*;
28 import java.awt.event.ActionEvent JavaDoc;
29 import java.awt.event.ActionListener JavaDoc;
30 import java.awt.event.MouseListener JavaDoc;
31 import java.util.Arrays JavaDoc;
32 import javax.swing.*;
33 import javax.swing.border.Border JavaDoc;
34 import javax.swing.border.CompoundBorder JavaDoc;
35 import javax.swing.event.ChangeEvent JavaDoc;
36 import javax.swing.event.ChangeListener JavaDoc;
37 import javax.swing.plaf.ComponentUI JavaDoc;
38 import org.netbeans.swing.tabcontrol.TabDisplayer;
39 import org.openide.awt.HtmlRenderer;
40 import org.openide.util.Utilities;
41
42 /**
43  * A TabDisplayerUI which uses a JToolBar and JButtons. This look is used
44  * in various places such as the property sheet and component inspector.
45  *
46  * @author Tim Boudreau
47  */

48 public class ToolbarTabDisplayerUI extends AbstractTabDisplayerUI {
49     private JToolBar toolbar = null;
50     private static final Border JavaDoc buttonBorder;
51     
52     static {
53         //Get the HIE requested button border via an ugly hack
54
Border JavaDoc b = (Border JavaDoc) UIManager.get("nb.tabbutton.border"); //NOI18N
55

56         if (b == null) {
57             JToolBar toolbar = new JToolBar();
58             JButton button = new JButton();
59             toolbar.setRollover(true);
60             toolbar.add(button);
61             b = button.getBorder();
62             toolbar.remove(button);
63         }
64         
65         buttonBorder = b;
66     }
67     
68     /** Creates a new instance of ToolbarTabDisplayerUI */
69     public ToolbarTabDisplayerUI(TabDisplayer disp) {
70         super (disp);
71     }
72     
73     public static ComponentUI JavaDoc createUI (JComponent jc) {
74         return new ToolbarTabDisplayerUI ((TabDisplayer) jc);
75     }
76     
77     protected TabLayoutModel createLayoutModel() {
78         //not used
79
return null;
80     }
81     
82     protected void install() {
83         toolbar = new TabToolbar();
84         toolbar.setLayout (new AutoGridLayout());
85         toolbar.setFloatable (false);
86         toolbar.setRollover( true );
87         displayer.setLayout (new BorderLayout());
88         displayer.add (toolbar, BorderLayout.CENTER);
89         if (displayer.getModel() != null && displayer.getModel().size() > 0) {
90             syncButtonsWithModel();
91         }
92     }
93     
94     protected void modelChanged() {
95         if (syncButtonsWithModel()) {
96             if (displayer.getParent() != null) {
97                 ((JComponent) displayer.getParent()).revalidate();
98             }
99         }
100     }
101     
102     protected MouseListener JavaDoc createMouseListener() {
103         return null;
104     }
105     
106     private IndexButton findButtonFor (int index) {
107         Component[] c = toolbar.getComponents();
108         for (int i=0; i < c.length; i++) {
109             if (c[i] instanceof IndexButton && ((IndexButton) c[i]).getIndex() == index) {
110                 return (IndexButton) c[i];
111             }
112         }
113         return null;
114     }
115     
116     public void requestAttention (int tab) {
117         //not implemented
118
}
119     
120     public void cancelRequestAttention (int tab) {
121         //not implemented
122
}
123     
124     protected ChangeListener JavaDoc createSelectionListener() {
125         return new ChangeListener JavaDoc() {
126             private int lastKnownSelection = -1;
127             public void stateChanged (ChangeEvent JavaDoc ce) {
128                 int selection = selectionModel.getSelectedIndex();
129                 if (selection != lastKnownSelection) {
130                     if (lastKnownSelection != -1) {
131                         IndexButton last = findButtonFor(lastKnownSelection);
132                         if (last != null) {
133                             last.getModel().setSelected(false);
134                         }
135                     }
136                     if (selection != -1) {
137                         IndexButton current = findButtonFor (selection);
138                         if (toolbar.getComponentCount() == 0) {
139                             syncButtonsWithModel();
140                         }
141                         if (current != null) {
142                             current.getModel().setSelected (true);
143                         }
144                     }
145                 }
146                 lastKnownSelection = selection;
147             }
148         };
149     }
150     
151     public Polygon getExactTabIndication(int index) {
152         JToggleButton jb = findButtonFor (index);
153         if (jb != null) {
154             return new EqualPolygon (jb.getBounds());
155         } else {
156             return new EqualPolygon (new Rectangle());
157         }
158     }
159     
160     public Polygon getInsertTabIndication(int index) {
161         return getExactTabIndication (index);
162     }
163     
164     public Rectangle getTabRect(int index, Rectangle destination) {
165         destination.setBounds(findButtonFor(index).getBounds());
166         return destination;
167     }
168     
169     public int tabForCoordinate(Point p) {
170         Point p1 = SwingUtilities.convertPoint(displayer, p, toolbar);
171         Component c = toolbar.getComponentAt(p1);
172         if (c instanceof IndexButton) {
173             return ((IndexButton) c).getIndex();
174         }
175         return -1;
176     }
177     
178     public Dimension getPreferredSize(JComponent c) {
179         return toolbar.getPreferredSize();
180     }
181
182     public Dimension getMinimumSize(JComponent c) {
183         return toolbar.getMinimumSize();
184     }
185
186     
187     private boolean syncButtonsWithModel() {
188         assert SwingUtilities.isEventDispatchThread();
189         
190         int expected = displayer.getModel().size();
191         int actual = toolbar.getComponentCount();
192         boolean result = actual != expected;
193         if (result) {
194             if (expected > actual) {
195                 for (int i = actual; i < expected; i++) {
196                     toolbar.add(new IndexButton());
197                 }
198             } else if (expected < actual) {
199                 for (int i=expected; i < actual; i++) {
200                     toolbar.remove(toolbar.getComponentCount() -1);
201                 }
202             }
203         }
204         int selIdx = selectionModel.getSelectedIndex();
205         if (selIdx != -1) {
206             findButtonFor(selIdx).setSelected(true);
207         }
208         if (result) {
209             displayer.revalidate();
210             displayer.repaint();
211         }
212         return result;
213     }
214
215     public Icon getButtonIcon(int buttonId, int buttonState) {
216         return null;
217     }
218     
219     private ButtonGroup bg = new ButtonGroup();
220     private static int fontHeight = -1;
221     private static int ascent = -1;
222     
223     /**
224      * A button which will get its content from an index in the datamodel
225      * which corresponds to its index in its parent's component hierarchy.
226      */

227     public final class IndexButton extends JToggleButton implements ActionListener JavaDoc {
228         private String JavaDoc lastKnownText = null;
229
230         /** Create a new button representing an index in the model. The index is immutable for the life of the
231          * button.
232          */

233         public IndexButton () {
234             addActionListener(this);
235             setFont (displayer.getFont());
236             setFocusable(false);
237             setBorder (buttonBorder);
238             setMargin(new Insets(0, 3, 0, 3));
239             setRolloverEnabled( true );
240         }
241
242         public void addNotify() {
243             super.addNotify();
244             ToolTipManager.sharedInstance().registerComponent(this);
245             bg.add(this);
246         }
247
248         public void removeNotify() {
249             super.removeNotify();
250             ToolTipManager.sharedInstance().unregisterComponent(this);
251             bg.remove(this);
252         }
253
254         /** Accessor for the UI delegate to determine if the tab displayer is currently active */
255         public boolean isActive() {
256             return displayer.isActive();
257         }
258         
259         public String JavaDoc getText() {
260              //so the font height is included in super.getPreferredSize();
261
return " ";
262         }
263
264         public String JavaDoc doGetText() {
265             int idx = getIndex();
266             if (idx == -1) {
267                 //We're being called in the superclass constructor when the UI is
268
//assigned
269
return "";
270             }
271             if (getIndex() < displayer.getModel().size()) {
272                 lastKnownText = displayer.getModel().getTab(idx).getText();
273             } else {
274                 return "This tab doesn't exist."; //NOI18N
275
}
276             return lastKnownText;
277         }
278         
279         public Dimension getPreferredSize() {
280             Dimension result = super.getPreferredSize();
281             String JavaDoc s = doGetText();
282             int w = DefaultTabLayoutModel.textWidth(s, getFont());
283             result.width += w;
284             // as we cannot get the button small enough using the margin and border...
285
if (Utilities.isMac()) {
286                 // #67128 the -3 heuristics seems to cripple the buttons on macosx. it looks ok otherwise.
287
result.height -= 3;
288             }
289             return result;
290         }
291         
292         public void paintComponent (Graphics g) {
293             super.paintComponent(g);
294             String JavaDoc s = doGetText();
295             
296             Insets ins = getInsets();
297             int x = ins.left;
298             int w = getWidth() - (ins.left + ins.right);
299             int h = getHeight();
300             
301             int txtW = DefaultTabLayoutModel.textWidth(s, getFont());
302             if (txtW < w) {
303                 x += (w / 2) - (txtW / 2);
304             }
305             
306             if (fontHeight == -1) {
307                 FontMetrics fm = g.getFontMetrics(getFont());
308                 fontHeight = fm.getHeight();
309                 ascent = fm.getMaxAscent();
310             }
311             int y = ins.top + ascent + (((getHeight() - (ins.top + ins.bottom)) / 2) - (fontHeight / 2));
312             
313             HtmlRenderer.renderString(s, g, x, y, w, h, getFont(), getForeground(),
314                 HtmlRenderer.STYLE_TRUNCATE, true);
315         }
316         
317         public String JavaDoc getToolTipText() {
318             return displayer.getModel().getTab(getIndex()).getTooltip();
319         }
320
321         /** Implementation of ActionListener - sets the selected index in the selection model */
322         public final void actionPerformed(ActionEvent JavaDoc e) {
323             selectionModel.setSelectedIndex (getIndex());
324         }
325
326         /** Get the index into the data model that this button represents */
327         public int getIndex() {
328             if (getParent() != null) {
329                 return Arrays.asList(getParent().getComponents()).indexOf(this);
330             }
331             return -1;
332         }
333         
334         public Icon getIcon() {
335             return null;
336         }
337
338         /**
339          * Test if the text or icon in the model has changed since the last time <code>getText()</code> or
340          * <code>getIcon()</code> was called. If a change has occured, the button will fire the appropriate
341          * property changes, including preferred size, to ensure the tab displayer is re-laid out correctly.
342          * This method is called when a change happens in the model over the index this button represents.
343          *
344          * @return true if something has changed
345          */

346         final boolean checkChanged() {
347             boolean result = false;
348             String JavaDoc txt = lastKnownText;
349             String JavaDoc nu = doGetText();
350             if (nu != txt) { //Equality compare probably not needed
351
firePropertyChange ("text", lastKnownText, doGetText()); //NOI18N
352
result = true;
353             }
354             if (result) {
355                 firePropertyChange ("preferredSize", null, null); //NOI18N
356
}
357             return result;
358         }
359     }
360     
361     /**
362      * Originally in org.netbeans.form.palette.CategorySelectPanel.
363      *
364      * @author Tomas Pavek
365      */

366     static class AutoGridLayout implements LayoutManager {
367
368         private int h_margin_left = 2; // margin on the left
369
private int h_margin_right = 1; // margin on the right
370
private int v_margin_top = 2; // margin at the top
371
private int v_margin_bottom = 3; // margin at the bottom
372
private int h_gap = 1; // horizontal gap between components
373
private int v_gap = 1; // vertical gap between components
374

375         public void addLayoutComponent(String JavaDoc name, Component comp) {
376         }
377
378         public void removeLayoutComponent(Component comp) {
379         }
380
381         public Dimension preferredLayoutSize(Container parent) {
382             synchronized (parent.getTreeLock()) {
383                 int containerWidth = parent.getWidth();
384                 int count = parent.getComponentCount();
385
386                 if (containerWidth <= 0 || count == 0) {
387                     // compute cumulated width of all components placed on one row
388
int cumulatedWidth = 0;
389                     int height = 0;
390                     for (int i=0; i < count; i++) {
391                         Dimension size = parent.getComponent(i).getPreferredSize();
392                         cumulatedWidth += size.width;
393                         if (i + 1 < count)
394                             cumulatedWidth += h_gap;
395                         if (size.height > height)
396                             height = size.height;
397                     }
398                     cumulatedWidth += h_margin_left + h_margin_right;
399                     height += v_margin_top + v_margin_bottom;
400                     return new Dimension(cumulatedWidth, height);
401                 }
402
403                 // otherwise the container already has some width set - so we
404
// just compute preferred height for it
405

406                 // get max. component width and height
407
int columnWidth = 0;
408                 int rowHeight = 0;
409                 for (int i=0; i < count; i++) {
410                     Dimension size = parent.getComponent(i).getPreferredSize();
411                     if (size.width > columnWidth)
412                         columnWidth = size.width;
413                     if (size.height > rowHeight)
414                         rowHeight = size.height;
415                 }
416
417                 // compute column count
418
int columnCount = 0;
419                 int w = h_margin_left + columnWidth + h_margin_right;
420                 do {
421                     columnCount++;
422                     w += h_gap + columnWidth;
423                 }
424                 while (w <= containerWidth && columnCount < count);
425
426                 // compute row count and preferred height
427
int rowCount = count / columnCount +
428                                (count % columnCount > 0 ? 1 : 0);
429                 int prefHeight = v_margin_top + rowCount * rowHeight
430                                      + (rowCount - 1) * v_gap + v_margin_bottom;
431
432                 Dimension result = new Dimension(containerWidth, prefHeight);
433                 return result;
434             }
435         }
436
437         public Dimension minimumLayoutSize(Container parent) {
438             return new Dimension(h_margin_left + h_margin_right,
439                                  v_margin_top + v_margin_bottom);
440         }
441
442         public void layoutContainer(Container parent) {
443             synchronized (parent.getTreeLock()) {
444                 int count = parent.getComponentCount();
445                 if (count == 0)
446                     return;
447
448                 // get max. component width and height
449
int columnWidth = 0;
450                 int rowHeight = 0;
451                 for (int i=0; i < count; i++) {
452                     Dimension size = parent.getComponent(i).getPreferredSize();
453                     if (size.width > columnWidth)
454                         columnWidth = size.width;
455                     if (size.height > rowHeight)
456                         rowHeight = size.height;
457                 }
458
459                 // compute column count
460
int containerWidth = parent.getWidth();
461                 int columnCount = 0;
462                 int w = h_margin_left + columnWidth + h_margin_right;
463                 do {
464                     columnCount++;
465                     w += h_gap + columnWidth;
466                 }
467                 while (w <= containerWidth && columnCount < count);
468
469                 // adjust layout matrix - balance number of columns according
470
// to last row
471
if (count % columnCount > 0) {
472                     int roundedRowCount = count / columnCount;
473                     int lastRowEmpty = columnCount - count % columnCount;
474                     if (lastRowEmpty > roundedRowCount)
475                         columnCount -= lastRowEmpty / (roundedRowCount + 1);
476                 }
477
478                 // adjust column width
479
if (count > columnCount)
480                     columnWidth = (containerWidth - h_margin_left - h_margin_right
481                                      - (columnCount - 1) * h_gap) / columnCount;
482                 if (columnWidth < 0)
483                     columnWidth = 0;
484                 
485                 // layout the components
486
for (int i=0, col=0, row=0; i < count; i++) {
487                     parent.getComponent(i).setBounds(
488                                        h_margin_left + col * (columnWidth + h_gap),
489                                        v_margin_top + row * (rowHeight + v_gap),
490                                        columnWidth,
491                                        rowHeight);
492                     if (++col >= columnCount) {
493                         col = 0;
494                         row++;
495                     }
496                 }
497             }
498         }
499     }
500     
501     static class TabToolbar extends JToolBar {
502         public void paintComponent(Graphics g) {
503             super.paintComponent(g);
504
505             Color color = g.getColor();
506
507             g.setColor(UIManager.getColor("controlLtHighlight")); // NOI18N
508
g.drawLine(0, 0, getWidth(), 0);
509             g.drawLine(0, 0, 0, getHeight()-1);
510             g.setColor(UIManager.getColor("controlShadow")); // NOI18N
511
g.drawLine(0, getHeight()-1, getWidth(), getHeight()-1);
512
513             g.setColor(color);
514         }
515     }
516 }
517
Popular Tags