1 /***
2 * FilterDialog.java
3 *
4 * Project: Dependency Tool
5 *
6 * WHEN WHO WHAT
7 * 06.06.2003 pko initial public release
8 * 15.02.2002 ctr creation
9 *
10 * Copyright 2003 ELCA Informatique SA
11 * Av. de la Harpe 22-24, 1000 Lausanne 13, Switzerland
12 * www.elca.ch
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public License
16 * as published by the Free Software Foundation; either version 2.1 of
17 * the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 * USA
28 */
29
30 package ch.elca.dependency.gui;
31
32 import java.awt.*;
33 import java.awt.event.*;
34 import java.io.*;
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.ListIterator;
38 import javax.swing.*;
39 import javax.swing.border.Border;
40 import javax.swing.border.TitledBorder;
41 import javax.swing.event.ListSelectionEvent;
42 import javax.swing.event.ListSelectionListener;
43
44 import org.apache.log4j.Logger;
45
46 import ch.elca.dependency.core.DependencyModel;
47 import ch.elca.dependency.core.Filter;
48 import ch.elca.dependency.core.FilterApplicator;
49 import ch.elca.dependency.core.RawModel;
50 import ch.elca.dependency.exception.FilterListIOException;
51
52 import info.clearthought.layout.TableLayout;
53
54 /***
55 * Dialog for creating, modifying and deleting filters. It is possible
56 * to specify and apply positive and negative filters. Positive or
57 * incude filters specify which artifacts are included in the views of
58 * the Dependency Tool. Negative or exclude filters specify the ones
59 * which are not displayed in the views. It is possible to specify
60 * either a positive or a negative. A positive and a negative or at
61 * least it is possible to specify no filter at all.
62 *
63 * @author Christoph Trutmann
64 * @version 1.0-beta
65 */
66 public class FilterDialog extends JDialog {
67
68 /***
69 * Log4j category to invoke the log statements.
70 */
71 private static final Logger LOG = Logger.getLogger(FilterDialog.class);
72
73 /***
74 * Table models for the include filter list and the exclude filter list
75 */
76 private FilterListTableModel m_includeModel, m_excludeModel;
77
78 /***
79 * Dialog for creating new filters or modifying existing ones.
80 */
81 private FilterManipulationDialog m_manipDialog;
82
83 /***
84 * List with the filters loaded at the startup.
85 * From this list the tables are filled and in case of a canceling of the
86 * <code>FilterDialog</code> this list will the backup.
87 */
88 private ArrayList m_initialFilters = new ArrayList();
89
90 /***
91 * This flag specifies whether the 'filters' file is read the first time
92 * during this runtime.
93 */
94 private boolean m_initFilterList = true;
95
96 /***
97 * Apply Filters upon the DependencyModels
98 */
99 private FilterApplicator m_filterApplicator = new FilterApplicator();
100
101 /***
102 * The Filter filename.
103 */
104 private final static String FILTER_FILE_NAME = "filters";
105
106 /***
107 * Constructor - Stet the owner and initialize the controller for applying
108 * the filter.
109 *
110 * @param owner MainFrame frame which is the owner of this dialog.
111 */
112 public FilterDialog(Frame owner) {
113 super(owner, true); // model dialog with the owner
114 init();
115 m_manipDialog = new FilterManipulationDialog(this);
116 }
117
118 /***
119 * Initializes the gui components.
120 */
121 public void init() {
122
123 // add the window closing event
124 this.addWindowListener(new WindowAdapter() {
125 public void windowClosing(WindowEvent e) {
126 handleCancel();
127 }
128 });
129
130 double border = 10;
131 double tableHeight = 150;
132 double fill = TableLayout.FILL;
133 double pref = TableLayout.PREFERRED;
134 double size[][] =
135 {{border, fill, fill, fill, border}, // Columns
136 {border, tableHeight, border, tableHeight, border, fill, border}}; // Rows
137
138 this.getContentPane().setLayout(new TableLayout(size));
139
140 // create the edged border type for the whole dialog
141 Border etched = BorderFactory.createEtchedBorder();
142
143 // create the part for the include filter list
144 m_includeModel = new FilterListTableModel(true);
145 JTable includeTable = new JTable(m_includeModel);
146
147 JPanel includePanel
148 = createFilterPanel(etched, "Include Filter", includeTable);
149
150 // add the include filter list to the content pane
151 this.getContentPane().add(includePanel, "1, 1, 3, 1");
152
153 // create the part for the exclude filter list
154 m_excludeModel = new FilterListTableModel(false);
155 JTable excludeTable = new JTable(m_excludeModel);
156
157 JPanel excludePanel
158 = createFilterPanel(etched, "Exclude Filter", excludeTable);
159
160 // add the include filter list to the content pane
161 this.getContentPane().add(excludePanel, "1, 3, 3, 3");
162
163 // ok button
164 JButton okButton = new JButton("OK");
165 okButton.setPreferredSize(new Dimension(100,25));
166 okButton.addActionListener(new ActionListener(){
167 public void actionPerformed(ActionEvent e){
168 handleOK();
169 }
170 });
171 this.getContentPane().add(okButton, "2, 5, C, C");
172
173 // cancel button
174 JButton cancelButton = new JButton("Cancel");
175 cancelButton.setPreferredSize(new Dimension(100,25));
176 cancelButton.addActionListener( new ActionListener(){
177 public void actionPerformed(ActionEvent e){
178 handleCancel();
179 }
180 });
181 this.getContentPane().add(cancelButton, "3, 5, C, C");
182
183 // do the frame settings
184 this.setTitle("Filter Packages");
185 this.setSize(new Dimension(496, 404));
186 this.setLocation(400, 200);
187 this.setVisible(false);
188 this.setResizable(false);
189
190 try {
191 readFilterList();
192 // do nothing --> filters will be saved in a new file
193 } catch(FilterListIOException fle) {
194 LOG.info("Cannot read the filter list file.");
195 }
196 }
197
198
199 /***
200 * Helper method for creating a panel with the table for the filter entries
201 * and the appropriate buttons for the manipulation.
202 */
203 private JPanel createFilterPanel(Border border, String title, JTable table){
204 // only one row can be selected at the same time
205 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
206
207 // set the columnwiths
208 table.getColumnModel().getColumn(0).setMaxWidth(25);
209 table.getColumnModel().getColumn(0).setResizable(false);
210 table.getColumnModel().getColumn(1).setMinWidth(180);
211 table.getColumnModel().getColumn(2).setMinWidth(250);
212
213 // make columns not changable
214 table.getTableHeader().setReorderingAllowed(false);
215
216 // make rows selectable and add the appropriate listener
217 ListSelectionModel rowSM = table.getSelectionModel();
218 MyListSelectionListener selectionListner
219 = new MyListSelectionListener(table);
220 rowSM.addListSelectionListener(selectionListner);
221
222 // set the resizing behavior of the columns
223 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
224 TitledBorder titBorder
225 = BorderFactory.createTitledBorder(border, title);
226 titBorder.setTitleJustification(TitledBorder.LEFT);
227 titBorder.setTitlePosition(TitledBorder.DEFAULT_POSITION);
228
229 // make a scroll pane with the JTable inside
230 JScrollPane scrollpane = new JScrollPane(table);
231 scrollpane.setHorizontalScrollBarPolicy(
232 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
233 scrollpane.setPreferredSize(table.getPreferredSize());
234 scrollpane.setMinimumSize(table.getMinimumSize());
235
236 // panel with include table
237 JPanel panel = new JPanel();
238 BorderLayout panelLayout = new BorderLayout();
239 panel.setLayout(panelLayout);
240 panel.setBorder(titBorder);
241 panel.add(scrollpane, BorderLayout.CENTER);
242 panel.setPreferredSize(table.getPreferredSize());
243 panel.setMinimumSize(table.getMinimumSize());
244 JPanel buttonPanel = new JPanel();
245 JLabel spacer = new JLabel("");
246 spacer.setPreferredSize(new Dimension(100,25));
247
248 // special action listener for applying the commands to the right table
249 MyActionListener myListener = new MyActionListener(table);
250
251 // button for cretaing a new filter
252 JButton newButton = new JButton("New...");
253 newButton.setPreferredSize(new Dimension(100,25));
254 newButton.setActionCommand("new");
255 newButton.addActionListener(myListener);
256
257 // button for modifying a existing filter
258 JButton modButton = new JButton("Modify...");
259 modButton.setPreferredSize(new Dimension(100,25));
260 modButton.setActionCommand("mod");
261 modButton.addActionListener(myListener);
262
263 // button for deleting a existing filter
264 JButton delButton = new JButton("Delete");
265 delButton.setPreferredSize(new Dimension(100,25));
266 delButton.setActionCommand("del");
267 delButton.addActionListener(myListener);
268
269 // add buttons to the appropriate panel
270 buttonPanel.add(spacer);
271 buttonPanel.add(newButton);
272 buttonPanel.add(modButton);
273 buttonPanel.add(delButton);
274
275 // add the buttons panel to the panel with the border
276 panel.add(buttonPanel, BorderLayout.SOUTH);
277 return panel;
278 }
279
280 /***
281 * Helper method for handling the action events of the new button.
282 *
283 * @param table Table to apply the command.
284 */
285 private void handleNew(JTable table){
286 FilterListTableModel model = (FilterListTableModel)table.getModel();
287
288 m_manipDialog.clearFields();
289
290 // set the title
291 if (model.isInclude()) {
292 m_manipDialog.setTitle("Create new include filter...");
293 }
294 else {
295 m_manipDialog.setTitle("Create new exclude filter...");
296 }
297
298 m_manipDialog.setVisible(true);
299
300 // --- return from the manipulation dialog
301 // get the input
302 String filterName = m_manipDialog.getFilterName().trim();
303 String filterValue = m_manipDialog.getFilterValue().trim();
304
305 if ( ! filterName.equals("") ) {
306 model.addFilterEntry(filterName, filterValue);
307 }
308 }
309
310
311 /***
312 * Helper method for handling the action events of the modify button.
313 *
314 * @param table Table to apply the command.
315 */
316 private void handleModify(JTable table){
317 // get the selected row of this table
318 int selectedRow = table.getSelectedRow();
319
320 // if no row is selected
321 if (selectedRow == -1) {
322 return;
323 }
324
325 // get the table model
326 FilterListTableModel model = (FilterListTableModel)table.getModel();
327
328 // get the existing data
329 String filterName = (String)model.getValueAt(selectedRow, 1);
330 String filterValue = (String)model.getValueAt(selectedRow, 2);
331
332 // fill in the field with the changing data
333 m_manipDialog.setFilterName(filterName);
334 m_manipDialog.setFilterValue(filterValue);
335
336 // set the title
337 if ( model.isInclude() ) {
338 m_manipDialog.setTitle("Modify include filter...");
339 }
340 else {
341 m_manipDialog.setTitle("Modify exclude filter...");
342 }
343 m_manipDialog.setVisible(true);
344
345 // --- return from the manipulation dialog
346 // get the input
347 filterName = m_manipDialog.getFilterName().trim();
348 filterValue = m_manipDialog.getFilterValue().trim();
349
350 // update the table model
351 if ( ! filterName.equals("") ) {
352 model.setValueAt(filterName, selectedRow, 1);
353 model.setValueAt(filterValue, selectedRow, 2);
354 }
355 }
356
357
358 /***
359 * Helper method for handling the action events of the delete button.
360 *
361 * @param table Table to apply the command.
362 */
363 private void handleDelete(JTable table){
364 // get the selected row
365 int selectedRow = table.getSelectedRow();
366 if ( selectedRow != -1 ) {
367 ((FilterListTableModel)table.getModel())
368 .removeFilterEntry(selectedRow);
369 }
370 }
371
372
373 /***
374 * Helper method for handling the action events of the ok button.
375 */
376 private void handleOK(){
377 this.setVisible(false);
378
379 // save the table entries into a file
380 try {
381 saveFilterList();
382
383 DependencyModel dependencyModel = DependencyModel.getDependencyModel();
384 RawModel rawModel = dependencyModel.getRawModel();
385 m_filterApplicator.apply(m_initialFilters, rawModel, dependencyModel);
386
387 } catch(Exception e){
388 JOptionPane.showMessageDialog(this, e.getMessage(),
389 "DependencyTool", JOptionPane.ERROR_MESSAGE);
390 }
391 }
392
393
394 /***
395 * Helper method for handling the action events of the cancel button.
396 */
397 private void handleCancel(){
398 this.setVisible(false);
399 // rollback all the changes
400 fillFilterList();
401 }
402
403
404 /***
405 * Saves the filter list in the file "filters".
406 */
407 private void saveFilterList() throws FilterListIOException {
408
409 try {
410 // delete the existing file for not having to much entries
411 File file = new File(FILTER_FILE_NAME);
412 file.delete();
413
414 // get the streams to the file to save
415 FileOutputStream outStream = new FileOutputStream(file);
416 ObjectOutputStream objOutStream = new ObjectOutputStream(outStream);
417
418 // write the include filters to the file
419 int incRows = m_includeModel.getRowCount();
420 int excRows = m_excludeModel.getRowCount();
421
422 objOutStream.writeInt(incRows + excRows);
423
424 // clear backup list
425 m_initialFilters.clear();
426
427 for ( int i=0 ; i<incRows ; i++ ) {
428 Filter tmp = m_includeModel.getFilterAt(i);
429 objOutStream.writeObject(tmp);
430 m_initialFilters.add(tmp);
431 }
432
433 // write the exclude filters to the file
434 for ( int i=0 ; i<excRows ; i++ ) {
435 Filter tmp = m_excludeModel.getFilterAt(i);
436 objOutStream.writeObject(tmp);
437 m_initialFilters.add(tmp);
438 }
439
440 // finish and close the writing
441 objOutStream.flush();
442 outStream.close();
443
444 } catch(Exception ex){
445 throw new FilterListIOException(ex);
446 }
447 }
448
449 /***
450 * Reads the filter list in the file "filters".
451 *
452 * @exception FilterListIOException If the filter list file cannot be
453 * read/write properly.
454 */
455 public void readFilterList() throws FilterListIOException {
456
457 try {
458 FileInputStream inStream = new FileInputStream("filters");
459 ObjectInputStream objInStream = new ObjectInputStream(inStream);
460
461 /*while ( inStream.available() > 0 ) {
462 m_initialFilters.add((Filter)objInStream.readObject());
463 }
464 inStream.close();
465 fillFilterList();*/
466
467 int numberOfObjects = objInStream.readInt();
468 for ( int i=0 ; i<numberOfObjects ; i++ ) {
469 Filter filterTmp = (Filter)objInStream.readObject();
470
471 // set all filters not marked at the beginning
472 if ( m_initFilterList ) {
473 filterTmp.setMarked(false);
474 }
475 m_initialFilters.add(filterTmp);
476 }
477 m_initFilterList = false; // marking the file read at least once
478 inStream.close();
479 fillFilterList();
480
481 } catch(Exception ex){
482 throw new FilterListIOException(ex);
483 }
484 }
485
486 /***
487 * Helper method for filling in the filters from the file or from the
488 * backup.
489 */
490 private void fillFilterList(){
491 ListIterator filterIter = m_initialFilters.listIterator();
492
493 m_includeModel.clear();
494 m_excludeModel.clear();
495
496 while (filterIter.hasNext()) {
497 Filter tmp = (Filter)filterIter.next();
498 if ( tmp.isInclude() ) {
499 m_includeModel.addFilter(tmp);
500 }
501 else {
502 m_excludeModel.addFilter(tmp);
503 }
504 }
505 }
506
507 /***
508 * ActionListener for distinguish the two tables and apply its
509 * corresponding commands.
510 */
511 class MyActionListener implements ActionListener {
512
513 /***
514 * Table which causes the <code>ActionEvent</code>.
515 */
516 private JTable m_tableToApply;
517
518 /***
519 * Constructor - Initializes the table on which the commands have to by
520 * applied.
521 *
522 * @param table JTable on which the commands have to by applied.
523 */
524 public MyActionListener(JTable table){
525 m_tableToApply = table;
526 }
527
528 /***
529 * Handles the action events generated by the buttons which depend on
530 * a specific table.
531 * The actions which depend not on a secific table are handled by the
532 * <code>actionPerformed</code> method of the class
533 * <code>FilterDialog</code>.
534 *
535 * @param event Action event generated by one of the buttons.
536 */
537 public void actionPerformed(ActionEvent event){
538 String comm = event.getActionCommand();
539
540 if ( comm.equals("new") ){
541 handleNew(m_tableToApply);
542 }
543 else if ( comm.equals("mod") ) {
544 handleModify(m_tableToApply);
545 }
546 else if ( comm.equals("del") ) {
547 handleDelete(m_tableToApply);
548 }
549 }
550 }
551
552 /***
553 * ListSelectionListener for distinguishing the two tables and act in the
554 * appropriate manner.
555 */
556 class MyListSelectionListener implements ListSelectionListener {
557
558 /***
559 * Table which causes the <code>ListSelectionEvent</code>.
560 */
561 private JTable m_tableToApply;
562
563 /***
564 * The actual selected row in this table
565 */
566 private int m_actualRow;
567
568 /***
569 * Costructor - Initialize the table to apply the commands.
570 */
571 public MyListSelectionListener(JTable table){
572 m_tableToApply = table;
573 }
574
575 /***
576 * Handles the list selection events generated by the appropriate table.
577 *
578 * @param e List selection event generated by one of the list.
579 */
580 public void valueChanged(ListSelectionEvent e) {
581 //Ignore extra messages.
582 if (e.getValueIsAdjusting()) {return;}
583
584 ListSelectionModel lsm = (ListSelectionModel)e.getSource();
585 if (lsm.isSelectionEmpty()) {
586 // no rows are selected
587 } else {
588 // this is the last selected row in the last selected table
589 m_actualRow = lsm.getMinSelectionIndex();
590 }
591 }
592 }
593 }
This page was automatically generated by Maven