| /* |
| * 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.apache.log4j.chainsaw.color; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Graphics; |
| import java.awt.GridLayout; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.ItemListener; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import javax.swing.AbstractAction; |
| import javax.swing.Action; |
| import javax.swing.BorderFactory; |
| import javax.swing.Box; |
| import javax.swing.BoxLayout; |
| import javax.swing.DefaultCellEditor; |
| import javax.swing.DefaultComboBoxModel; |
| import javax.swing.Icon; |
| import javax.swing.JButton; |
| import javax.swing.JCheckBox; |
| import javax.swing.JColorChooser; |
| import javax.swing.JComboBox; |
| import javax.swing.JDialog; |
| import javax.swing.JLabel; |
| import javax.swing.JList; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JTable; |
| import javax.swing.JTextField; |
| import javax.swing.ListCellRenderer; |
| import javax.swing.ListSelectionModel; |
| import javax.swing.WindowConstants; |
| import javax.swing.border.Border; |
| import javax.swing.table.DefaultTableModel; |
| import javax.swing.table.TableCellRenderer; |
| |
| import org.apache.log4j.chainsaw.ApplicationPreferenceModel; |
| import org.apache.log4j.chainsaw.ChainsawConstants; |
| import org.apache.log4j.chainsaw.ExpressionRuleContext; |
| import org.apache.log4j.chainsaw.filter.FilterModel; |
| import org.apache.log4j.chainsaw.helper.SwingHelper; |
| import org.apache.log4j.chainsaw.icons.ChainsawIcons; |
| import org.apache.log4j.rule.ColorRule; |
| import org.apache.log4j.rule.ExpressionRule; |
| import org.apache.log4j.rule.Rule; |
| |
| |
| /** |
| * Panel which updates a RuleColorizer, allowing the user to build expression-based |
| * color rules. |
| * |
| * TODO: examine ColorPanel/RuleColorizer/LogPanel listeners and interactions |
| * |
| * @author Scott Deboy <sdeboy@apache.org> |
| */ |
| public class ColorPanel extends JPanel |
| { |
| private static final String DEFAULT_STATUS = "<html>Double click a rule field to edit the rule</html>"; |
| private final String currentRuleSet = "Default"; |
| |
| private RuleColorizer colorizer; |
| private JPanel rulesPanel; |
| private FilterModel filterModel; |
| private DefaultTableModel tableModel; |
| private JScrollPane tableScrollPane; |
| private JTable table; |
| private ActionListener closeListener; |
| private JLabel statusBar; |
| private Vector<String> columns; |
| private final String noTab = "None"; |
| private DefaultComboBoxModel logPanelColorizersModel; |
| private Map<String, RuleColorizer> allLogPanelColorizers; |
| private RuleColorizer currentLogPanelColorizer; |
| private JTable searchTable; |
| private DefaultTableModel searchTableModel; |
| private Vector<String> searchColumns; |
| private Vector<Vector<Color>> searchDataVector; |
| private Vector<Color> searchDataVectorEntry; |
| |
| private JTable alternatingColorTable; |
| private DefaultTableModel alternatingColorTableModel; |
| private Vector<String> alternatingColorColumns; |
| private Vector<Vector<Color>> alternatingColorDataVector; |
| private Vector<Color> alternatingColorDataVectorEntry; |
| private ApplicationPreferenceModel applicationPreferenceModel; |
| private JCheckBox bypassSearchColorsCheckBox; |
| |
| public ColorPanel(final RuleColorizer currentLogPanelColorizer, final FilterModel filterModel, |
| final Map<String, RuleColorizer> allLogPanelColorizers, final ApplicationPreferenceModel applicationPreferenceModel) { |
| super(new BorderLayout()); |
| |
| this.currentLogPanelColorizer = currentLogPanelColorizer; |
| this.colorizer = currentLogPanelColorizer; |
| this.filterModel = filterModel; |
| this.allLogPanelColorizers = allLogPanelColorizers; |
| this.applicationPreferenceModel = applicationPreferenceModel; |
| |
| currentLogPanelColorizer.addPropertyChangeListener( |
| "colorrule", |
| evt -> updateColors()); |
| |
| tableModel = new DefaultTableModel(); |
| table = new JTable(tableModel); |
| table.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT); |
| |
| searchTableModel = new DefaultTableModel(); |
| searchTable = new JTable(searchTableModel); |
| searchTable.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT); |
| searchTable.setPreferredScrollableViewportSize(new Dimension(30, 30)); |
| |
| alternatingColorTableModel = new DefaultTableModel(); |
| alternatingColorTable = new JTable(alternatingColorTableModel); |
| alternatingColorTable.setRowHeight(ChainsawConstants.DEFAULT_ROW_HEIGHT); |
| alternatingColorTable.setPreferredScrollableViewportSize(new Dimension(30, 30)); |
| |
| columns = new Vector<>(); |
| columns.add("Expression"); |
| columns.add("Background"); |
| columns.add("Foreground"); |
| |
| searchColumns = new Vector<>(); |
| searchColumns.add("Background"); |
| searchColumns.add("Foreground"); |
| |
| alternatingColorColumns = new Vector<>(); |
| alternatingColorColumns.add("Background"); |
| alternatingColorColumns.add("Foreground"); |
| |
| //searchtable contains only a single-entry vector containing a two-item vector (foreground, background) |
| searchDataVector = new Vector<>(); |
| searchDataVectorEntry = new Vector<>(); |
| searchDataVectorEntry.add(applicationPreferenceModel.getSearchBackgroundColor()); |
| searchDataVectorEntry.add(applicationPreferenceModel.getSearchForegroundColor()); |
| searchDataVector.add(searchDataVectorEntry); |
| searchTableModel.setDataVector(searchDataVector, searchColumns); |
| |
| alternatingColorDataVector = new Vector<>(); |
| alternatingColorDataVectorEntry = new Vector<>(); |
| alternatingColorDataVectorEntry.add(applicationPreferenceModel.getAlternatingColorBackgroundColor()); |
| alternatingColorDataVectorEntry.add(applicationPreferenceModel.getAlternatingColorForegroundColor()); |
| alternatingColorDataVector.add(alternatingColorDataVectorEntry); |
| alternatingColorTableModel.setDataVector(alternatingColorDataVector, alternatingColorColumns); |
| |
| table.setPreferredScrollableViewportSize(new Dimension(525, 200)); |
| tableScrollPane = new JScrollPane(table); |
| |
| Vector<Vector<java.io.Serializable>> data = getColorizerVector(); |
| tableModel.setDataVector(data, columns); |
| |
| table.sizeColumnsToFit(0); |
| table.getColumnModel().getColumn(1).setPreferredWidth(80); |
| table.getColumnModel().getColumn(2).setPreferredWidth(80); |
| table.getColumnModel().getColumn(1).setMaxWidth(80); |
| table.getColumnModel().getColumn(2).setMaxWidth(80); |
| |
| searchTable.sizeColumnsToFit(0); |
| searchTable.getColumnModel().getColumn(0).setPreferredWidth(80); |
| searchTable.getColumnModel().getColumn(1).setPreferredWidth(80); |
| searchTable.getColumnModel().getColumn(0).setMaxWidth(80); |
| searchTable.getColumnModel().getColumn(1).setMaxWidth(80); |
| //building color choosers needs to be done on the EDT |
| SwingHelper.invokeOnEDT(() -> configureSingleEntryColorTable(searchTable)); |
| |
| alternatingColorTable.sizeColumnsToFit(0); |
| alternatingColorTable.getColumnModel().getColumn(0).setPreferredWidth(80); |
| alternatingColorTable.getColumnModel().getColumn(1).setPreferredWidth(80); |
| alternatingColorTable.getColumnModel().getColumn(0).setMaxWidth(80); |
| alternatingColorTable.getColumnModel().getColumn(1).setMaxWidth(80); |
| //building color choosers needs to be done on the EDT |
| SwingHelper.invokeOnEDT(() -> configureSingleEntryColorTable(alternatingColorTable)); |
| |
| configureTable(); |
| |
| statusBar = new JLabel(DEFAULT_STATUS); |
| |
| rulesPanel = buildRulesPanel(); |
| rulesPanel.setAlignmentX(Component.LEFT_ALIGNMENT); |
| |
| JPanel rightPanel = new JPanel(new BorderLayout()); |
| |
| JPanel rightOuterPanel = new JPanel(); |
| rightOuterPanel.setLayout( |
| new BoxLayout(rightOuterPanel, BoxLayout.X_AXIS)); |
| rightOuterPanel.add(Box.createHorizontalStrut(10)); |
| |
| JPanel southPanel = new JPanel(); |
| southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS)); |
| southPanel.add(Box.createVerticalStrut(5)); |
| southPanel.add(Box.createVerticalStrut(5)); |
| JPanel searchAndAlternatingColorPanel = buildSearchAndAlternatingColorPanel(); |
| JPanel bypassSearchColorsPanel = buildBypassSearchColorsPanel(); |
| bypassSearchColorsCheckBox.setSelected(applicationPreferenceModel.isBypassSearchColors()); |
| |
| JPanel globalLabelPanel = new JPanel(); |
| globalLabelPanel.setLayout(new BoxLayout(globalLabelPanel, BoxLayout.X_AXIS)); |
| JLabel globalLabel = new JLabel("Global colors:"); |
| globalLabelPanel.add(globalLabel); |
| globalLabelPanel.add(Box.createHorizontalGlue()); |
| southPanel.add(globalLabelPanel); |
| southPanel.add(searchAndAlternatingColorPanel); |
| southPanel.add(bypassSearchColorsPanel); |
| southPanel.add(Box.createVerticalStrut(5)); |
| JPanel closePanel = buildClosePanel(); |
| southPanel.add(closePanel); |
| |
| JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
| statusPanel.add(statusBar); |
| southPanel.add(statusPanel); |
| rightPanel.add(rulesPanel, BorderLayout.CENTER); |
| rightPanel.add(southPanel, BorderLayout.SOUTH); |
| rightOuterPanel.add(rightPanel); |
| |
| JPanel topPanel = new JPanel(); |
| topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS)); |
| |
| JLabel selectText = new JLabel("Apply a tab's colors"); |
| topPanel.add(selectText); |
| topPanel.add(Box.createHorizontalStrut(5)); |
| |
| logPanelColorizersModel = new DefaultComboBoxModel(); |
| final JComboBox loadPanelColorizersComboBox = new JComboBox(logPanelColorizersModel); |
| loadLogPanelColorizers(); |
| |
| topPanel.add(loadPanelColorizersComboBox); |
| |
| topPanel.add(Box.createHorizontalStrut(5)); |
| final Action copyRulesAction = new AbstractAction() { |
| public void actionPerformed(ActionEvent e) |
| { |
| tableModel.getDataVector().clear(); |
| Object selectedItem = loadPanelColorizersComboBox.getSelectedItem(); |
| if (selectedItem != null) { |
| RuleColorizer sourceColorizer = allLogPanelColorizers.get(selectedItem.toString()); |
| colorizer.setRules(sourceColorizer.getRules()); |
| updateColors(); |
| } |
| } |
| }; |
| |
| loadPanelColorizersComboBox.addActionListener(e -> { |
| Object selectedItem = loadPanelColorizersComboBox.getSelectedItem(); |
| if (selectedItem != null) { |
| String selectedColorizerName = selectedItem.toString(); |
| copyRulesAction.setEnabled(!(noTab.equals(selectedColorizerName))); |
| } |
| }); |
| |
| copyRulesAction.putValue(Action.NAME, "Copy color rules"); |
| copyRulesAction.setEnabled(!(noTab.equals(loadPanelColorizersComboBox.getSelectedItem()))); |
| |
| JButton copyRulesButton = new JButton(copyRulesAction); |
| topPanel.add(copyRulesButton); |
| |
| add(topPanel, BorderLayout.NORTH); |
| add(rightOuterPanel, BorderLayout.CENTER); |
| if (table.getRowCount() > 0) { |
| table.getSelectionModel().setSelectionInterval(0, 0); |
| } |
| } |
| |
| public void loadLogPanelColorizers() { |
| if (logPanelColorizersModel.getIndexOf(noTab) == -1) { |
| logPanelColorizersModel.addElement(noTab); |
| } |
| for (Object o : allLogPanelColorizers.entrySet()) { |
| Map.Entry entry = (Map.Entry) o; |
| if (!entry.getValue().equals(currentLogPanelColorizer) && (logPanelColorizersModel.getIndexOf(entry.getKey()) == -1)) { |
| logPanelColorizersModel.addElement(entry.getKey()); |
| } |
| } |
| //update search and alternating colors, since they may have changed from another color panel |
| searchDataVectorEntry.set(0, applicationPreferenceModel.getSearchBackgroundColor()); |
| searchDataVectorEntry.set(1, applicationPreferenceModel.getSearchForegroundColor()); |
| alternatingColorDataVectorEntry.set(0, applicationPreferenceModel.getAlternatingColorBackgroundColor()); |
| alternatingColorDataVectorEntry.set(1, applicationPreferenceModel.getAlternatingColorForegroundColor()); |
| } |
| |
| public JPanel buildBypassSearchColorsPanel() { |
| JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); |
| |
| bypassSearchColorsCheckBox = new JCheckBox("Don't use a search color for matching rows"); |
| panel.add(bypassSearchColorsCheckBox); |
| return panel; |
| } |
| |
| public JPanel buildSearchAndAlternatingColorPanel() { |
| JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); |
| |
| JLabel defineSearchColorsLabel = new JLabel("Find colors"); |
| |
| panel.add(defineSearchColorsLabel); |
| |
| panel.add(Box.createHorizontalStrut(10)); |
| JScrollPane searchPane = new JScrollPane(searchTable); |
| searchPane.setBorder(BorderFactory.createEmptyBorder()); |
| panel.add(searchPane); |
| |
| panel.add(Box.createHorizontalStrut(10)); |
| JLabel defineAlternatingColorLabel = new JLabel("Alternating colors"); |
| |
| panel.add(defineAlternatingColorLabel); |
| |
| panel.add(Box.createHorizontalStrut(10)); |
| JScrollPane alternatingColorPane = new JScrollPane(alternatingColorTable); |
| alternatingColorPane.setBorder(BorderFactory.createEmptyBorder()); |
| |
| panel.add(alternatingColorPane); |
| panel.setBorder(BorderFactory.createEtchedBorder()); |
| panel.add(Box.createHorizontalGlue()); |
| return panel; |
| } |
| |
| public void updateColors() { |
| tableModel.getDataVector().clear(); |
| tableModel.getDataVector().addAll(getColorizerVector()); |
| tableModel.fireTableDataChanged(); |
| } |
| |
| private Vector<Vector<java.io.Serializable>> getColorizerVector() { |
| Vector<Vector<java.io.Serializable>> data = new Vector<>(); |
| Map map = colorizer.getRules(); |
| for (Object o1 : map.entrySet()) { |
| Map.Entry entry = (Map.Entry) o1; |
| //update ruleset list |
| if (entry.getKey().equals(currentRuleSet)) { |
| |
| for (Object o : ((List) entry.getValue())) { |
| ColorRule rule = (ColorRule) o; |
| Vector<java.io.Serializable> v = new Vector<>(); |
| v.add(rule.getExpression()); |
| v.add(rule.getBackgroundColor()); |
| v.add(rule.getForegroundColor()); |
| data.add(v); |
| } |
| } |
| } |
| return data; |
| } |
| |
| private void configureTable() { |
| table.setToolTipText("Double click to edit"); |
| table.setRowHeight(20); |
| table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| table.setColumnSelectionAllowed(false); |
| |
| Vector backgroundColors = colorizer.getDefaultColors(); |
| Vector foregroundColors = colorizer.getDefaultColors(); |
| backgroundColors.add("Browse..."); |
| foregroundColors.add("Browse..."); |
| |
| JComboBox background = new JComboBox(backgroundColors); |
| background.setMaximumRowCount(15); |
| background.setRenderer(new ColorListCellRenderer()); |
| |
| JComboBox foreground = new JComboBox(foregroundColors); |
| foreground.setMaximumRowCount(15); |
| foreground.setRenderer(new ColorListCellRenderer()); |
| |
| DefaultCellEditor backgroundEditor = new DefaultCellEditor(background); |
| DefaultCellEditor foregroundEditor = new DefaultCellEditor(foreground); |
| JTextField textField = new JTextField(); |
| textField.addKeyListener( |
| new ExpressionRuleContext(filterModel, textField)); |
| table.getColumnModel().getColumn(0).setCellEditor( |
| new DefaultCellEditor(textField)); |
| table.getColumnModel().getColumn(1).setCellEditor(backgroundEditor); |
| table.getColumnModel().getColumn(2).setCellEditor(foregroundEditor); |
| |
| background.addItemListener(new ColorItemListener(background)); |
| foreground.addItemListener(new ColorItemListener(foreground)); |
| |
| table.getColumnModel().getColumn(0).setCellRenderer( |
| new ExpressionTableCellRenderer()); |
| table.getColumnModel().getColumn(1).setCellRenderer( |
| new ColorTableCellRenderer()); |
| table.getColumnModel().getColumn(2).setCellRenderer( |
| new ColorTableCellRenderer()); |
| } |
| |
| private void configureSingleEntryColorTable(JTable thisTable) { |
| thisTable.setToolTipText("Double click to edit"); |
| thisTable.setRowHeight(20); |
| thisTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
| thisTable.setColumnSelectionAllowed(false); |
| |
| Vector backgroundColors = colorizer.getDefaultColors(); |
| Vector foregroundColors = colorizer.getDefaultColors(); |
| backgroundColors.add("Browse..."); |
| foregroundColors.add("Browse..."); |
| |
| JComboBox background = new JComboBox(backgroundColors); |
| background.setMaximumRowCount(15); |
| background.setRenderer(new ColorListCellRenderer()); |
| |
| JComboBox foreground = new JComboBox(foregroundColors); |
| foreground.setMaximumRowCount(15); |
| foreground.setRenderer(new ColorListCellRenderer()); |
| |
| DefaultCellEditor backgroundEditor = new DefaultCellEditor(background); |
| DefaultCellEditor foregroundEditor = new DefaultCellEditor(foreground); |
| thisTable.getColumnModel().getColumn(0).setCellEditor(backgroundEditor); |
| thisTable.getColumnModel().getColumn(1).setCellEditor(foregroundEditor); |
| |
| background.addItemListener(new ColorItemListener(background)); |
| foreground.addItemListener(new ColorItemListener(foreground)); |
| |
| thisTable.getColumnModel().getColumn(0).setCellRenderer( |
| new ColorTableCellRenderer()); |
| thisTable.getColumnModel().getColumn(1).setCellRenderer( |
| new ColorTableCellRenderer()); |
| } |
| |
| public void setCloseActionListener(ActionListener listener) { |
| closeListener = listener; |
| } |
| |
| public void hidePanel() { |
| if (closeListener != null) { |
| closeListener.actionPerformed(null); |
| } |
| } |
| |
| void applyRules(String ruleSet, RuleColorizer applyingColorizer) { |
| table.getColumnModel().getColumn(0).getCellEditor().stopCellEditing(); |
| |
| List list = new ArrayList(); |
| Vector vector = tableModel.getDataVector(); |
| StringBuilder result = new StringBuilder(); |
| |
| for (int i = 0; i < vector.size(); i++) { |
| Vector v = (Vector) vector.elementAt(i); |
| |
| try { |
| Rule expressionRule = ExpressionRule.getRule((String) v.elementAt(0)); |
| Color background = getBackground(); |
| Color foreground = getForeground(); |
| |
| if (v.elementAt(1) instanceof Color) { |
| background = (Color) v.elementAt(1); |
| } |
| |
| if (v.elementAt(2) instanceof Color) { |
| foreground = (Color) v.elementAt(2); |
| } |
| |
| ColorRule r = new ColorRule((String)v.elementAt(0), expressionRule, background, foreground); |
| list.add(r); |
| } catch (IllegalArgumentException iae) { |
| if (!result.toString().equals("")) { |
| result.append("<br>"); |
| } |
| |
| result.append(iae.getMessage()); |
| } |
| } |
| |
| //all rules are valid, they can be applied |
| if (result.toString().equals("")) { |
| ((ExpressionTableCellRenderer) table.getColumnModel().getColumn(0).getCellRenderer()) |
| .setToolTipText("Double click to edit"); |
| statusBar.setText(DEFAULT_STATUS); |
| |
| //only update rules if there were no errors |
| Map map = new HashMap(); |
| map.put(ruleSet, list); |
| applyingColorizer.setRules(map); |
| |
| } else { |
| statusBar.setText("Errors - see expression tooltip (color filters won't be active until errors are resolved)"); |
| ((ExpressionTableCellRenderer) table.getColumnModel().getColumn(0).getCellRenderer()) |
| .setToolTipText("<html>" + result.toString() + "</html>"); |
| } |
| } |
| |
| JPanel buildClosePanel() { |
| JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); |
| panel.add(Box.createHorizontalGlue()); |
| |
| JButton saveAsDefaultButton = new JButton(" Save as default "); |
| |
| saveAsDefaultButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| RuleColorizer defaultColorizer = allLogPanelColorizers.get(ChainsawConstants.DEFAULT_COLOR_RULE_NAME); |
| applyRules(currentRuleSet, defaultColorizer); |
| } |
| }); |
| |
| panel.add(saveAsDefaultButton); |
| |
| JButton applyButton = new JButton(" Apply "); |
| |
| applyButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| applyRules(currentRuleSet, colorizer); |
| saveSearchColors(); |
| saveAlternatingColors(); |
| saveBypassFlag(); |
| } |
| }); |
| |
| panel.add(Box.createHorizontalStrut(10)); |
| panel.add(applyButton); |
| |
| JButton closeButton = new JButton(" Close "); |
| |
| closeButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| hidePanel(); |
| } |
| }); |
| panel.add(Box.createHorizontalStrut(10)); |
| panel.add(closeButton); |
| |
| return panel; |
| } |
| |
| private void saveSearchColors() { |
| Vector thisVector = (Vector) searchTableModel.getDataVector().get(0); |
| applicationPreferenceModel.setSearchBackgroundColor((Color)thisVector.get(0)); |
| applicationPreferenceModel.setSearchForegroundColor((Color)thisVector.get(1)); |
| } |
| |
| private void saveAlternatingColors() { |
| Vector thisVector = (Vector) alternatingColorTableModel.getDataVector().get(0); |
| applicationPreferenceModel.setAlternatingBackgroundColor((Color)thisVector.get(0)); |
| Color alternatingColorForegroundColor = (Color) thisVector.get(1); |
| applicationPreferenceModel.setAlternatingForegroundColor(alternatingColorForegroundColor); |
| } |
| |
| private void saveBypassFlag() { |
| applicationPreferenceModel.setBypassSearchColors(bypassSearchColorsCheckBox.isSelected()); |
| } |
| |
| JPanel buildUpDownPanel() { |
| JPanel panel = new JPanel(new BorderLayout()); |
| JPanel innerPanel = new JPanel(); |
| innerPanel.setLayout(new GridLayout(5, 1)); |
| |
| final JButton upButton = new JButton(ChainsawIcons.ICON_UP); |
| upButton.setToolTipText("Move selected rule up"); |
| |
| final JButton downButton = new JButton(ChainsawIcons.ICON_DOWN); |
| downButton.setToolTipText("Move selected rule down"); |
| upButton.setEnabled(false); |
| downButton.setEnabled(false); |
| |
| table.getSelectionModel().addListSelectionListener( |
| e -> { |
| if (!e.getValueIsAdjusting()) { |
| int index = table.getSelectionModel().getMaxSelectionIndex(); |
| |
| if (index < 0) { |
| downButton.setEnabled(false); |
| upButton.setEnabled(false); |
| } else if ((index == 0) && (tableModel.getRowCount() == 1)) { |
| downButton.setEnabled(false); |
| upButton.setEnabled(false); |
| } else if ((index == 0) && (tableModel.getRowCount() > 1)) { |
| downButton.setEnabled(true); |
| upButton.setEnabled(false); |
| } else if (index == (tableModel.getRowCount() - 1)) { |
| downButton.setEnabled(false); |
| upButton.setEnabled(true); |
| } else { |
| downButton.setEnabled(true); |
| upButton.setEnabled(true); |
| } |
| } |
| }); |
| |
| JPanel upPanel = new JPanel(); |
| |
| upPanel.add(upButton); |
| |
| JPanel downPanel = new JPanel(); |
| downPanel.add(downButton); |
| |
| innerPanel.add(new JLabel("")); |
| innerPanel.add(upPanel); |
| innerPanel.add(new JLabel("")); |
| innerPanel.add(downPanel); |
| panel.add(innerPanel, BorderLayout.CENTER); |
| |
| upButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| int index = table.getSelectionModel().getMaxSelectionIndex(); |
| |
| if (index > 0) { |
| Vector v = tableModel.getDataVector(); |
| Vector row = (Vector) v.elementAt(index); |
| tableModel.removeRow(index); |
| index = index - 1; |
| tableModel.insertRow(index, row); |
| table.getSelectionModel().setSelectionInterval(index, index); |
| } |
| } |
| }); |
| |
| downButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| int index = table.getSelectionModel().getMaxSelectionIndex(); |
| |
| if ((index > -1) && (index < (tableModel.getRowCount() - 1))) { |
| Vector v = tableModel.getDataVector(); |
| Vector row = (Vector) v.elementAt(index); |
| |
| tableModel.removeRow(index); |
| index = index + 1; |
| tableModel.insertRow(index, row); |
| table.getSelectionModel().setSelectionInterval(index, index); |
| } |
| } |
| }); |
| |
| return panel; |
| } |
| |
| JPanel buildRulesPanel() { |
| JPanel listPanel = new JPanel(new BorderLayout()); |
| JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); |
| |
| panel.add(Box.createVerticalStrut(10)); |
| |
| JLabel rulesLabel = new JLabel("Rules:"); |
| |
| panel.add(rulesLabel); |
| |
| JPanel buttonPanel = new JPanel(new GridLayout(0, 2)); |
| buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT); |
| |
| JPanel newPanel = new JPanel(); |
| JButton newButton = new JButton(" New "); |
| newButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| int currentRow = table.getSelectedRow(); |
| Vector<java.io.Serializable> v = new Vector<>(); |
| v.add(""); |
| v.add(Color.white); |
| v.add(Color.black); |
| |
| if (currentRow < 0) { |
| tableModel.addRow(v); |
| currentRow = table.getRowCount() - 1; |
| } else { |
| tableModel.insertRow(currentRow, v); |
| } |
| |
| table.getSelectionModel().setSelectionInterval( |
| currentRow, currentRow); |
| } |
| }); |
| |
| newPanel.add(newButton); |
| |
| JPanel deletePanel = new JPanel(); |
| final JButton deleteButton = new JButton(" Delete "); |
| deleteButton.setEnabled(false); |
| |
| deleteButton.addActionListener( |
| new AbstractAction() { |
| public void actionPerformed(ActionEvent evt) { |
| int index = table.getSelectionModel().getMaxSelectionIndex(); |
| |
| if ((index > -1) && (index < table.getRowCount())) { |
| tableModel.removeRow(index); |
| |
| if (index > 0) { |
| index = index - 1; |
| } |
| |
| if (tableModel.getRowCount() > 0) { |
| table.getSelectionModel().setSelectionInterval(index, index); |
| } |
| } |
| } |
| }); |
| |
| table.getSelectionModel().addListSelectionListener( |
| e -> { |
| if (!e.getValueIsAdjusting()) { |
| int index = table.getSelectionModel().getMaxSelectionIndex(); |
| |
| if (index < 0) { |
| deleteButton.setEnabled(false); |
| } else { |
| deleteButton.setEnabled(true); |
| } |
| } |
| }); |
| |
| deletePanel.add(deleteButton); |
| |
| buttonPanel.add(newPanel); |
| buttonPanel.add(deletePanel); |
| |
| listPanel.add(panel, BorderLayout.NORTH); |
| |
| JPanel tablePanel = new JPanel(new BorderLayout()); |
| tableScrollPane.setBorder(BorderFactory.createEtchedBorder()); |
| tablePanel.add(tableScrollPane, BorderLayout.CENTER); |
| tablePanel.add(buildUpDownPanel(), BorderLayout.EAST); |
| listPanel.add(tablePanel, BorderLayout.CENTER); |
| listPanel.add(buttonPanel, BorderLayout.SOUTH); |
| |
| return listPanel; |
| } |
| |
| class ColorListCellRenderer extends JLabel implements ListCellRenderer { |
| ColorListCellRenderer() { |
| setOpaque(true); |
| } |
| |
| public Component getListCellRendererComponent( |
| JList list, Object value, int index, boolean isSelected, |
| boolean cellHasFocus) { |
| setText(" "); |
| |
| if (isSelected && (index > -1)) { |
| setBorder(BorderFactory.createLineBorder(Color.black, 2)); |
| } else { |
| setBorder(BorderFactory.createEmptyBorder()); |
| } |
| |
| if (value instanceof Color) { |
| setBackground((Color) value); |
| } else { |
| setBackground(Color.white); |
| |
| if (value != null) { |
| setText(value.toString()); |
| } |
| } |
| |
| return this; |
| } |
| } |
| |
| class ColorItemListener implements ItemListener { |
| JComboBox box; |
| JDialog dialog; |
| JColorChooser colorChooser; |
| Color lastColor; |
| |
| ColorItemListener(final JComboBox box) { |
| this.box = box; |
| colorChooser = new JColorChooser(); |
| dialog = |
| JColorChooser.createDialog( |
| box, "Pick a Color", true, //modal |
| colorChooser, |
| e -> { |
| box.insertItemAt(colorChooser.getColor(), 0); |
| box.setSelectedIndex(0); |
| }, //OK button handler |
| e -> box.setSelectedItem(lastColor)); //CANCEL button handler |
| dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); |
| } |
| |
| public void itemStateChanged(ItemEvent e) { |
| if (e.getStateChange() == ItemEvent.SELECTED) { |
| if (box.getSelectedItem() instanceof Color) { |
| box.setBackground((Color) box.getSelectedItem()); |
| repaint(); |
| } else { |
| box.setBackground(Color.white); |
| int selectedRow = table.getSelectedRow(); |
| int selectedColumn = table.getSelectedColumn(); |
| if (selectedRow != -1 && selectedColumn != -1) { |
| colorChooser.setColor((Color)table.getValueAt(selectedRow, selectedColumn)); |
| lastColor = (Color)table.getValueAt(selectedRow, selectedColumn); |
| } |
| dialog.setVisible(true); |
| } |
| } |
| } |
| } |
| |
| class ColorTableCellRenderer implements TableCellRenderer { |
| Border border; |
| JPanel panel; |
| |
| ColorTableCellRenderer() { |
| panel = new JPanel(); |
| panel.setOpaque(true); |
| } |
| |
| public Color getCurrentColor() { |
| return panel.getBackground(); |
| } |
| |
| public Component getTableCellRendererComponent( |
| JTable thisTable, Object value, boolean isSelected, boolean hasFocus, int row, |
| int column) { |
| if (value instanceof Color) { |
| panel.setBackground((Color) value); |
| } |
| if (border == null) { |
| border = BorderFactory.createMatteBorder(2, 2, 2, 2, table.getBackground()); |
| } |
| |
| panel.setBorder(border); |
| |
| return panel; |
| } |
| } |
| |
| class ExpressionTableCellRenderer implements TableCellRenderer { |
| JPanel panel = new JPanel(); |
| JLabel expressionLabel = new JLabel(); |
| JLabel iconLabel = new JLabel(); |
| Icon selectedIcon = new SelectedIcon(true); |
| Icon unselectedIcon = new SelectedIcon(false); |
| |
| ExpressionTableCellRenderer() { |
| panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); |
| panel.setOpaque(true); |
| panel.add(iconLabel); |
| panel.add(Box.createHorizontalStrut(5)); |
| panel.add(expressionLabel); |
| } |
| |
| void setToolTipText(String text) { |
| panel.setToolTipText(text); |
| } |
| |
| public Component getTableCellRendererComponent( |
| JTable thisTable, Object value, boolean isSelected, boolean hasFocus, int row, |
| int column) { |
| if (value == null) { |
| return panel; |
| } |
| |
| Vector v = tableModel.getDataVector(); |
| Vector r = (Vector) v.elementAt(row); |
| expressionLabel.setText(value.toString()); |
| |
| if (r.elementAt(1) instanceof Color) { |
| expressionLabel.setBackground((Color) r.elementAt(1)); |
| panel.setBackground((Color) r.elementAt(1)); |
| } |
| |
| if (r.elementAt(2) instanceof Color) { |
| expressionLabel.setForeground((Color) r.elementAt(2)); |
| panel.setForeground((Color) r.elementAt(2)); |
| } |
| |
| if (isSelected) { |
| iconLabel.setIcon(selectedIcon); |
| } else { |
| iconLabel.setIcon(unselectedIcon); |
| } |
| |
| return panel; |
| } |
| } |
| |
| class SelectedIcon implements Icon { |
| private boolean isSelected; |
| private int width = 9; |
| private int height = 18; |
| private int[] xPoints = new int[4]; |
| private int[] yPoints = new int[4]; |
| |
| public SelectedIcon(boolean isSelected) { |
| this.isSelected = isSelected; |
| xPoints[0] = 0; |
| yPoints[0] = -1; |
| xPoints[1] = 0; |
| yPoints[1] = height; |
| xPoints[2] = width; |
| yPoints[2] = height / 2; |
| xPoints[3] = width; |
| yPoints[3] = (height / 2) - 1; |
| } |
| |
| public int getIconHeight() { |
| return height; |
| } |
| |
| public int getIconWidth() { |
| return width; |
| } |
| |
| public void paintIcon(Component c, Graphics g, int x, int y) { |
| if (isSelected) { |
| int length = xPoints.length; |
| int[] newXPoints = new int[length]; |
| int[] newYPoints = new int[length]; |
| |
| for (int i = 0; i < length; i++) { |
| newXPoints[i] = xPoints[i] + x; |
| newYPoints[i] = yPoints[i] + y; |
| } |
| |
| g.setColor(Color.black); |
| |
| g.fillPolygon(newXPoints, newYPoints, length); |
| } |
| } |
| } |
| } |