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: package org.netbeans.modules.sql.framework.ui.graph.view.impl;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.FlowLayout;
048: import java.awt.GridBagConstraints;
049: import java.awt.GridBagLayout;
050: import java.awt.KeyboardFocusManager;
051: import java.awt.event.FocusEvent;
052: import java.awt.event.FocusListener;
053: import java.awt.event.ItemEvent;
054: import java.awt.event.ItemListener;
055: import java.awt.event.KeyEvent;
056: import java.awt.event.KeyListener;
057: import java.awt.event.MouseAdapter;
058: import java.awt.event.MouseEvent;
059: import java.util.HashSet;
060: import java.util.Set;
061:
062: import javax.swing.BorderFactory;
063: import javax.swing.Icon;
064: import javax.swing.JCheckBox;
065: import javax.swing.JComponent;
066: import javax.swing.JLabel;
067: import javax.swing.JPanel;
068: import javax.swing.JTabbedPane;
069: import javax.swing.KeyStroke;
070: import javax.swing.SwingConstants;
071:
072: import org.netbeans.modules.sql.framework.ui.graph.IGraphView;
073: import org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfo;
074: import org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfoCategory;
075: import org.netbeans.modules.sql.framework.ui.graph.IOperatorXmlInfoModel;
076: import org.openide.nodes.Children;
077: import org.openide.nodes.Node;
078:
079: /**
080: * @author Ritesh Adval
081: * @author Jonathan Giron
082: * @version $Revision$
083: */
084: public class OperatorSelectionPanel extends JPanel {
085: private static final int MIN_WIDTH = 400;
086: private static final int MIN_HEIGHT = 230;
087:
088: private IOperatorXmlInfoModel model;
089: private JTabbedPane tabPane;
090: private boolean showNames = true;
091: private IGraphView graphView;
092: private int toolbarType = IOperatorXmlInfoModel.CATEGORY_ALL;
093:
094: /**
095: * Creates a new instance of OperatorSelectionPanel using the given model.
096: *
097: * @param m OperatorXmlInfoModel containing operator information
098: */
099: public OperatorSelectionPanel(IGraphView gView,
100: IOperatorXmlInfoModel m, int type) {
101: this .model = m;
102: this .graphView = gView;
103: this .toolbarType = type;
104: this .setLayout(new BorderLayout());
105: this .tabPane = new JTabbedPane();
106: initializeSelectionPanel();
107: setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
108: this .add(BorderLayout.CENTER, tabPane);
109: }
110:
111: /**
112: * Selects the panel corresponding to the given category name.
113: *
114: * @param catName name of category whose panel is to be selected
115: */
116: public void selectCategory(String catName) {
117: int i = tabPane.indexOfTab(catName);
118: tabPane.setSelectedIndex(i);
119: }
120:
121: /**
122: * Updates display to show or hide names of operator items, depending on value of
123: * given flag.
124: *
125: * @param newFlag true to display operator names, false to hide
126: */
127: public synchronized void updateShowNames(boolean newFlag) {
128: if (showNames != newFlag) {
129: showNames = newFlag;
130: Component[] panels = tabPane.getComponents();
131: for (int i = 0; i < panels.length; i++) {
132: if (panels[i] instanceof OperatorCategoryPanel) {
133: ((OperatorCategoryPanel) panels[i])
134: .updateShowNames(newFlag);
135: }
136: }
137: }
138: }
139:
140: private void initializeSelectionPanel() {
141: Node node = model.getRootNode();
142: Children children = node.getChildren();
143: Node[] nodes = children.getNodes();
144: for (int i = 0; i < nodes.length; i++) {
145: Node catNode = nodes[i];
146: IOperatorXmlInfoCategory catXmlInfo = (IOperatorXmlInfoCategory) catNode;
147: if (shouldDisplay(catXmlInfo.getToolbarType())) {
148: OperatorCategoryPanel catPanel = new OperatorCategoryPanel(
149: catNode);
150: tabPane.add(catNode.getDisplayName(), catPanel);
151: }
152: }
153: }
154:
155: public void setToolbarType(int type) {
156: this .toolbarType = type;
157: }
158:
159: public int getToolbarType() {
160: return toolbarType;
161: }
162:
163: private boolean shouldDisplay(final int nodeType) {
164: return (IOperatorXmlInfoModel.CATEGORY_ALL == toolbarType
165: || IOperatorXmlInfoModel.CATEGORY_ALL == nodeType || (nodeType & toolbarType) != 0);
166: }
167:
168: class OperatorCategoryPanel extends JPanel {
169: private Node node;
170: private JPanel innerPnl;
171: private GridBagLayout layout;
172:
173: public OperatorCategoryPanel(Node myNode) {
174: node = myNode;
175: setName(node.getDisplayName());
176: setLayout(new BorderLayout());
177:
178: layout = new GridBagLayout();
179: innerPnl = new JPanel(layout);
180: this .add(innerPnl, BorderLayout.NORTH);
181:
182: // this.setLayout(new FlowLayout(FlowLayout.LEFT));
183: createOperators();
184: }
185:
186: public synchronized void updateShowNames(boolean showNames1) {
187: doUpdateShowNames(getComponents(), showNames1);
188: }
189:
190: private void doUpdateShowNames(Component[] children,
191: boolean showNames1) {
192: for (int i = 0; i < children.length; i++) {
193: if (children[i] instanceof OperatorCheckBox) {
194: ((OperatorCheckBox) children[i])
195: .setShowName(showNames1);
196: } else if (children[i] instanceof JPanel) {
197: doUpdateShowNames(((JPanel) children[i])
198: .getComponents(), showNames1);
199: }
200: }
201: }
202:
203: private void createOperators() {
204: Children children = node.getChildren();
205: Node[] nodes = children.getNodes();
206: int opsAdded = 0;
207:
208: for (int i = 0; i < nodes.length; i++) {
209: IOperatorXmlInfo opNode = (IOperatorXmlInfo) nodes[i];
210: if (OperatorSelectionPanel.this .shouldDisplay(opNode
211: .getToolbarType())) {
212: int rd = (opsAdded + 1) % 3;
213: boolean nextLine = (rd == 0);
214: addCheckBox(opNode, nextLine);
215: opsAdded++;
216: }
217: }
218: }
219:
220: private void addCheckBox(IOperatorXmlInfo node1,
221: boolean nextLine) {
222: GridBagConstraints c = new GridBagConstraints();
223:
224: JComponent checkBox = new OperatorCheckBox(node1, showNames);
225: c.fill = GridBagConstraints.BOTH;
226: c.weightx = 1.0;
227: if (nextLine) {
228: c.gridwidth = GridBagConstraints.REMAINDER;
229: }
230:
231: layout.setConstraints(checkBox, c);
232: innerPnl.add(checkBox);
233: }
234: }
235:
236: class OperatorCheckBox extends JPanel implements ItemListener,
237: FocusListener, KeyListener {
238: private JCheckBox cbox;
239: private JPanel labelWrapper;
240: private JLabel label;
241: private IOperatorXmlInfo opNode;
242:
243: public OperatorCheckBox(IOperatorXmlInfo node) {
244: this (node, true);
245: }
246:
247: public OperatorCheckBox(final IOperatorXmlInfo node,
248: boolean showName) {
249: setLayout(new FlowLayout(FlowLayout.LEADING));
250: setFocusable(true);
251:
252: opNode = node;
253: cbox = new JCheckBox();
254: cbox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
255: cbox.setFocusable(false);
256: add(cbox);
257:
258: MouseAdapter cboxClickListener = new MouseAdapter() {
259: public void mouseClicked(MouseEvent e) {
260: OperatorCheckBox.this .requestFocusInWindow();
261: }
262: };
263:
264: labelWrapper = new JPanel();
265: labelWrapper.setBorder(BorderFactory.createEmptyBorder(0,
266: 0, 0, 0));
267:
268: Icon myIcon = node.getIcon();
269: if (myIcon != null) {
270: JLabel iconLabel = new JLabel(node.getIcon(),
271: SwingConstants.LEADING);
272: iconLabel.setFocusable(false);
273: labelWrapper.add(iconLabel);
274: }
275:
276: label = new JLabel(node.getDisplayName(),
277: SwingConstants.LEADING);
278: label.setFocusable(false);
279:
280: labelWrapper.add(label);
281: labelWrapper.setToolTipText(node.getToolTip());
282: this .add(labelWrapper);
283:
284: cbox.setSelected(node.isChecked());
285: cbox.addItemListener(this );
286: cbox.addMouseListener(cboxClickListener);
287:
288: label.setVisible(showName);
289:
290: addFocusListener(this );
291: addKeyListener(this );
292:
293: // Set right, left arrow keys to be forward, backward traversal keys,
294: // respectively.
295: Set newForwardKeys = new HashSet(
296: getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
297: newForwardKeys.add(KeyStroke.getKeyStroke(
298: KeyEvent.VK_RIGHT, 0));
299: setFocusTraversalKeys(
300: KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
301: newForwardKeys);
302:
303: Set newBackwardKeys = new HashSet(
304: getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
305: newBackwardKeys.add(KeyStroke.getKeyStroke(
306: KeyEvent.VK_LEFT, 0));
307: setFocusTraversalKeys(
308: KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
309: newBackwardKeys);
310: }
311:
312: /**
313: * Invoked when an item has been selected or deselected by the user. The code
314: * written for this method performs the operations that need to occur when an item
315: * is selected (or deselected).
316: */
317: public void itemStateChanged(ItemEvent e) {
318: JCheckBox ckBox = (JCheckBox) e.getItem();
319: opNode.setChecked(ckBox.isSelected());
320: }
321:
322: public void setShowName(boolean showName) {
323: label.setVisible(showName);
324: revalidate();
325: repaint();
326: }
327:
328: public void focusGained(FocusEvent e) {
329: // Highlight the focused label.
330: labelWrapper.setBackground(Color.YELLOW);
331: this .revalidate();
332: this .repaint();
333: }
334:
335: public void focusLost(FocusEvent e) {
336: // Remove highlight from the previously focused label.
337: labelWrapper.setBackground(getParent().getBackground());
338: this .revalidate();
339: this .repaint();
340: }
341:
342: /*
343: * (non-Javadoc)
344: *
345: * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
346: */
347: public void keyTyped(KeyEvent e) {
348: }
349:
350: /*
351: * (non-Javadoc)
352: *
353: * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
354: */
355: public void keyPressed(KeyEvent e) {
356: int keyCode = e.getKeyCode();
357: switch (keyCode) {
358: case KeyEvent.VK_ENTER:
359: dropOperatorInstance();
360: e.consume();
361: break;
362:
363: case KeyEvent.VK_SPACE:
364: cbox.doClick();
365: e.consume();
366: break;
367:
368: default:
369: break;
370: }
371: }
372:
373: /*
374: * (non-Javadoc)
375: *
376: * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
377: */
378: public void keyReleased(KeyEvent e) {
379: }
380:
381: private void dropOperatorInstance() {
382: if (graphView != null) {
383: graphView.getGraphController().handleNodeAdded(opNode,
384: new java.awt.Point(50, 50));
385: }
386: }
387: }
388: }
|