001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.xml.xam.ui.category;
043:
044: import java.awt.BorderLayout;
045: import java.awt.Component;
046: import java.awt.GridBagConstraints;
047: import java.awt.GridBagLayout;
048: import java.awt.event.ActionEvent;
049: import java.util.ArrayList;
050: import java.util.List;
051: import javax.swing.AbstractAction;
052: import javax.swing.Action;
053: import javax.swing.ButtonGroup;
054: import javax.swing.JPanel;
055: import javax.swing.JToggleButton;
056: import javax.swing.JToolBar;
057: import javax.swing.UIManager;
058: import javax.swing.border.Border;
059: import org.netbeans.modules.xml.xam.ui.search.DefaultSearchControlPanel;
060:
061: /**
062: * The default implementation of CategoryPane.
063: *
064: * @author Nathan Fiedler
065: */
066: public class DefaultCategoryPane extends AbstractCategoryPane {
067: /** The top component of our interface. */
068: private JPanel visualComponent;
069: /** Component for search interface. */
070: private DefaultSearchControlPanel searchComponent;
071: /** Where the Category components reside. */
072: private JPanel categoryPanel;
073: /** List of actions to show the categories. */
074: private List<ShowCategoryAction> categoryActions;
075: /** Makes the buttons act like radio buttons. */
076: private ButtonGroup buttonGroup;
077:
078: /**
079: * Creates a new instance of DefaultCategoryPane.
080: */
081: public DefaultCategoryPane() {
082: categoryActions = new ArrayList<ShowCategoryAction>();
083: initComponents();
084: }
085:
086: public void addCategory(Category category) {
087: categoryActions.add(new ShowCategoryAction(category, this ));
088: }
089:
090: public Component getComponent() {
091: return visualComponent;
092: }
093:
094: public SearchComponent getSearchComponent() {
095: return searchComponent;
096: }
097:
098: /**
099: * Construct our user interface.
100: */
101: private void initComponents() {
102: // Button group for our category buttons.
103: buttonGroup = new ButtonGroup();
104:
105: // Build our overall container.
106: visualComponent = new JPanel(new GridBagLayout()) {
107: /** silence compiler warnings */
108: private static final long serialVersionUID = 1L;
109:
110: @Override
111: public void requestFocus() {
112: super .requestFocus();
113: // Pass focus to category component to ease keyboard navigation.
114: Category cat = getCategory();
115: if (cat != null) {
116: cat.getComponent().requestFocus();
117: }
118: }
119:
120: @Override
121: public boolean requestFocusInWindow() {
122: boolean retVal = super .requestFocusInWindow();
123: // Pass focus to category component to ease keyboard navigation.
124: Category cat = getCategory();
125: if (cat != null) {
126: return cat.getComponent().requestFocusInWindow();
127: }
128: return retVal;
129: }
130: };
131:
132: // Build the primary view component.
133: GridBagConstraints gbc = new GridBagConstraints();
134: gbc.fill = GridBagConstraints.BOTH;
135: gbc.gridwidth = GridBagConstraints.REMAINDER;
136: gbc.weightx = 1.0d;
137: gbc.weighty = 1.0d;
138: categoryPanel = new JPanel(new BorderLayout());
139: visualComponent.add(categoryPanel, gbc);
140:
141: // Build the search component.
142: searchComponent = new DefaultSearchControlPanel(this );
143: searchComponent.hideComponent();
144: gbc.anchor = GridBagConstraints.WEST;
145: gbc.fill = GridBagConstraints.HORIZONTAL;
146: gbc.weightx = 0.0d;
147: gbc.weighty = 0.0d;
148: visualComponent.add(searchComponent.getComponent(), gbc);
149: }
150:
151: public void populateToolbar(JToolBar toolbar) {
152: Category selected = getCategory();
153: // Get the NetBeans button border, if available.
154: Border border = UIManager.getBorder("nb.tabbutton.border"); //NOI18N
155: for (ShowCategoryAction action : categoryActions) {
156: JToggleButton button = new JToggleButton(action);
157: // Action has a name for accessibility purposes, but we do
158: // not want that to appear in the button label.
159: button.setText(null);
160: button.getAccessibleContext().setAccessibleName(
161: action.getCategory().getTitle());
162: button.setRolloverEnabled(true);
163: if (border != null) {
164: button.setBorder(border);
165: }
166: buttonGroup.add(button);
167: if (selected == null) {
168: if (buttonGroup.getButtonCount() == 1) {
169: // Make the first button the chosen one.
170: button.setSelected(true);
171: // Select the category so it is visible.
172: action.actionPerformed(null);
173: }
174: } else {
175: if (action.getCategory().equals(selected)) {
176: button.setSelected(true);
177: }
178: }
179: toolbar.add(button);
180: }
181: }
182:
183: @Override
184: public void setCategory(Category category) {
185: Category oldcat = getCategory();
186: super .setCategory(category);
187: if (oldcat != null) {
188: Component oldcomp = oldcat.getComponent();
189: categoryPanel.remove(oldcomp);
190: oldcat.componentHidden();
191: }
192: Component newcomp = category.getComponent();
193: categoryPanel.add(newcomp, BorderLayout.CENTER);
194: category.componentShown();
195: categoryPanel.validate();
196: categoryPanel.repaint();
197: searchComponent.updateSearchProviders();
198: }
199:
200: /**
201: * An action to show a category.
202: */
203: private static class ShowCategoryAction extends AbstractAction {
204: private static final long serialVersionUID = 1L;
205: /** The Category we show. */
206: private transient Category category;
207: /** The CategoryPane containing the Category. */
208: private transient CategoryPane pane;
209:
210: /**
211: * Creates a new instance of ShowCategoryAction.
212: *
213: * @param category the Category to be shown.
214: * @param pane the CategoryPane for category.
215: */
216: public ShowCategoryAction(Category category, CategoryPane pane) {
217: this .category = category;
218: this .pane = pane;
219: putValue(Action.NAME, category.getTitle());
220: putValue(Action.SHORT_DESCRIPTION, category
221: .getDescription());
222: putValue(Action.SMALL_ICON, category.getIcon());
223: }
224:
225: public void actionPerformed(ActionEvent e) {
226: pane.setCategory(category);
227: }
228:
229: /**
230: * Return the Category associated with this action.
231: *
232: * @return Category this action displays.
233: */
234: public Category getCategory() {
235: return category;
236: }
237: }
238: }
|