KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xam > ui > column > LinkPanel


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.xam.ui.column;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.awt.Color JavaDoc;
24 import java.awt.Component JavaDoc;
25 import java.awt.Dimension JavaDoc;
26 import java.awt.Graphics JavaDoc;
27 import java.awt.GridBagConstraints JavaDoc;
28 import java.awt.GridBagLayout JavaDoc;
29 import java.awt.GridLayout JavaDoc;
30 import java.awt.Insets JavaDoc;
31 import java.awt.Point JavaDoc;
32 import java.awt.Rectangle JavaDoc;
33 import java.awt.event.ActionEvent JavaDoc;
34 import java.awt.event.ActionListener JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Map.Entry;
39 import java.util.Set JavaDoc;
40 import javax.accessibility.AccessibleContext JavaDoc;
41 import javax.swing.AbstractAction JavaDoc;
42 import javax.swing.BorderFactory JavaDoc;
43 import javax.swing.Box JavaDoc;
44 import javax.swing.Icon JavaDoc;
45 import javax.swing.JButton JavaDoc;
46 import javax.swing.JLabel JavaDoc;
47 import javax.swing.JPanel JavaDoc;
48 import javax.swing.JScrollPane JavaDoc;
49 import javax.swing.JViewport JavaDoc;
50 import javax.swing.UIManager JavaDoc;
51 import javax.swing.border.Border JavaDoc;
52 import javax.swing.border.EmptyBorder JavaDoc;
53 import javax.swing.event.ChangeEvent JavaDoc;
54 import javax.swing.event.ChangeListener JavaDoc;
55
56 /**
57  * Contains and manages the link buttons that act as bread crumbs
58  * for quickly browsing an instance of ColumnView.
59  *
60  * @author Nathan Fiedler
61  */

