1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw.color;
19
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Component;
23 import java.awt.Dimension;
24 import java.awt.FlowLayout;
25 import java.awt.Graphics;
26 import java.awt.GridLayout;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.awt.event.ItemEvent;
30 import java.awt.event.ItemListener;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeListener;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Vector;
39
40 import javax.swing.AbstractAction;
41 import javax.swing.Action;
42 import javax.swing.BorderFactory;
43 import javax.swing.Box;
44 import javax.swing.BoxLayout;
45 import javax.swing.DefaultCellEditor;
46 import javax.swing.DefaultComboBoxModel;
47 import javax.swing.Icon;
48 import javax.swing.JButton;
49 import javax.swing.JCheckBox;
50 import javax.swing.JColorChooser;
51 import javax.swing.JComboBox;
52 import javax.swing.JDialog;
53 import javax.swing.JLabel;
54 import javax.swing.JList;
55 import javax.swing.JPanel;
56 import javax.swing.JScrollPane;
57 import javax.swing.JTable;
58 import javax.swing.JTextField;
59 import javax.swing.ListCellRenderer;
60 import javax.swing.ListSelectionModel;
61 import javax.swing.WindowConstants;
62 import javax.swing.border.Border;
63 import javax.swing.event.ListSelectionEvent;
64 import javax.swing.event.ListSelectionListener;
65 import javax.swing.table.DefaultTableModel;
66 import javax.swing.table.TableCellRenderer;
67
68 import org.apache.log4j.chainsaw.ApplicationPreferenceModel;
69 import org.apache.log4j.chainsaw.ChainsawConstants;
70 import org.apache.log4j.chainsaw.ExpressionRuleContext;
71 import org.apache.log4j.chainsaw.filter.FilterModel;
72 import org.apache.log4j.chainsaw.helper.SwingHelper;
73 import org.apache.log4j.chainsaw.icons.ChainsawIcons;
74 import org.apache.log4j.rule.ColorRule;
75 import org.apache.log4j.rule.ExpressionRule;
76 import org.apache.log4j.rule.Rule;
77
78
79
80
81
82
83
84
85
86
87 public class ColorPanel extends JPanel
88 {
89 private static final String DEFAULT_STATUS = "<html>Double click a rule field to edit the rule</html>";
90 private final String currentRuleSet = "Default";
91
92 private RuleColorizer colorizer;
93 private JPanel rulesPanel;
94 private FilterModel filterModel;
95 private DefaultTableModel tableModel;
96 private JScrollPane tableScrollPane;
97 private JTable table;
98 private ActionListener closeListener;
99 private JLabel statusBar;
100 private Vector columns;
101 private final String noTab = "None";
102 private DefaultComboBoxModel logPanelColorizersModel;
103 private Map allLogPanelColorizers;
104 private RuleColorizer currentLogPanelColorizer;
105 private JTable searchTable;
106 private DefaultTableModel searchTableModel;
107 private Vector searchColumns;
108 private Vector searchDataVector;
109 private Vector searchDataVectorEntry;
110
111 private JTable alternatingColorTable;
112 private DefaultTableModel alternatingColorTableModel;
113 private Vector alternatingColorColumns;
114 private Vector alternatingColorDataVector;
115 private Vector alternatingColorDataVectorEntry;
116 private ApplicationPreferenceModel applicationPreferenceModel;
117 private JCheckBox bypassSearchColorsCheckBox;
118
119 public ColorPanel(final RuleColorizer currentLogPanelColorizer, final FilterModel filterModel,
120 final Map allLogPanelColorizers, final ApplicationPreferenceModel applicationPreferenceModel) {
121 super(new BorderLayout());
122
123 this.currentLogPanelColorizer = currentLogPanelColorizer;
124 this.colorizer = currentLogPanelColorizer;
125 this.filterModel = filterModel;
126 this.allLogPanelColorizers = allLogPanelColorizers;
127 this.applicationPreferenceModel = applicationPreferenceModel;
128
129 currentLogPanelColorizer.addPropertyChangeListener(
130 "colorrule",
131 new PropertyChangeListener() {
132 public void propertyChange(PropertyChangeEvent evt) {
133 updateColors();
134 }
135 });
136
137 tableModel = new DefaultTableModel();
138 table = new JTable(tableModel);
139 table.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT);
140
141 searchTableModel = new DefaultTableModel();
142 searchTable = new JTable(searchTableModel);
143 searchTable.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT);
144 searchTable.setPreferredScrollableViewportSize(new Dimension(30, 30));
145
146 alternatingColorTableModel = new DefaultTableModel();
147 alternatingColorTable = new JTable(alternatingColorTableModel);
148 alternatingColorTable.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT);
149 alternatingColorTable.setPreferredScrollableViewportSize(new Dimension(30, 30));
150
151 columns = new Vector();
152 columns.add("Expression");
153 columns.add("Background");
154 columns.add("Foreground");
155
156 searchColumns = new Vector();
157 searchColumns.add("Background");
158 searchColumns.add("Foreground");
159
160 alternatingColorColumns = new Vector();
161 alternatingColorColumns.add("Background");
162 alternatingColorColumns.add("Foreground");
163
164
165 searchDataVector = new Vector();
166 searchDataVectorEntry = new Vector();
167 searchDataVectorEntry.add(applicationPreferenceModel.getSearchBackgroundColor());
168 searchDataVectorEntry.add(applicationPreferenceModel.getSearchForegroundColor());
169 searchDataVector.add(searchDataVectorEntry);
170 searchTableModel.setDataVector(searchDataVector, searchColumns);
171
172 alternatingColorDataVector = new Vector();
173 alternatingColorDataVectorEntry = new Vector();
174 alternatingColorDataVectorEntry.add(applicationPreferenceModel.getAlternatingColorBackgroundColor());
175 alternatingColorDataVectorEntry.add(applicationPreferenceModel.getAlternatingColorForegroundColor());
176 alternatingColorDataVector.add(alternatingColorDataVectorEntry);
177 alternatingColorTableModel.setDataVector(alternatingColorDataVector, alternatingColorColumns);
178
179 table.setPreferredScrollableViewportSize(new Dimension(525, 200));
180 tableScrollPane = new JScrollPane(table);
181
182 Vector data = getColorizerVector();
183 tableModel.setDataVector(data, columns);
184
185 table.sizeColumnsToFit(0);
186 table.getColumnModel().getColumn(1).setPreferredWidth(80);
187 table.getColumnModel().getColumn(2).setPreferredWidth(80);
188 table.getColumnModel().getColumn(1).setMaxWidth(80);
189 table.getColumnModel().getColumn(2).setMaxWidth(80);
190
191 searchTable.sizeColumnsToFit(0);
192 searchTable.getColumnModel().getColumn(0).setPreferredWidth(80);
193 searchTable.getColumnModel().getColumn(1).setPreferredWidth(80);
194 searchTable.getColumnModel().getColumn(0).setMaxWidth(80);
195 searchTable.getColumnModel().getColumn(1).setMaxWidth(80);
196
197 SwingHelper.invokeOnEDT(new Runnable() {
198 public void run() {
199 configureSingleEntryColorTable(searchTable);
200 }
201 });
202
203 alternatingColorTable.sizeColumnsToFit(0);
204 alternatingColorTable.getColumnModel().getColumn(0).setPreferredWidth(80);
205 alternatingColorTable.getColumnModel().getColumn(1).setPreferredWidth(80);
206 alternatingColorTable.getColumnModel().getColumn(0).setMaxWidth(80);
207 alternatingColorTable.getColumnModel().getColumn(1).setMaxWidth(80);
208
209 SwingHelper.invokeOnEDT(new Runnable() {
210 public void run() {
211 configureSingleEntryColorTable(alternatingColorTable);
212 }
213 });
214
215 configureTable();
216
217 statusBar = new JLabel(DEFAULT_STATUS);
218
219 rulesPanel = buildRulesPanel();
220 rulesPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
221
222 JPanel rightPanel = new JPanel(new BorderLayout());
223
224 JPanel rightOuterPanel = new JPanel();
225 rightOuterPanel.setLayout(
226 new BoxLayout(rightOuterPanel, BoxLayout.X_AXIS));
227 rightOuterPanel.add(Box.createHorizontalStrut(10));
228
229 JPanel southPanel = new JPanel();
230 southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
231 southPanel.add(Box.createVerticalStrut(5));
232 southPanel.add(Box.createVerticalStrut(5));
233 JPanel searchAndAlternatingColorPanel = buildSearchAndAlternatingColorPanel();
234 JPanel bypassSearchColorsPanel = buildBypassSearchColorsPanel();
235 bypassSearchColorsCheckBox.setSelected(applicationPreferenceModel.isBypassSearchColors());
236
237 JPanel globalLabelPanel = new JPanel();
238 globalLabelPanel.setLayout(new BoxLayout(globalLabelPanel, BoxLayout.X_AXIS));
239 JLabel globalLabel = new JLabel("Global colors:");
240 globalLabelPanel.add(globalLabel);
241 globalLabelPanel.add(Box.createHorizontalGlue());
242 southPanel.add(globalLabelPanel);
243 southPanel.add(searchAndAlternatingColorPanel);
244 southPanel.add(bypassSearchColorsPanel);
245 southPanel.add(Box.createVerticalStrut(5));
246 JPanel closePanel = buildClosePanel();
247 southPanel.add(closePanel);
248
249 JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
250 statusPanel.add(statusBar);
251 southPanel.add(statusPanel);
252 rightPanel.add(rulesPanel, BorderLayout.CENTER);
253 rightPanel.add(southPanel, BorderLayout.SOUTH);
254 rightOuterPanel.add(rightPanel);
255
256 JPanel topPanel = new JPanel();
257 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
258
259 JLabel selectText = new JLabel("Apply a tab's colors");
260 topPanel.add(selectText);
261 topPanel.add(Box.createHorizontalStrut(5));
262
263 logPanelColorizersModel = new DefaultComboBoxModel();
264 final JComboBox loadPanelColorizersComboBox = new JComboBox(logPanelColorizersModel);
265 loadLogPanelColorizers();
266
267 topPanel.add(loadPanelColorizersComboBox);
268
269 topPanel.add(Box.createHorizontalStrut(5));
270 final Action copyRulesAction = new AbstractAction() {
271 public void actionPerformed(ActionEvent e)
272 {
273 tableModel.getDataVector().clear();
274 Object selectedItem = loadPanelColorizersComboBox.getSelectedItem();
275 if (selectedItem != null) {
276 RuleColorizer sourceColorizer = (RuleColorizer) allLogPanelColorizers.get(selectedItem.toString());
277 colorizer.setRules(sourceColorizer.getRules());
278 updateColors();
279 }
280 }
281 };
282
283 loadPanelColorizersComboBox.addActionListener(new ActionListener() {
284 public void actionPerformed(ActionEvent e) {
285 Object selectedItem = loadPanelColorizersComboBox.getSelectedItem();
286 if (selectedItem != null) {
287 String selectedColorizerName = selectedItem.toString();
288 copyRulesAction.setEnabled(!(noTab.equals(selectedColorizerName)));
289 }
290 }
291 });
292
293 copyRulesAction.putValue(Action.NAME, "Copy color rules");
294 copyRulesAction.setEnabled(!(noTab.equals(loadPanelColorizersComboBox.getSelectedItem())));
295
296 JButton copyRulesButton = new JButton(copyRulesAction);
297 topPanel.add(copyRulesButton);
298
299 add(topPanel, BorderLayout.NORTH);
300 add(rightOuterPanel, BorderLayout.CENTER);
301 if (table.getRowCount() > 0) {
302 table.getSelectionModel().setSelectionInterval(0, 0);
303 }
304 }
305
306 public void loadLogPanelColorizers() {
307 if (logPanelColorizersModel.getIndexOf(noTab) == -1) {
308 logPanelColorizersModel.addElement(noTab);
309 }
310 for (Iterator iter = allLogPanelColorizers.entrySet().iterator();iter.hasNext();) {
311 Map.Entry entry = (Map.Entry)iter.next();
312 if (!entry.getValue().equals(currentLogPanelColorizer) && (logPanelColorizersModel.getIndexOf(entry.getKey()) == -1)) {
313 logPanelColorizersModel.addElement(entry.getKey());
314 }
315 }
316
317 searchDataVectorEntry.set(0, applicationPreferenceModel.getSearchBackgroundColor());
318 searchDataVectorEntry.set(1, applicationPreferenceModel.getSearchForegroundColor());
319 alternatingColorDataVectorEntry.set(0, applicationPreferenceModel.getAlternatingColorBackgroundColor());
320 alternatingColorDataVectorEntry.set(1, applicationPreferenceModel.getAlternatingColorForegroundColor());
321 }
322
323 public JPanel buildBypassSearchColorsPanel() {
324 JPanel panel = new JPanel();
325 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
326
327 bypassSearchColorsCheckBox = new JCheckBox("Don't use a search color for matching rows");
328 panel.add(bypassSearchColorsCheckBox);
329 return panel;
330 }
331
332 public JPanel buildSearchAndAlternatingColorPanel() {
333 JPanel panel = new JPanel();
334 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
335
336 JLabel defineSearchColorsLabel = new JLabel("Find colors");
337
338 panel.add(defineSearchColorsLabel);
339
340 panel.add(Box.createHorizontalStrut(10));
341 JScrollPane searchPane = new JScrollPane(searchTable);
342 searchPane.setBorder(BorderFactory.createEmptyBorder());
343 panel.add(searchPane);
344
345 panel.add(Box.createHorizontalStrut(10));
346 JLabel defineAlternatingColorLabel = new JLabel("Alternating colors");
347
348 panel.add(defineAlternatingColorLabel);
349
350 panel.add(Box.createHorizontalStrut(10));
351 JScrollPane alternatingColorPane = new JScrollPane(alternatingColorTable);
352 alternatingColorPane.setBorder(BorderFactory.createEmptyBorder());
353
354 panel.add(alternatingColorPane);
355 panel.setBorder(BorderFactory.createEtchedBorder());
356 panel.add(Box.createHorizontalGlue());
357 return panel;
358 }
359
360 public void updateColors() {
361 tableModel.getDataVector().clear();
362 tableModel.getDataVector().addAll(getColorizerVector());
363 tableModel.fireTableDataChanged();
364 }
365
366 private Vector getColorizerVector() {
367 Vector data = new Vector();
368 Map map = colorizer.getRules();
369 Iterator iter = map.entrySet().iterator();
370 while (iter.hasNext()) {
371 Map.Entry entry = (Map.Entry)iter.next();
372
373 if (entry.getKey().equals(currentRuleSet)) {
374 Iterator iter2 = ((List)entry.getValue()).iterator();
375
376 while (iter2.hasNext()) {
377 ColorRule rule = (ColorRule)iter2.next();
378 Vector v = new Vector();
379 v.add(rule.getExpression());
380 v.add(rule.getBackgroundColor());
381 v.add(rule.getForegroundColor());
382 data.add(v);
383 }
384 }
385 }
386 return data;
387 }
388
389 private void configureTable() {
390 table.setToolTipText("Double click to edit");
391 table.setRowHeight(20);
392 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
393 table.setColumnSelectionAllowed(false);
394
395 Vector backgroundColors = colorizer.getDefaultColors();
396 Vector foregroundColors = colorizer.getDefaultColors();
397 backgroundColors.add("Browse...");
398 foregroundColors.add("Browse...");
399
400 JComboBox background = new JComboBox(backgroundColors);
401 background.setMaximumRowCount(15);
402 background.setRenderer(new ColorListCellRenderer());
403
404 JComboBox foreground = new JComboBox(foregroundColors);
405 foreground.setMaximumRowCount(15);
406 foreground.setRenderer(new ColorListCellRenderer());
407
408 DefaultCellEditor backgroundEditor = new DefaultCellEditor(background);
409 DefaultCellEditor foregroundEditor = new DefaultCellEditor(foreground);
410 JTextField textField = new JTextField();
411 textField.addKeyListener(
412 new ExpressionRuleContext(filterModel, textField));
413 table.getColumnModel().getColumn(0).setCellEditor(
414 new DefaultCellEditor(textField));
415 table.getColumnModel().getColumn(1).setCellEditor(backgroundEditor);
416 table.getColumnModel().getColumn(2).setCellEditor(foregroundEditor);
417
418 background.addItemListener(new ColorItemListener(background));
419 foreground.addItemListener(new ColorItemListener(foreground));
420
421 table.getColumnModel().getColumn(0).setCellRenderer(
422 new ExpressionTableCellRenderer());
423 table.getColumnModel().getColumn(1).setCellRenderer(
424 new ColorTableCellRenderer());
425 table.getColumnModel().getColumn(2).setCellRenderer(
426 new ColorTableCellRenderer());
427 }
428
429 private void configureSingleEntryColorTable(JTable thisTable) {
430 thisTable.setToolTipText("Double click to edit");
431 thisTable.setRowHeight(20);
432 thisTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
433 thisTable.setColumnSelectionAllowed(false);
434
435 Vector backgroundColors = colorizer.getDefaultColors();
436 Vector foregroundColors = colorizer.getDefaultColors();
437 backgroundColors.add("Browse...");
438 foregroundColors.add("Browse...");
439
440 JComboBox background = new JComboBox(backgroundColors);
441 background.setMaximumRowCount(15);
442 background.setRenderer(new ColorListCellRenderer());
443
444 JComboBox foreground = new JComboBox(foregroundColors);
445 foreground.setMaximumRowCount(15);
446 foreground.setRenderer(new ColorListCellRenderer());
447
448 DefaultCellEditor backgroundEditor = new DefaultCellEditor(background);
449 DefaultCellEditor foregroundEditor = new DefaultCellEditor(foreground);
450 thisTable.getColumnModel().getColumn(0).setCellEditor(backgroundEditor);
451 thisTable.getColumnModel().getColumn(1).setCellEditor(foregroundEditor);
452
453 background.addItemListener(new ColorItemListener(background));
454 foreground.addItemListener(new ColorItemListener(foreground));
455
456 thisTable.getColumnModel().getColumn(0).setCellRenderer(
457 new ColorTableCellRenderer());
458 thisTable.getColumnModel().getColumn(1).setCellRenderer(
459 new ColorTableCellRenderer());
460 }
461
462 public void setCloseActionListener(ActionListener listener) {
463 closeListener = listener;
464 }
465
466 public void hidePanel() {
467 if (closeListener != null) {
468 closeListener.actionPerformed(null);
469 }
470 }
471
472 void applyRules(String ruleSet, RuleColorizer applyingColorizer) {
473 table.getColumnModel().getColumn(0).getCellEditor().stopCellEditing();
474
475 List list = new ArrayList();
476 Vector vector = tableModel.getDataVector();
477 StringBuffer result = new StringBuffer();
478
479 for (int i = 0; i < vector.size(); i++) {
480 Vector v = (Vector) vector.elementAt(i);
481
482 try {
483 Rule expressionRule = ExpressionRule.getRule((String) v.elementAt(0));
484 Color background = getBackground();
485 Color foreground = getForeground();
486
487 if (v.elementAt(1) instanceof Color) {
488 background = (Color) v.elementAt(1);
489 }
490
491 if (v.elementAt(2) instanceof Color) {
492 foreground = (Color) v.elementAt(2);
493 }
494
495 ColorRule r = new ColorRule((String)v.elementAt(0), expressionRule, background, foreground);
496 list.add(r);
497 } catch (IllegalArgumentException iae) {
498 if (!result.toString().equals("")) {
499 result.append("<br>");
500 }
501
502 result.append(iae.getMessage());
503 }
504 }
505
506
507 if (result.toString().equals("")) {
508 ((ExpressionTableCellRenderer) table.getColumnModel().getColumn(0).getCellRenderer())
509 .setToolTipText("Double click to edit");
510 statusBar.setText(DEFAULT_STATUS);
511
512
513 Map map = new HashMap();
514 map.put(ruleSet, list);
515 applyingColorizer.setRules(map);
516
517 } else {
518 statusBar.setText("Errors - see expression tooltip (color filters won't be active until errors are resolved)");
519 ((ExpressionTableCellRenderer) table.getColumnModel().getColumn(0).getCellRenderer())
520 .setToolTipText("<html>" + result.toString() + "</html>");
521 }
522 }
523
524 JPanel buildClosePanel() {
525 JPanel panel = new JPanel();
526 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
527 panel.add(Box.createHorizontalGlue());
528
529 JButton saveAsDefaultButton = new JButton(" Save as default ");
530
531 saveAsDefaultButton.addActionListener(
532 new AbstractAction() {
533 public void actionPerformed(ActionEvent evt) {
534 RuleColorizer defaultColorizer = (RuleColorizer) allLogPanelColorizers.get(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
535 applyRules(currentRuleSet, defaultColorizer);
536 }
537 });
538
539 panel.add(saveAsDefaultButton);
540
541 JButton applyButton = new JButton(" Apply ");
542
543 applyButton.addActionListener(
544 new AbstractAction() {
545 public void actionPerformed(ActionEvent evt) {
546 applyRules(currentRuleSet, colorizer);
547 saveSearchColors();
548 saveAlternatingColors();
549 saveBypassFlag();
550 }
551 });
552
553 panel.add(Box.createHorizontalStrut(10));
554 panel.add(applyButton);
555
556 JButton closeButton = new JButton(" Close ");
557
558 closeButton.addActionListener(
559 new AbstractAction() {
560 public void actionPerformed(ActionEvent evt) {
561 hidePanel();
562 }
563 });
564 panel.add(Box.createHorizontalStrut(10));
565 panel.add(closeButton);
566
567 return panel;
568 }
569
570 private void saveSearchColors() {
571 Vector thisVector = (Vector) searchTableModel.getDataVector().get(0);
572 applicationPreferenceModel.setSearchBackgroundColor((Color)thisVector.get(0));
573 applicationPreferenceModel.setSearchForegroundColor((Color)thisVector.get(1));
574 }
575
576 private void saveAlternatingColors() {
577 Vector thisVector = (Vector) alternatingColorTableModel.getDataVector().get(0);
578 applicationPreferenceModel.setAlternatingBackgroundColor((Color)thisVector.get(0));
579 Color alternatingColorForegroundColor = (Color) thisVector.get(1);
580 applicationPreferenceModel.setAlternatingForegroundColor(alternatingColorForegroundColor);
581 }
582
583 private void saveBypassFlag() {
584 applicationPreferenceModel.setBypassSearchColors(bypassSearchColorsCheckBox.isSelected());
585 }
586
587 JPanel buildUpDownPanel() {
588 JPanel panel = new JPanel(new BorderLayout());
589 JPanel innerPanel = new JPanel();
590 innerPanel.setLayout(new GridLayout(5, 1));
591
592 final JButton upButton = new JButton(ChainsawIcons.ICON_UP);
593 upButton.setToolTipText("Move selected rule up");
594
595 final JButton downButton = new JButton(ChainsawIcons.ICON_DOWN);
596 downButton.setToolTipText("Move selected rule down");
597 upButton.setEnabled(false);
598 downButton.setEnabled(false);
599
600 table.getSelectionModel().addListSelectionListener(
601 new ListSelectionListener() {
602 public void valueChanged(ListSelectionEvent e) {
603 if (!e.getValueIsAdjusting()) {
604 int index = table.getSelectionModel().getMaxSelectionIndex();
605
606 if (index < 0) {
607 downButton.setEnabled(false);
608 upButton.setEnabled(false);
609 } else if ((index == 0) && (tableModel.getRowCount() == 1)) {
610 downButton.setEnabled(false);
611 upButton.setEnabled(false);
612 } else if ((index == 0) && (tableModel.getRowCount() > 1)) {
613 downButton.setEnabled(true);
614 upButton.setEnabled(false);
615 } else if (index == (tableModel.getRowCount() - 1)) {
616 downButton.setEnabled(false);
617 upButton.setEnabled(true);
618 } else {
619 downButton.setEnabled(true);
620 upButton.setEnabled(true);
621 }
622 }
623 }
624 });
625
626 JPanel upPanel = new JPanel();
627
628 upPanel.add(upButton);
629
630 JPanel downPanel = new JPanel();
631 downPanel.add(downButton);
632
633 innerPanel.add(new JLabel(""));
634 innerPanel.add(upPanel);
635 innerPanel.add(new JLabel(""));
636 innerPanel.add(downPanel);
637 panel.add(innerPanel, BorderLayout.CENTER);
638
639 upButton.addActionListener(
640 new AbstractAction() {
641 public void actionPerformed(ActionEvent evt) {
642 int index = table.getSelectionModel().getMaxSelectionIndex();
643
644 if (index > 0) {
645 Vector v = tableModel.getDataVector();
646 Vector row = (Vector) v.elementAt(index);
647 tableModel.removeRow(index);
648 index = index - 1;
649 tableModel.insertRow(index, row);
650 table.getSelectionModel().setSelectionInterval(index, index);
651 }
652 }
653 });
654
655 downButton.addActionListener(
656 new AbstractAction() {
657 public void actionPerformed(ActionEvent evt) {
658 int index = table.getSelectionModel().getMaxSelectionIndex();
659
660 if ((index > -1) && (index < (tableModel.getRowCount() - 1))) {
661 Vector v = tableModel.getDataVector();
662 Vector row = (Vector) v.elementAt(index);
663
664 tableModel.removeRow(index);
665 index = index + 1;
666 tableModel.insertRow(index, row);
667 table.getSelectionModel().setSelectionInterval(index, index);
668 }
669 }
670 });
671
672 return panel;
673 }
674
675 JPanel buildRulesPanel() {
676 JPanel listPanel = new JPanel(new BorderLayout());
677 JPanel panel = new JPanel();
678 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
679
680 panel.add(Box.createVerticalStrut(10));
681
682 JLabel rulesLabel = new JLabel("Rules:");
683
684 panel.add(rulesLabel);
685
686 JPanel buttonPanel = new JPanel(new GridLayout(0, 2));
687 buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
688
689 JPanel newPanel = new JPanel();
690 JButton newButton = new JButton(" New ");
691 newButton.addActionListener(
692 new AbstractAction() {
693 public void actionPerformed(ActionEvent evt) {
694 int currentRow = table.getSelectedRow();
695 Vector v = new Vector();
696 v.add("");
697 v.add(Color.white);
698 v.add(Color.black);
699
700 if (currentRow < 0) {
701 tableModel.addRow(v);
702 currentRow = table.getRowCount() - 1;
703 } else {
704 tableModel.insertRow(currentRow, v);
705 }
706
707 table.getSelectionModel().setSelectionInterval(
708 currentRow, currentRow);
709 }
710 });
711
712 newPanel.add(newButton);
713
714 JPanel deletePanel = new JPanel();
715 final JButton deleteButton = new JButton(" Delete ");
716 deleteButton.setEnabled(false);
717
718 deleteButton.addActionListener(
719 new AbstractAction() {
720 public void actionPerformed(ActionEvent evt) {
721 int index = table.getSelectionModel().getMaxSelectionIndex();
722
723 if ((index > -1) && (index < table.getRowCount())) {
724 tableModel.removeRow(index);
725
726 if (index > 0) {
727 index = index - 1;
728 }
729
730 if (tableModel.getRowCount() > 0) {
731 table.getSelectionModel().setSelectionInterval(index, index);
732 }
733 }
734 }
735 });
736
737 table.getSelectionModel().addListSelectionListener(
738 new ListSelectionListener() {
739 public void valueChanged(ListSelectionEvent e) {
740 if (!e.getValueIsAdjusting()) {
741 int index = table.getSelectionModel().getMaxSelectionIndex();
742
743 if (index < 0) {
744 deleteButton.setEnabled(false);
745 } else {
746 deleteButton.setEnabled(true);
747 }
748 }
749 }
750 });
751
752 deletePanel.add(deleteButton);
753
754 buttonPanel.add(newPanel);
755 buttonPanel.add(deletePanel);
756
757 listPanel.add(panel, BorderLayout.NORTH);
758
759 JPanel tablePanel = new JPanel(new BorderLayout());
760 tableScrollPane.setBorder(BorderFactory.createEtchedBorder());
761 tablePanel.add(tableScrollPane, BorderLayout.CENTER);
762 tablePanel.add(buildUpDownPanel(), BorderLayout.EAST);
763 listPanel.add(tablePanel, BorderLayout.CENTER);
764 listPanel.add(buttonPanel, BorderLayout.SOUTH);
765
766 return listPanel;
767 }
768
769 class ColorListCellRenderer extends JLabel implements ListCellRenderer {
770 ColorListCellRenderer() {
771 setOpaque(true);
772 }
773
774 public Component getListCellRendererComponent(
775 JList list, Object value, int index, boolean isSelected,
776 boolean cellHasFocus) {
777 setText(" ");
778
779 if (isSelected && (index > -1)) {
780 setBorder(BorderFactory.createLineBorder(Color.black, 2));
781 } else {
782 setBorder(BorderFactory.createEmptyBorder());
783 }
784
785 if (value instanceof Color) {
786 setBackground((Color) value);
787 } else {
788 setBackground(Color.white);
789
790 if (value != null) {
791 setText(value.toString());
792 }
793 }
794
795 return this;
796 }
797 }
798
799 class ColorItemListener implements ItemListener {
800 JComboBox box;
801 JDialog dialog;
802 JColorChooser colorChooser;
803 Color lastColor;
804
805 ColorItemListener(final JComboBox box) {
806 this.box = box;
807 colorChooser = new JColorChooser();
808 dialog =
809 JColorChooser.createDialog(
810 box, "Pick a Color", true,
811 colorChooser,
812 new ActionListener() {
813 public void actionPerformed(ActionEvent e) {
814 box.insertItemAt(colorChooser.getColor(), 0);
815 box.setSelectedIndex(0);
816 }
817 },
818 new ActionListener() {
819 public void actionPerformed(ActionEvent e) {
820 box.setSelectedItem(lastColor);
821 }
822 });
823 dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
824 }
825
826 public void itemStateChanged(ItemEvent e) {
827 if (e.getStateChange() == ItemEvent.SELECTED) {
828 if (box.getSelectedItem() instanceof Color) {
829 box.setBackground((Color) box.getSelectedItem());
830 repaint();
831 } else {
832 box.setBackground(Color.white);
833 int selectedRow = table.getSelectedRow();
834 int selectedColumn = table.getSelectedColumn();
835 if (selectedRow != -1 && selectedColumn != -1) {
836 colorChooser.setColor((Color)table.getValueAt(selectedRow, selectedColumn));
837 lastColor = (Color)table.getValueAt(selectedRow, selectedColumn);
838 }
839 dialog.setVisible(true);
840 }
841 }
842 }
843 }
844
845 class ColorTableCellRenderer implements TableCellRenderer {
846 Border border;
847 JPanel panel;
848
849 ColorTableCellRenderer() {
850 panel = new JPanel();
851 panel.setOpaque(true);
852 }
853
854 public Color getCurrentColor() {
855 return panel.getBackground();
856 }
857
858 public Component getTableCellRendererComponent(
859 JTable thisTable, Object value, boolean isSelected, boolean hasFocus, int row,
860 int column) {
861 if (value instanceof Color) {
862 panel.setBackground((Color) value);
863 }
864 if (border == null) {
865 border = BorderFactory.createMatteBorder(2, 2, 2, 2, table.getBackground());
866 }
867
868 panel.setBorder(border);
869
870 return panel;
871 }
872 }
873
874 class ExpressionTableCellRenderer implements TableCellRenderer {
875 JPanel panel = new JPanel();
876 JLabel expressionLabel = new JLabel();
877 JLabel iconLabel = new JLabel();
878 Icon selectedIcon = new SelectedIcon(true);
879 Icon unselectedIcon = new SelectedIcon(false);
880
881 ExpressionTableCellRenderer() {
882 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
883 panel.setOpaque(true);
884 panel.add(iconLabel);
885 panel.add(Box.createHorizontalStrut(5));
886 panel.add(expressionLabel);
887 }
888
889 void setToolTipText(String text) {
890 panel.setToolTipText(text);
891 }
892
893 public Component getTableCellRendererComponent(
894 JTable thisTable, Object value, boolean isSelected, boolean hasFocus, int row,
895 int column) {
896 if (value == null) {
897 return panel;
898 }
899
900 Vector v = tableModel.getDataVector();
901 Vector r = (Vector) v.elementAt(row);
902 expressionLabel.setText(value.toString());
903
904 if (r.elementAt(1) instanceof Color) {
905 expressionLabel.setBackground((Color) r.elementAt(1));
906 panel.setBackground((Color) r.elementAt(1));
907 }
908
909 if (r.elementAt(2) instanceof Color) {
910 expressionLabel.setForeground((Color) r.elementAt(2));
911 panel.setForeground((Color) r.elementAt(2));
912 }
913
914 if (isSelected) {
915 iconLabel.setIcon(selectedIcon);
916 } else {
917 iconLabel.setIcon(unselectedIcon);
918 }
919
920 return panel;
921 }
922 }
923
924 class SelectedIcon implements Icon {
925 private boolean isSelected;
926 private int width = 9;
927 private int height = 18;
928 private int[] xPoints = new int[4];
929 private int[] yPoints = new int[4];
930
931 public SelectedIcon(boolean isSelected) {
932 this.isSelected = isSelected;
933 xPoints[0] = 0;
934 yPoints[0] = -1;
935 xPoints[1] = 0;
936 yPoints[1] = height;
937 xPoints[2] = width;
938 yPoints[2] = height / 2;
939 xPoints[3] = width;
940 yPoints[3] = (height / 2) - 1;
941 }
942
943 public int getIconHeight() {
944 return height;
945 }
946
947 public int getIconWidth() {
948 return width;
949 }
950
951 public void paintIcon(Component c, Graphics g, int x, int y) {
952 if (isSelected) {
953 int length = xPoints.length;
954 int[] newXPoints = new int[length];
955 int[] newYPoints = new int[length];
956
957 for (int i = 0; i < length; i++) {
958 newXPoints[i] = xPoints[i] + x;
959 newYPoints[i] = yPoints[i] + y;
960 }
961
962 g.setColor(Color.black);
963
964 g.fillPolygon(newXPoints, newYPoints, length);
965 }
966 }
967 }
968 }