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.tasklist.filter;
042:
043: import java.awt.Component;
044: import java.awt.GridBagConstraints;
045:
046: import java.awt.event.ActionEvent;
047: import java.awt.event.ActionListener;
048: import java.beans.PropertyChangeListener;
049: import java.beans.PropertyChangeEvent;
050: import javax.swing.*;
051:
052: import org.openide.util.NbBundle;
053: import javax.swing.text.JTextComponent;
054:
055: /**
056: * GUI component for a single condition within the Filter Panel
057: *
058: * @author Tor Norbye
059: * @author tl
060: */
061: final class ConditionPanel extends JPanel implements ActionListener,
062: PropertyChangeListener {
063:
064: private static final long serialVersionUID = 1;
065:
066: private KeywordsFilter filter;
067: private JComponent valueField;
068:
069: /**
070: * Creates new form ConditionPanel
071: *
072: * @param filter filter to be used
073: * @param cond condition to be shown or null
074: */
075: public ConditionPanel(KeywordsFilter filter,
076: AppliedFilterCondition cond) {
077: this .filter = filter;
078:
079: initComponents();
080: initA11y();
081:
082: valueField = emptyPanel;
083:
084: // fill ComboBox with properties
085: TaskProperty[] props = filter.getProperties();
086: int selectedIndex = -1;
087:
088: DefaultComboBoxModel m = new DefaultComboBoxModel();
089: for (int i = 0; i < props.length; i++) {
090: AppliedFilterCondition[] c = filter
091: .createConditions(props[i]);
092: if (c.length != 0) {
093: m.addElement(props[i]);
094: if (cond == null)
095: cond = c[0];
096: }
097: if (props[i].getName().equals(cond.getProperty().getName()))
098: selectedIndex = i;
099: }
100: propertyCombo.setModel(m);
101: propertyCombo.addActionListener(this );
102: propertyCombo.setSelectedIndex(selectedIndex);
103: propertyCombo
104: .setRenderer(new ConditionPanel.PropertyCellRenderer());
105:
106: // construct the rest of items for the current condition
107: AppliedFilterCondition[] conditions = filter
108: .createConditions(cond.getProperty());
109: m = new DefaultComboBoxModel();
110: for (int i = 0; i < conditions.length; i++) {
111: if (conditions[i].sameType(cond)) {
112: m.addElement(cond);
113: } else {
114: m.addElement(conditions[i]);
115: }
116: }
117: relationCombo.setModel(m);
118: relationCombo.addActionListener(this );
119: relationCombo.setSelectedItem(cond);
120: relationCombo
121: .setRenderer(new ConditionPanel.ConditionCellRenderer());
122:
123: setValueComponent(cond.getCondition().createConstantComponent());
124: }
125:
126: public void actionPerformed(ActionEvent evt) {
127: if (evt.getSource() == propertyCombo) {
128: AppliedFilterCondition[] c = filter
129: .createConditions((TaskProperty) propertyCombo
130: .getSelectedItem());
131:
132: relationCombo.setModel(new DefaultComboBoxModel(c));
133: if (c.length != 0) {
134: relationCombo.setSelectedIndex(0);
135: AppliedFilterCondition cond = (AppliedFilterCondition) relationCombo
136: .getSelectedItem();
137: setValueComponent(cond.getCondition()
138: .createConstantComponent());
139: } else {
140: setValueComponent(null);
141: }
142: } else if (evt.getSource() == relationCombo) {
143: AppliedFilterCondition cond = (AppliedFilterCondition) relationCombo
144: .getSelectedItem();
145: setValueComponent(cond.getCondition()
146: .createConstantComponent());
147: }
148: }
149:
150: /**
151: * Return a filter condition corresponding to what is in the GUI
152: *
153: * @return choosed filter condition
154: */
155: public AppliedFilterCondition getCondition() {
156: AppliedFilterCondition cond = (AppliedFilterCondition) relationCombo
157: .getSelectedItem();
158: if (valueField != emptyPanel)
159: cond.getCondition().getConstantFrom(valueField);
160: return cond;
161: }
162:
163: private void initA11y() {
164: propertyCombo.getAccessibleContext().setAccessibleName(
165: NbBundle.getMessage(ConditionPanel.class,
166: "ACSN_Property")); // NOI18N
167: propertyCombo.getAccessibleContext().setAccessibleDescription(
168: NbBundle.getMessage(ConditionPanel.class,
169: "ACSD_Property")); // NOI18N
170: relationCombo.getAccessibleContext().setAccessibleName(
171: NbBundle.getMessage(ConditionPanel.class,
172: "ACSN_Relation")); // NOI18N
173: relationCombo.getAccessibleContext().setAccessibleDescription(
174: NbBundle.getMessage(ConditionPanel.class,
175: "ACSD_Relation")); // NOI18N
176: }
177:
178: /**
179: * Changes component with a constant.
180: *
181: * @param cmp new component or null if it should be removed
182: */
183: private void setValueComponent(JComponent cmp) {
184: if (valueField == emptyPanel && cmp == null
185: || valueField == cmp)
186: return;
187:
188: remove(valueField);
189:
190: if (cmp == null)
191: valueField = emptyPanel;
192: else {
193: if ((cmp instanceof JTextComponent)
194: && (valueField instanceof JTextComponent)
195: && ((JTextComponent) cmp).getText().length() == 0)
196: ((JTextComponent) cmp)
197: .setText(((JTextComponent) valueField)
198: .getText());
199: valueField = cmp;
200:
201: // supply with default values if no specific one defined
202: if (cmp.getAccessibleContext().getAccessibleName() == null) {
203: cmp.getAccessibleContext().setAccessibleName(
204: NbBundle.getMessage(ConditionPanel.class,
205: "ACSN_Value")); // NOI18N
206: }
207:
208: if (cmp.getAccessibleContext().getAccessibleDescription() == null) {
209: cmp.getAccessibleContext().setAccessibleDescription(
210: NbBundle.getMessage(ConditionPanel.class,
211: "ACSD_Value")); // NOI18N
212: }
213:
214: cmp.addPropertyChangeListener(
215: FilterCondition.PROP_VALUE_VALID, this );
216: }
217:
218: GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
219: gridBagConstraints.gridx = 2;
220: gridBagConstraints.gridy = 0;
221: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
222: gridBagConstraints.weightx = 1.0;
223: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 11);
224: add(valueField, gridBagConstraints);
225: revalidate();
226: repaint();
227: }
228:
229: public void focusPropertyCombo() {
230: propertyCombo.requestFocusInWindow();
231: }
232:
233: /**
234: * Cell renderer for FilterCondition
235: */
236: private static class ConditionCellRenderer extends
237: DefaultListCellRenderer {
238:
239: private static final long serialVersionUID = 1;
240:
241: public ConditionCellRenderer() {
242: }
243:
244: public Component getListCellRendererComponent(JList list,
245: Object value, int index, boolean isSelected,
246: boolean cellHasFocus) {
247: super .getListCellRendererComponent(list, value, index,
248: isSelected, cellHasFocus);
249: AppliedFilterCondition c = (AppliedFilterCondition) value;
250: if (c != null)
251: setText(c.getCondition().getDisplayName());
252: return this ;
253: }
254: }
255:
256: /**
257: * Cell renderer for Properties
258: */
259: private static class PropertyCellRenderer extends
260: DefaultListCellRenderer {
261:
262: private static final long serialVersionUID = 1;
263:
264: public PropertyCellRenderer() {
265: }
266:
267: public Component getListCellRendererComponent(JList list,
268: Object value, int index, boolean isSelected,
269: boolean cellHasFocus) {
270: super .getListCellRendererComponent(list, value, index,
271: isSelected, cellHasFocus);
272: TaskProperty prop = (TaskProperty) value;
273: if (prop != null)
274: setText(prop.getName());
275: return this ;
276: }
277: }
278:
279: // forward PROP_VALUE_VALID event
280: public void propertyChange(PropertyChangeEvent evt) {
281: putClientProperty(FilterCondition.PROP_VALUE_VALID, Boolean
282: .valueOf(isValueValid()));
283: }
284:
285: public boolean isValueValid() {
286: AppliedFilterCondition cond = (AppliedFilterCondition) relationCombo
287: .getSelectedItem();
288: return valueField != emptyPanel
289: && cond.getCondition().isValueValid(valueField);
290: }
291:
292: /**
293: * This method is called from within the constructor to
294: * initialize the form.
295: * WARNING: Do NOT modify this code. The content of this method is
296: * always regenerated by the Form Editor.
297: */
298: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
299: private void initComponents() {
300: java.awt.GridBagConstraints gridBagConstraints;
301:
302: setLayout(new java.awt.GridBagLayout());
303:
304: setFocusable(false);
305: gridBagConstraints = new java.awt.GridBagConstraints();
306: gridBagConstraints.gridx = 0;
307: gridBagConstraints.gridy = 0;
308: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
309: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
310: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
311: add(propertyCombo, gridBagConstraints);
312:
313: gridBagConstraints = new java.awt.GridBagConstraints();
314: gridBagConstraints.gridx = 1;
315: gridBagConstraints.gridy = 0;
316: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
317: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
318: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12);
319: add(relationCombo, gridBagConstraints);
320:
321: emptyPanel.setOpaque(false);
322: gridBagConstraints = new java.awt.GridBagConstraints();
323: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
324: gridBagConstraints.weightx = 1.0;
325: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12);
326: add(emptyPanel, gridBagConstraints);
327:
328: }// </editor-fold>//GEN-END:initComponents
329:
330: // Variables declaration - do not modify//GEN-BEGIN:variables
331: final javax.swing.JPanel emptyPanel = new javax.swing.JPanel();
332: final javax.swing.JComboBox propertyCombo = new javax.swing.JComboBox();
333: final javax.swing.JComboBox relationCombo = new javax.swing.JComboBox();
334: // End of variables declaration//GEN-END:variables
335: }
|