View Javadoc

1   /*
2    * $Id: PreferencesTablePanel.java,v 1.9 2007/07/04 19:42:50 edankert Exp $
3    *
4    * The contents of this file are subject to the Mozilla Public License 
5    * Version 1.1 (the "License"); you may not use this file except in 
6    * compliance with the License. You may obtain a copy of the License at 
7    * http://www.mozilla.org/MPL/ 
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis, 
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
11   * for the specific language governing rights and limitations under the License.
12   *
13   * The Original Code is XML Hammer code. (org.xmlhammer.*)
14   *
15   * The Initial Developer of the Original Code is Edwin Dankert. Portions created 
16   * by the Initial Developer are Copyright (C) 2005 - 2006 the Initial Developer. 
17   * All Rights Reserved.
18   *
19   * Contributor(s): Edwin Dankert <edankert@gmail.com>
20   */
21  
22  package org.xmlhammer.gui.preferences;
23  
24  import java.awt.BorderLayout;
25  import java.awt.Color;
26  import java.awt.Component;
27  import java.awt.Dimension;
28  import java.awt.FlowLayout;
29  import java.awt.Font;
30  import java.awt.event.ActionEvent;
31  import java.awt.event.ActionListener;
32  import java.awt.event.FocusAdapter;
33  import java.awt.event.FocusEvent;
34  
35  import javax.swing.DefaultCellEditor;
36  import javax.swing.JButton;
37  import javax.swing.JComboBox;
38  import javax.swing.JFrame;
39  import javax.swing.JOptionPane;
40  import javax.swing.JPanel;
41  import javax.swing.JScrollPane;
42  import javax.swing.JTable;
43  import javax.swing.JTextField;
44  import javax.swing.ListSelectionModel;
45  import javax.swing.border.EmptyBorder;
46  import javax.swing.event.TableModelEvent;
47  import javax.swing.event.TableModelListener;
48  import javax.swing.table.DefaultTableCellRenderer;
49  import javax.swing.table.DefaultTableModel;
50  
51  import org.bounce.ThreeStateCheckBox;
52  
53  /***
54   * Generic Preferences Panel.
55   * 
56   * @version $Revision: 1.9 $, $Date: 2007/07/04 19:42:50 $
57   * @author Edwin Dankert <edankert@gmail.com>
58   */
59  
60  public abstract class PreferencesTablePanel extends PreferencesPanel {
61  	private static final long serialVersionUID = 6877164067547749433L;
62      private static final String[] BOOLEAN_VALUES = {Boolean.toString(true), Boolean.toString(false)};
63      
64      private JFrame parent = null;
65      private JTable table = null;
66      private ThreeStateCheckBox ativateAllButton = null;
67      private JButton addButton = null;
68      private JButton deleteButton = null;
69      protected DefaultTableModel model = null;
70  
71  	/***
72  	 * Constructs a Preferences panel with a table.
73  	 */
74  	public PreferencesTablePanel( JFrame parent, String name, String helpID) {
75  		this( parent, name, helpID, false);
76  	}
77  	
78      public PreferencesTablePanel( JFrame parent, String name, String helpID, boolean project) {
79  		super(name, helpID, project);
80  
81          this.parent = parent;
82  
83          JPanel featureListPanel = new JPanel( new BorderLayout());
84          
85          table = new JTable(getModel());
86          table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
87          table.setFont(table.getFont().deriveFont((float)11));
88          table.getModel().addTableModelListener(new TableModelListener() {
89              public void tableChanged(TableModelEvent event) {
90                  updateSelectAllButton();
91                  table.repaint();
92             }
93          });
94  
95          JTextField field = new JTextField();
96          field.addFocusListener( new FocusAdapter() {
97              public void focusLost(FocusEvent arg0) {
98                  if (table.isEditing()) {
99                      table.getCellEditor().stopCellEditing();
100                 }
101             }
102         });
103 
104         field.setBorder(new EmptyBorder(0, 1, 0, 1));
105         field.setFont(field.getFont().deriveFont((float)11));
106         table.setDefaultEditor(String.class, new DefaultCellEditor(field));
107         table.setDefaultRenderer(String.class, new ActiveTableCellRenderer());
108         
109         JComboBox combo = new JComboBox(BOOLEAN_VALUES);
110         combo.addFocusListener( new FocusAdapter() {
111             public void focusLost(FocusEvent arg0) {
112                 if (table.isEditing()) {
113                     table.getCellEditor().stopCellEditing();
114                 }
115             }
116         });
117 
118         combo.setBorder(new EmptyBorder(0, 1, 0, 1));
119         combo.setFont(combo.getFont().deriveFont(Font.PLAIN, 11));
120         table.setDefaultEditor(Object.class, new DefaultCellEditor(combo));
121         table.setDefaultRenderer(Object.class, new ActiveTableCellRenderer());
122         
123         int[] width = getColumnWidths();
124         for ( int i = 0; i < width.length; i++) {
125             table.getColumnModel().getColumn(i).setMaxWidth(width[i]);
126         }
127         
128         JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
129         buttonPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
130     
131         addButton = new JButton("Add");
132         addButton.addActionListener(new ActionListener() {
133             public void actionPerformed(ActionEvent e) {
134                 addButtonPressed();
135             }
136         });
137         addButton.setMnemonic('A');
138         buttonPanel.add(addButton);
139     
140         deleteButton = new JButton("Delete");
141         deleteButton.addActionListener( new ActionListener() {
142             public void actionPerformed( ActionEvent e) {
143                 deleteButtonPressed();
144             }
145         });
146         deleteButton.setMnemonic('t');
147         buttonPanel.add(deleteButton);
148         
149         JPanel southPanel = new JPanel(new BorderLayout());
150         southPanel.add(buttonPanel, BorderLayout.EAST);
151 
152         JPanel selectPanel = new JPanel(new FlowLayout()); 
153         ativateAllButton = new ThreeStateCheckBox("Activate All");
154         ativateAllButton.addActionListener(new ActionListener() {
155             public void actionPerformed(ActionEvent e) {
156                 boolean selected = ativateAllButton.isSelected();
157                 
158                 for (int i = 0; i < getModel().getRowCount(); i++) {
159                     getModel().setValueAt(selected, i, 0);
160                 }
161             }
162         });
163         ativateAllButton.setMnemonic('A');
164         selectPanel.add(ativateAllButton);
165         updateSelectAllButton();
166         southPanel.add(selectPanel, BorderLayout.WEST);
167 
168         JScrollPane scroller = new JScrollPane(table);
169         scroller.getViewport().setBackground(Color.white);
170         scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
171         
172         scroller.setPreferredSize(new Dimension(100, 100));
173         featureListPanel.add(scroller, BorderLayout.CENTER);
174         featureListPanel.add(southPanel, BorderLayout.SOUTH);
175     
176         this.setCenterPane(featureListPanel);
177     }
178     
179     protected abstract DefaultTableModel getModel();
180 	
181     public void setEnabled( boolean enabled) {
182         table.setEnabled(enabled);
183         addButton.setEnabled(enabled);
184         deleteButton.setEnabled(enabled);
185         
186         if (ativateAllButton != null) {
187             ativateAllButton.setEnabled(enabled);
188 //            deselectAllButton.setEnabled(enabled);
189         }
190     }
191     
192     private void updateSelectAllButton() {
193         boolean active = false;
194         boolean inactive = false;
195         
196         for (int i = 0; i < table.getModel().getRowCount(); i++) {
197             Object value = table.getModel().getValueAt(i, 0);
198             if (value instanceof Boolean) {
199                 if ((Boolean)value) {
200                     active = true;
201                 } else {
202                     inactive = true;
203                 }
204             }
205         }
206         
207         if (ativateAllButton != null) {
208             if (active && inactive) {
209                 ativateAllButton.setSelected(ThreeStateCheckBox.DONT_CARE);
210             } else if (active) {
211                 ativateAllButton.setSelected(ThreeStateCheckBox.SELECTED);
212             } else if (inactive) {
213                 ativateAllButton.setSelected(ThreeStateCheckBox.NOT_SELECTED);
214             }
215         }
216     }
217     
218     protected JTable getTable() {
219         return table;
220     }
221     
222     protected abstract int[] getColumnWidths();
223     
224     protected abstract Object[] getDefaultRowContent();
225 
226     protected void addButtonPressed() {
227         getModel().addRow(getDefaultRowContent());
228         getTable().scrollRectToVisible(getTable().getCellRect(getModel().getRowCount()-1, 1, false));
229     }
230     
231     protected JFrame getFrame() {
232         return parent;
233     }
234 
235     protected void deleteButtonPressed() {
236         int[] indices = table.getSelectedRows();
237 
238         for(int i = indices.length-1; i >= 0; i--) {              
239             int result = -1;
240 
241             if(indices.length > 1) {
242                 result = JOptionPane.showOptionDialog(parent, "Are you sure you want to delete:\n"+getName(indices[i]), "Please Confirm", JOptionPane.YES_NO_CANCEL_OPTION,
243                     JOptionPane.QUESTION_MESSAGE, null, new String[] { "Yes", "No", "All"}, "Yes");
244             } else {
245                 result = JOptionPane.showConfirmDialog(parent, "Are you sure you want to delete:\n"+getName(indices[i]), "Please Confirm", JOptionPane.YES_NO_OPTION);
246             }
247                                 
248             if(result == 2 && indices.length > 1) { // Remove ALL
249                 for (int j = i; j >= 0; j--) { 
250                     getModel().removeRow(indices[j]);
251                 }
252                 
253                 return;
254             } else if(result == JOptionPane.YES_OPTION) {
255                 getModel().removeRow(indices[i]);
256             }
257         }
258     }
259     
260     /***
261      * @param row the table row.
262      * @return the name for the row specified.
263      */
264     protected abstract String getName(int row);
265     
266     private class ActiveTableCellRenderer extends DefaultTableCellRenderer {
267         private static final long serialVersionUID = 6609794766790303814L;
268 
269         @Override
270         public Component getTableCellRendererComponent(JTable table, Object obj, boolean selected, boolean focus, int row, int column) {
271             Component comp = super.getTableCellRendererComponent(table, obj, selected, focus, row, column);
272             Object activated = table.getModel().getValueAt(row, 0);
273             
274             if (activated instanceof Boolean) {
275                 comp.setEnabled((Boolean)activated);
276             } else {
277                 comp.setEnabled(true);
278             }
279             
280             return comp;
281         }
282     }
283 }