| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.tasklist.filter; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.FontMetrics; |
| import java.awt.GridBagConstraints; |
| import java.awt.Insets; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollBar; |
| import javax.swing.UIManager; |
| import org.openide.util.NbBundle; |
| |
| /** |
| * Panel which is used to create a filter for the tasklist |
| * The GUI is based on the one in Mozilla's mail tool. |
| * Please read comment at the beginning of initA11y before editing |
| * this file using the form builder. |
| * |
| * @author Tor Norbye |
| */ |
| final class KeywordsPanel extends JPanel implements ActionListener, PropertyChangeListener { |
| |
| private static final long serialVersionUID = 1; |
| |
| // private FilteredTopComponent view; |
| private KeywordsFilter filter; |
| |
| // head of subpanels chain |
| private FilterSubpanel subpanel; |
| |
| /** |
| * Creates new form KeywordsPanel. |
| * |
| * @param view view with the given filter |
| * @param filter filter to be edited. Can be null and in that case |
| * all fields are disabled. |
| */ |
| public KeywordsPanel( KeywordsFilter filter ) { |
| this.filter = filter; |
| |
| initComponents(); |
| initA11y(); |
| |
| if( "Metal".equals( UIManager.getLookAndFeel().getID() ) ) //NOI18N |
| setOpaque( true ); |
| else |
| setOpaque( false ); |
| |
| // it's not generated by form editor |
| JPanel topAlign = new JPanel(); |
| topAlign.setLayout(new BorderLayout()); |
| topAlign.add(conditionsPanel, BorderLayout.NORTH); |
| conditionsScrollPane.setViewportView(topAlign); |
| // compute 80x10 chars space in scroll pane |
| FontMetrics fm = getFontMetrics(getFont()); |
| int width = fm.charWidth('n') * 80; // NOI18N |
| int height = fm.getHeight() * 10; |
| conditionsScrollPane.setPreferredSize(new java.awt.Dimension(width, height)); |
| |
| Color background = (Color)UIManager.get("Table.background"); //NOI18N |
| conditionsPanel.setBackground(background); |
| topAlign.setBackground(background); |
| |
| moreButton.addActionListener(this); |
| fewerButton.addActionListener(this); |
| matchAllRadio.addActionListener(this); |
| matchAnyRadio.addActionListener(this); |
| |
| showFilter(filter); |
| updateSensitivity(); |
| } |
| |
| /** |
| * Links to next filter customizer (or null). |
| */ |
| public void initSubpanel(FilterSubpanel next) { |
| assert subpanel == null; |
| subpanel = next; |
| } |
| |
| /** |
| * Show the given filter in the GUI |
| */ |
| private void showFilter(KeywordsFilter filter) { |
| if (filter != null) { |
| if (filter.matchAll()) { |
| matchAllRadio.setSelected(true); |
| } else { |
| matchAnyRadio.setSelected(true); |
| } |
| conditionsPanel.removeAll(); |
| List conditions = filter.getConditions(); |
| if (conditions.size() > 0) { |
| Iterator it = conditions.iterator(); |
| while (it.hasNext()) { |
| AppliedFilterCondition cond = (AppliedFilterCondition) it.next(); |
| addCondition(false, cond); |
| } |
| } else { |
| addCondition(false, null); |
| } |
| } else { |
| this.setEnabled(false); |
| matchAnyRadio.setEnabled(false); |
| matchAllRadio.setEnabled(false); |
| conditionsPanel.setEnabled(false); |
| moreButton.setEnabled(false); |
| fewerButton.setEnabled(false); |
| } |
| } |
| |
| /** |
| * This method is called from within the constructor to |
| * initialize the form. |
| * WARNING: Do NOT modify this code. The content of this method is |
| * always regenerated by the Form Editor. |
| */ |
| // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents |
| private void initComponents() { |
| |
| matchGroup.add(matchAllRadio); |
| org.openide.awt.Mnemonics.setLocalizedText(matchAllRadio, NbBundle.getMessage(KeywordsPanel.class, "MatchAll")); // NOI18N(); // NOI18N |
| matchAllRadio.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordsPanel.class, "HINT_MatchAll")); // NOI18N |
| matchAllRadio.setOpaque(false); |
| |
| matchGroup.add(matchAnyRadio); |
| matchAnyRadio.setSelected(true); |
| org.openide.awt.Mnemonics.setLocalizedText(matchAnyRadio, NbBundle.getMessage(KeywordsPanel.class, "MatchAny")); // NOI18N(); // NOI18N |
| matchAnyRadio.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordsPanel.class, "HINT_MatchAny")); // NOI18N |
| matchAnyRadio.setOpaque(false); |
| |
| conditionsScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); |
| conditionsScrollPane.setAlignmentX(0.0F); |
| conditionsScrollPane.setAlignmentY(0.0F); |
| conditionsScrollPane.setPreferredSize(new java.awt.Dimension(32767, 32767)); |
| |
| conditionsPanel.setLayout(new java.awt.GridBagLayout()); |
| conditionsScrollPane.setViewportView(conditionsPanel); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(fewerButton, NbBundle.getMessage(KeywordsPanel.class, "Fewer")); // NOI18N(); // NOI18N |
| fewerButton.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordsPanel.class, "HINT_Fewer")); // NOI18N |
| |
| org.openide.awt.Mnemonics.setLocalizedText(moreButton, NbBundle.getMessage(KeywordsPanel.class, "More")); // NOI18N(); // NOI18N |
| moreButton.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordsPanel.class, "HINT_More")); // NOI18N |
| |
| javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); |
| this.setLayout(layout); |
| layout.setHorizontalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addComponent(moreButton) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(fewerButton)) |
| .addGroup(layout.createSequentialGroup() |
| .addComponent(matchAllRadio) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(matchAnyRadio) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)) |
| .addComponent(conditionsScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 596, Short.MAX_VALUE)) |
| .addContainerGap()) |
| ); |
| layout.setVerticalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(matchAllRadio) |
| .addComponent(matchAnyRadio)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(conditionsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) |
| .addComponent(fewerButton) |
| .addComponent(moreButton)) |
| .addContainerGap()) |
| ); |
| |
| conditionsScrollPane.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getBundle(KeywordsPanel.class).getString("LBL_Conditions")); // NOI18N |
| conditionsScrollPane.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(KeywordsPanel.class).getString("HNT_Conditions")); // NOI18N |
| }// </editor-fold>//GEN-END:initComponents |
| |
| private void initA11y() { |
| // accessible |
| this.getAccessibleContext().setAccessibleDescription( |
| NbBundle.getMessage(KeywordsPanel.class, |
| "ACSD_Filter")); // NOI18N |
| conditionsPanel.getAccessibleContext().setAccessibleName( |
| NbBundle.getMessage(KeywordsPanel.class, |
| "ACSN_Conditions")); // NOI18N |
| conditionsPanel.getAccessibleContext().setAccessibleDescription( |
| NbBundle.getMessage(KeywordsPanel.class, |
| "ACSD_Conditions")); // NOI18N |
| } |
| |
| /** |
| * Adds a condition to the filter. |
| * |
| * @param revalidate true = invalidate() will be called |
| * @param condition a condition or null |
| */ |
| private ConditionPanel addCondition(boolean revalidate, AppliedFilterCondition condition) { |
| GridBagConstraints gridBagConstraints = new GridBagConstraints(); |
| gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER; |
| gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = GridBagConstraints.NORTH; |
| gridBagConstraints.insets = new Insets(6, 0, 0, 0); |
| gridBagConstraints.weightx = 1.0; |
| ConditionPanel panel = new ConditionPanel(filter, condition); |
| panel.addPropertyChangeListener(FilterCondition.PROP_VALUE_VALID, this); |
| panel.setBackground((Color)UIManager.get("Table.background")); //NOI18N |
| conditionsPanel.add(panel, gridBagConstraints); |
| if (revalidate) { |
| invalidate(); |
| getParent().validate(); |
| repaint(); |
| } |
| putClientProperty(FilterCondition.PROP_VALUE_VALID, Boolean.valueOf(isValueValid())); |
| return panel; |
| } |
| |
| /** @return aggregated PROP_VALUE_VALID value */ |
| public final boolean isValueValid() { |
| Component[] cps = conditionsPanel.getComponents(); |
| for (int i = 0; i < cps.length; i++) { |
| ConditionPanel condition = (ConditionPanel) cps[i]; |
| if (condition != null) { |
| if (condition.isValueValid() == false) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| // forward aggregated PROP_VALUE_VALID value |
| public void propertyChange(PropertyChangeEvent evt) { |
| putClientProperty(FilterCondition.PROP_VALUE_VALID, Boolean.valueOf(isValueValid())); |
| } |
| |
| /** |
| * Invoked when an action occurs. |
| */ |
| public void actionPerformed(ActionEvent evt) { |
| Object source = evt.getSource(); |
| if (source == moreButton) { |
| ConditionPanel comp = addCondition(true, null); |
| JScrollBar vsb = conditionsScrollPane.getVerticalScrollBar(); |
| vsb.setValue(vsb.getMaximum()); |
| comp.focusPropertyCombo(); |
| } else if (source == fewerButton) { |
| conditionsPanel.remove(conditionsPanel.getComponentCount() - 1); |
| invalidate(); |
| getParent().validate(); |
| repaint(); |
| } |
| updateSensitivity(); |
| putClientProperty(FilterCondition.PROP_VALUE_VALID, Boolean.valueOf(isValueValid())); |
| } |
| |
| /** |
| * Updates enabled/disabled state of the "fewer" button |
| */ |
| private void updateSensitivity() { |
| int n = conditionsPanel.getComponentCount(); |
| fewerButton.setEnabled(n > 0); |
| } |
| |
| /** |
| * Return a filter corresponding to what is in the GUI |
| * |
| * @return filter or null |
| */ |
| public KeywordsFilter getFilter() { |
| if (filter != null) { |
| // Get conditions |
| Component[] cps = conditionsPanel.getComponents(); |
| ArrayList<AppliedFilterCondition> conditions = new ArrayList<AppliedFilterCondition>(cps.length); |
| for (int i = 0; i < cps.length; i++) { |
| AppliedFilterCondition condition = ((ConditionPanel)cps[i]).getCondition(); |
| if (condition != null) { |
| conditions.add(condition); |
| } |
| } |
| filter.setConditions(conditions); |
| filter.setMatchAll(matchAllRadio.isSelected()); |
| if (subpanel != null) { |
| subpanel.updateFilter(filter); |
| } |
| } |
| return filter; |
| |
| } |
| |
| // Variables declaration - do not modify//GEN-BEGIN:variables |
| final javax.swing.JPanel conditionsPanel = new javax.swing.JPanel(); |
| final javax.swing.JScrollPane conditionsScrollPane = new javax.swing.JScrollPane(); |
| final javax.swing.JButton fewerButton = new javax.swing.JButton(); |
| final javax.swing.JRadioButton matchAllRadio = new javax.swing.JRadioButton(); |
| final javax.swing.JRadioButton matchAnyRadio = new javax.swing.JRadioButton(); |
| final javax.swing.ButtonGroup matchGroup = new javax.swing.ButtonGroup(); |
| final javax.swing.JButton moreButton = new javax.swing.JButton(); |
| final javax.swing.ButtonGroup subtaskGroup = new javax.swing.ButtonGroup(); |
| // End of variables declaration//GEN-END:variables |
| |
| } |