62 public class LinkPanel extends JPanel JavaDoc implements ActionListener JavaDoc {
63     private static final long serialVersionUID = 1L;
64     /** Occupies space to the right of the buttons. */
65     private Component JavaDoc layoutFiller;
66     /** Mapping of buttons to columns. */
67     private Map JavaDoc<LinkButton, Column> buttonColumnMap;
68     /** Scroll pane to manage, if non-null. */
69     private JScrollPane JavaDoc scrollPane;
70     /** The column view to scroll. */
71     private ColumnView columnView;
72     /** The container for the links. */
73     private JPanel JavaDoc linkPanel;
74     private static final int ICON_WIDTH = 11;
75     private static final int ICON_HEIGHT = 11;
76     private static final int[] xpoints = new int[20];
77     private static final int[] ypoints = new int[20];
78
79     /**
80      * Creates a new instance of LinkPanel.
81      *
82      * @param view the column view to scroll.
83      */

84     public LinkPanel(ColumnView view) {
85         super(new BorderLayout JavaDoc());
86         linkPanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
87         scrollPane = new JScrollPane JavaDoc(linkPanel,
88                 JScrollPane.VERTICAL_SCROLLBAR_NEVER,
89                 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
90         scrollPane.setBorder(null);
91         add(scrollPane, BorderLayout.CENTER);
92         columnView = view;
93         // Try to use the toolbar border defined in NetBeans core.
94
Border JavaDoc b = (Border JavaDoc) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
95
if (b == null) {
96             // But, fall back on having something rather than nothing.
97
b = BorderFactory.createMatteBorder(0, 0, 1, 0, Color.BLACK);
98         }
99         setBorder(b);
100         buttonColumnMap = new HashMap JavaDoc<LinkButton, Column>();
101
102         // Configure the scrolling buttons.
103
JButton JavaDoc left = new TimerButton(new ScrollLeftAction(scrollPane));
104         JButton JavaDoc right = new TimerButton(new ScrollRightAction(scrollPane));
105         configureButton(left, new LeftIcon());
106         configureButton(right, new RightIcon());
107         left.setPreferredSize(new Dimension JavaDoc(17, 17));
108         right.setPreferredSize(new Dimension JavaDoc(17, 17));
109         JPanel JavaDoc buttonPanel = new JPanel JavaDoc(new GridLayout JavaDoc(1, 0));
110         buttonPanel.setBorder(new EmptyBorder JavaDoc(0, 3, 1, 2));
111         buttonPanel.add(left);
112         buttonPanel.add(right);
113         add(buttonPanel, BorderLayout.EAST);
114     }
115
116     public void actionPerformed(ActionEvent JavaDoc e) {
117         Object JavaDoc src = e.getSource();
118         if (src instanceof LinkButton) {
119             LinkButton button = (LinkButton) src;
120             // Scroll the link button to the center, which is in
121
// addition to the default scroll pane behavior of making
122
// the focused component visible.
123
if (scrollPane != null) {
124                 JViewport JavaDoc vp = scrollPane.getViewport();
125                 Rectangle JavaDoc visRect = vp.getViewRect();
126                 Rectangle JavaDoc compRect = button.getBounds();
127                 Component JavaDoc view = vp.getView();
128                 visRect.x = Math.max(0, Math.min(compRect.x -
129                         (visRect.width - compRect.width) / 2,
130                         view.getWidth() - visRect.width));
131                 vp.scrollRectToVisible(visRect);
132             }
133             // Scroll to the corresponding column.
134
Column column = buttonColumnMap.get(button);
135             columnView.scrollToColumn(column, true);
136         }
137     }
138
139     /**
140      * Adds a link button to the panel for the given column.
141      *
142      * @param column Column for which to add button.
143      */

144     public void appendLink(Column column) {
145         if (linkPanel.getComponentCount() > 0) {
146             // There are other links, we need to add '>' now.
147
GridBagConstraints JavaDoc gbc = new GridBagConstraints JavaDoc();
148             // Pad for five pixels on either side, taking account
149
// of the 3 pixel inset of the button (below). Note that
150
// > character has two blank pixels on the left.
151
gbc.insets = new Insets JavaDoc(0, 3, 2, 0);
152             linkPanel.add(new JLabel JavaDoc(">"), gbc); // NOI18N
153
}
154         LinkButton button = new LinkButton(column.getTitle());
155         AccessibleContext JavaDoc ac = button.getAccessibleContext();
156         ac.setAccessibleName(column.getTitle());
157         ac.setAccessibleDescription(column.getDescription());
158         button.addActionListener(this);
159         buttonColumnMap.put(button, column);
160         GridBagConstraints JavaDoc gbc = new GridBagConstraints JavaDoc();
161         gbc.insets = new Insets JavaDoc(0, 3, 0, 0);
162         linkPanel.add(button, gbc);
163         // Fill the space to the right so the links will be left-aligned.
164
if (layoutFiller != null) {
165             linkPanel.remove(layoutFiller);
166         } else {
167             layoutFiller = Box.createHorizontalGlue();
168         }
169         gbc.fill = GridBagConstraints.HORIZONTAL;
170         gbc.weightx = 1.0d;
171         linkPanel.add(layoutFiller, gbc);
172         linkPanel.revalidate();
173         linkPanel.repaint();
174     }
175
176     /**
177      * Removes all of the links from the panel.
178      */

179     public void clearLinks() {
180         linkPanel.removeAll();
181         buttonColumnMap.clear();
182         linkPanel.revalidate();
183         linkPanel.repaint();
184     }
185
186     /**
187      * Configure a button for the link panel.
188      *
189      * @param button the button.
190      * @param icon icon for the button.
191      */

192     private static void configureButton(JButton JavaDoc button, Icon JavaDoc icon) {
193         button.setIcon(icon);
194         button.setMargin(null);
195         button.setText(null);
196         button.setFocusable(false);
197     }
198
199     /**
200      * Remove the links from the panel, starting at the given offset.
201      *
202      * @param index link index from which to start removing.
203      */

204     public void truncateLinks(int index) {
205         // Account for the layout filler, which we want to preserve.
206
int count = linkPanel.getComponentCount() - 1;
207         // Account for the separators between the buttons.
208
index = index * 2 - 1;
209         while (count > index) {
210             Component JavaDoc child = linkPanel.getComponent(index);
211             if (child instanceof LinkButton) {
212                 buttonColumnMap.remove((LinkButton) child);
213             }
214             linkPanel.remove(index);
215             count--;
216         }
217         linkPanel.revalidate();
218         linkPanel.repaint();
219     }
220
221     /**
222      * Update the link title to reflect a change in the column.
223      *
224      * @param column Column for which to update link text.
225      */

226     public void updateLink(Column column) {
227         Set JavaDoc<Entry<LinkButton, Column>> entries = buttonColumnMap.entrySet();
228         Iterator JavaDoc<Entry<LinkButton, Column>> iter = entries.iterator();
229         while (iter.hasNext()) {
230             Entry<LinkButton, Column> entry = iter.next();
231             if (entry.getValue().equals(column)) {
232                 LinkButton button = entry.getKey();
233                 button.setText(column.getTitle());
234             }
235         }
236     }
237
238     /**
239      * Scrolls the link panel to the left.
240      */

241     private static class ScrollLeftAction extends AbstractAction JavaDoc implements
242             ChangeListener JavaDoc {
243         /** silence compiler warnings */
244         private static final long serialVersionUID = 1L;
245         /** The pane to be scrolled. */
246         private JScrollPane JavaDoc pane;
247
248         /**
249          * Creates a new instance of ScrollLeftAction.
250          *
251          * @param pane the scroll pane to manage.
252          */

253         public ScrollLeftAction(JScrollPane JavaDoc pane) {
254             super();
255             this.pane = pane;
256             pane.getViewport().addChangeListener(this);
257         }
258         
259         public void actionPerformed(ActionEvent JavaDoc e) {
260             JViewport JavaDoc vp = pane.getViewport();
261             Dimension JavaDoc size = vp.getExtentSize();
262             Point JavaDoc p = vp.getViewPosition();
263             p.x -= (size.width / 10);
264             if (p.x < 0) {
265                 p.x = 0;
266             }
267             vp.setViewPosition(p);
268         }
269
270         public void stateChanged(ChangeEvent JavaDoc e) {
271             JViewport JavaDoc vp = pane.getViewport();
272             Point JavaDoc p = vp.getViewPosition();
273             setEnabled(p.x > 0);
274         }
275     }
276
277     /**
278      * Scrolls the link panel to the right.
279      */

280     private static class ScrollRightAction extends AbstractAction JavaDoc implements
281             ChangeListener JavaDoc {
282         /** silence compiler warnings */
283         private static final long serialVersionUID = 1L;
284         /** The pane to be scrolled. */
285         private JScrollPane JavaDoc pane;
286
287         /**
288          * Creates a new instance of ScrollRightAction.
289          *
290          * @param pane the scroll pane to manage.
291          */

292         public ScrollRightAction(JScrollPane JavaDoc pane) {
293             super();
294             this.pane = pane;
295             pane.getViewport().addChangeListener(this);
296         }
297
298         public void actionPerformed(ActionEvent JavaDoc e) {
299             JViewport JavaDoc vp = pane.getViewport();
300             Dimension JavaDoc size = vp.getExtentSize();
301             Point JavaDoc p = vp.getViewPosition();
302             p.x += (size.width / 10);
303             int max = vp.getViewSize().width - size.width;
304             if (p.x > max) {
305                 p.x = max;
306             }
307             vp.setViewPosition(p);
308         }
309
310         public void stateChanged(ChangeEvent JavaDoc e) {
311             JViewport JavaDoc vp = pane.getViewport();
312             Dimension JavaDoc size = vp.getExtentSize();
313             Point JavaDoc p = vp.getViewPosition();
314             int max = vp.getViewSize().width - size.width;
315             setEnabled(p.x < max);
316         }
317     }
318
319     /**
320      * Copied from core/swing/tabcontrol; paints a left arrow.
321      */

322     private static class LeftIcon implements Icon JavaDoc {
323
324         public int getIconHeight() {
325             return ICON_HEIGHT;
326         }
327
328         public int getIconWidth() {
329             return ICON_WIDTH;
330         }
331
332         public void paintIcon(Component JavaDoc c, Graphics JavaDoc g, int x, int y) {
333             y -= 2;
334             g.setColor(c.isEnabled() ? c.getForeground() :
335                 UIManager.getColor("controlShadow")); //NOI18N
336
int wid = getIconWidth();
337             int hi = getIconHeight() + 1;
338             xpoints[0] = x + (wid - 4);
339             ypoints[0] = y + 2;
340             xpoints[1] = xpoints[0];
341             ypoints[1] = y + hi + 1;
342             xpoints[2] = x + 2;
343             ypoints[2] = y + (hi / 2) + 1;
344             g.fillPolygon(xpoints, ypoints, 3);
345         }
346     }
347
348     /**
349      * Copied from core/swing/tabcontrol; paints a right arrow.
350      */

351     private static class RightIcon implements Icon JavaDoc {
352
353         public int getIconWidth() {
354             return ICON_WIDTH;
355         }
356
357         public int getIconHeight() {
358             return ICON_HEIGHT - 2;
359         }
360
361         public void paintIcon(Component JavaDoc c, Graphics JavaDoc g, int x, int y) {
362             y -= 2;
363             g.setColor(c.isEnabled() ? c.getForeground() :
364                 UIManager.getColor("controlShadow")); //NOI18N
365
int wid = getIconWidth();
366             int hi = getIconHeight() + 1;
367             xpoints[0] = x + 3;
368             ypoints[0] = y + 1;
369             xpoints[1] = x + 3;
370             ypoints[1] = y + hi + 1;
371             xpoints[2] = x + (wid - 4) + 1;
372             ypoints[2] = y + (hi / 2) + 1;
373             g.fillPolygon(xpoints, ypoints, 3);
374         }
375     }
376 }
377
Popular Tags