tvbrowser.ui.filter.dlgs.EditFilterDlg.java Source code

Java tutorial

Introduction

Here is the source code for tvbrowser.ui.filter.dlgs.EditFilterDlg.java

Source

/*
 * TV-Browser
 * Copyright (C) 04-2003 Martin Oberhauser (darras@users.sourceforge.net)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * CVS information:
 *  $RCSfile$
 *   $Source$
 *     $Date: 2010-10-30 12:44:07 +0200 (Sat, 30 Oct 2010) $
 *   $Author: bananeweizen $
 * $Revision: 6796 $
 */
package tvbrowser.ui.filter.dlgs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import org.apache.commons.lang.StringUtils;

import tvbrowser.core.Settings;
import tvbrowser.core.filters.FilterComponent;
import tvbrowser.core.filters.FilterComponentList;
import tvbrowser.core.filters.FilterList;
import tvbrowser.core.filters.ParserException;
import tvbrowser.core.filters.UserFilter;
import util.ui.Localizer;
import util.ui.UiUtilities;
import util.ui.WindowClosingIf;

import com.jgoodies.forms.builder.ButtonBarBuilder2;
import com.jgoodies.forms.factories.DefaultComponentFactory;

public class EditFilterDlg extends JDialog
        implements ActionListener, DocumentListener, CaretListener, WindowClosingIf {

    private static final util.ui.Localizer mLocalizer = util.ui.Localizer.getLocalizerFor(EditFilterDlg.class);

    private static final util.ui.Localizer mFilterLocalizer = util.ui.Localizer.getLocalizerFor(UserFilter.class);

    private JButton mNewBtn, mEditBtn, mRemoveBtn, mOkBtn, mCancelBtn;

    private JFrame mParent;

    private JTable mRuleTableBox;

    private JTextField mFilterNameTF, mFilterRuleTF;

    private FilterTableModel mComponentTableModel;

    private UserFilter mFilter = null;

    private JLabel mFilterRuleErrorLb, mColLb;

    private String mFilterName = null;

    private FilterList mFilterList;

    public EditFilterDlg(JFrame parent, FilterList filterList, UserFilter filter) {

        super(parent, true);

        UiUtilities.registerForClosing(this);

        mFilterList = filterList;
        mParent = parent;
        mFilter = filter;

        JPanel contentPane = (JPanel) getContentPane();
        contentPane.setLayout(new BorderLayout(7, 7));
        contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        if (filter == null) {
            setTitle(mLocalizer.msg("titleNew", "Create filter"));
        } else {
            setTitle(mLocalizer.msg("titleEdit", "Edit filter {0}", filter.toString()));
            mFilterName = filter.toString();
        }

        JPanel northPanel = new JPanel();
        northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS));

        mFilterNameTF = new JTextField(new PlainDocument() {

            public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
                str = str.replaceAll("[\\p{Punct}&&[^_]]", "_");
                super.insertString(offset, str, a);
            }
        }, "", 30);

        mFilterNameTF.getDocument().addDocumentListener(this);
        JPanel panel = new JPanel(new BorderLayout(7, 7));
        panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));
        panel.add(new JLabel(mLocalizer.msg("filterName", "Filter name:")), BorderLayout.WEST);
        JPanel panel1 = new JPanel(new BorderLayout());
        panel1.add(mFilterNameTF, BorderLayout.WEST);
        panel.add(panel1, BorderLayout.CENTER);
        northPanel.add(panel);

        mFilterRuleTF = new JTextField();
        mFilterRuleTF.getDocument().addDocumentListener(this);
        mFilterRuleTF.addCaretListener(this);
        panel = new JPanel(new BorderLayout(7, 7));
        panel1 = new JPanel(new BorderLayout());
        panel.add(new JLabel(mLocalizer.msg("ruleString", "Filter rule:")), BorderLayout.WEST);
        JLabel exampleLb = new JLabel(
                mLocalizer.msg("ruleExample", "example: component1 or (component2 and not component3)"));
        Font f = exampleLb.getFont();
        exampleLb.setFont(new Font(f.getName(), Font.ITALIC | Font.PLAIN, f.getSize()));
        panel1.add(exampleLb, BorderLayout.WEST);
        panel.add(panel1, BorderLayout.CENTER);
        northPanel.add(panel);
        northPanel.add(mFilterRuleTF);
        mFilterRuleErrorLb = new JLabel();
        mFilterRuleErrorLb.setForeground(Color.red);
        panel = new JPanel(new BorderLayout(7, 7));
        panel.add(mFilterRuleErrorLb, BorderLayout.WEST);
        mColLb = new JLabel("0");
        panel.add(mColLb, BorderLayout.EAST);
        northPanel.add(panel);

        JPanel filterComponentsPanel = new JPanel(new BorderLayout(7, 7));
        filterComponentsPanel.add(DefaultComponentFactory.getInstance().createSeparator(
                mLocalizer.msg("componentsTitle", "Available filter components:")), BorderLayout.NORTH);
        JPanel btnPanel = new JPanel(new BorderLayout());
        panel1 = new JPanel(new GridLayout(0, 1, 0, 7));

        mNewBtn = new JButton(mLocalizer.msg("newButton", "new"));
        mEditBtn = new JButton(Localizer.getLocalization(Localizer.I18N_EDIT));
        mRemoveBtn = new JButton(Localizer.getLocalization(Localizer.I18N_DELETE));

        mNewBtn.addActionListener(this);
        mEditBtn.addActionListener(this);
        mRemoveBtn.addActionListener(this);

        panel1.add(mNewBtn);
        panel1.add(mEditBtn);
        panel1.add(mRemoveBtn);

        btnPanel.add(panel1, BorderLayout.NORTH);

        mComponentTableModel = new FilterTableModel();

        mRuleTableBox = new JTable(mComponentTableModel);
        mRuleTableBox.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                updateBtns();
            }
        });

        mRuleTableBox.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() >= 2) {
                    int row = mRuleTableBox.rowAtPoint(e.getPoint());

                    if (mRuleTableBox.getSelectedRow() == row && mEditBtn.isEnabled()) {
                        actionPerformed(new ActionEvent(mEditBtn, ActionEvent.ACTION_PERFORMED,
                                mEditBtn.getActionCommand()));
                    }
                }
            }
        });

        mRuleTableBox.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        mRuleTableBox.setShowGrid(false);
        mRuleTableBox.setShowVerticalLines(true);
        mRuleTableBox.getColumnModel().getColumn(0).setPreferredWidth(125);
        mRuleTableBox.getColumnModel().getColumn(1).setPreferredWidth(320);
        //    mRuleTableBox.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        // Dispatchs the KeyEvent to the RootPane for Closing the Dialog.
        // Needed for Java 1.4.
        mRuleTableBox.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    mRuleTableBox.getRootPane().dispatchEvent(e);
                }
            }
        });

        JPanel ruleListBoxPanel = new JPanel(new BorderLayout());
        ruleListBoxPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));
        ruleListBoxPanel.add(new JScrollPane(mRuleTableBox), BorderLayout.CENTER);

        filterComponentsPanel.add(btnPanel, BorderLayout.EAST);
        filterComponentsPanel.add(ruleListBoxPanel, BorderLayout.CENTER);

        ButtonBarBuilder2 bottomBar = Utilities.createFilterButtonBar();

        mOkBtn = new JButton(Localizer.getLocalization(Localizer.I18N_OK));
        mOkBtn.addActionListener(this);
        getRootPane().setDefaultButton(mOkBtn);

        mCancelBtn = new JButton(Localizer.getLocalization(Localizer.I18N_CANCEL));
        mCancelBtn.addActionListener(this);

        bottomBar.addButton(new JButton[] { mOkBtn, mCancelBtn });

        contentPane.add(northPanel, BorderLayout.NORTH);
        contentPane.add(filterComponentsPanel, BorderLayout.CENTER);
        contentPane.add(bottomBar.getPanel(), BorderLayout.SOUTH);

        if (mFilter != null) {
            mFilterNameTF.setText(mFilter.toString());
            mFilterRuleTF.setText(mFilter.getRule());
        }

        FilterComponent[] fc = FilterComponentList.getInstance().getAvailableFilterComponents();

        Arrays.sort(fc, new FilterComponent.NameComparator());

        for (FilterComponent element : fc) {
            mComponentTableModel.addElement(element);
        }

        updateBtns();

        Settings.layoutWindow("editFilterDlg", this, new Dimension(600, 300));
        setVisible(true);
    }

    private void updateBtns() {
        if (mRuleTableBox == null) {
            return;
        }
        Object item = mRuleTableBox.getSelectedRows();
        final boolean enabled = item != null;
        mEditBtn.setEnabled(enabled);
        mRemoveBtn.setEnabled(enabled);

        boolean validRule = true;
        try {
            UserFilter.testTokenTree(mFilterRuleTF.getText());
            mFilterRuleErrorLb.setText("");
        } catch (ParserException e) {
            mFilterRuleErrorLb.setText(e.getMessage());
            validRule = false;
        }

        mOkBtn.setEnabled(StringUtils.isNotBlank(mFilterNameTF.getText()) && mComponentTableModel.getRowCount() > 0
                && validRule);
    }

    public void actionPerformed(ActionEvent e) {

        Object o = e.getSource();
        if (o == mNewBtn) {
            EditFilterComponentDlg dlg = new EditFilterComponentDlg(mParent);
            FilterComponent rule = dlg.getFilterComponent();
            if (rule != null) {
                mComponentTableModel.addElement(rule);
                tvbrowser.core.filters.FilterComponentList.getInstance().add(rule);
                String text = mFilterRuleTF.getText();
                if (text.length() > 0) {
                    text += " " + mFilterLocalizer.msg("or", "or") + " ";
                }
                text += rule.getName();
                mFilterRuleTF.setText(text);

            }
        } else if (o == mEditBtn) {
            int inx = mRuleTableBox.getSelectedRow();

            if (inx == -1) {
                return;
            }

            FilterComponent rule = mComponentTableModel.getElement(inx);
            FilterComponentList.getInstance().remove(rule.getName());
            mComponentTableModel.removeElement(rule);
            EditFilterComponentDlg dlg = new EditFilterComponentDlg(mParent, rule);
            FilterComponent newRule = dlg.getFilterComponent();
            if (newRule == null) {
                newRule = rule;
            }
            FilterComponentList.getInstance().add(newRule);
            mComponentTableModel.addElement(newRule);
            // mRuleListBox.repaint();
            updateBtns();

        } else if (o == mRuleTableBox) {
            updateBtns();
        } else if (o == mRemoveBtn) {
            boolean allowRemove = true;
            UserFilter[] userFilterArr = mFilterList.getUserFilterArr();
            FilterComponent fc = mComponentTableModel.getElement(mRuleTableBox.getSelectedRow());

            // Create the Filter based on the new Rule and check if the FC exists
            // there
            UserFilter testFilter = new UserFilter("test");

            try {
                testFilter.setRule(mFilterRuleTF.getText());

                if (testFilter.containsRuleComponent(fc.getName())) {
                    allowRemove = false;
                    JOptionPane.showMessageDialog(this,
                            mLocalizer.msg("usedByAnotherFilter",
                                    "This filter component is used by filter '{0}'\nRemove the filter first.",
                                    mFilterNameTF.getText()));
                }
            } catch (Exception ex) {
                // Filter creation failed, assume the old one is correct
                if ((mFilter != null) && (mFilter.containsRuleComponent(fc.getName()))) {
                    allowRemove = false;
                    JOptionPane.showMessageDialog(this,
                            mLocalizer.msg("usedByAnotherFilter",
                                    "This filter component is used by filter '{0}'\nRemove the filter first.",
                                    mFilterNameTF.getText()));
                }
            }

            for (int i = 0; i < userFilterArr.length && allowRemove; i++) {
                if ((userFilterArr[i] != mFilter) && userFilterArr[i].containsRuleComponent(fc.getName())) {
                    allowRemove = false;
                    JOptionPane.showMessageDialog(this,
                            mLocalizer.msg("usedByAnotherFilter",
                                    "This filter component is used by filter '{0}'\nRemove the filter first.",
                                    userFilterArr[i].toString()));
                }
            }
            if (allowRemove) {
                FilterComponentList.getInstance().remove(fc.getName());
                mComponentTableModel.removeElement(mRuleTableBox.getSelectedRow());
                updateBtns();
            }

        } else if (o == mOkBtn) {
            String filterName = mFilterNameTF.getText();
            if (!filterName.equalsIgnoreCase(mFilterName) && mFilterList.containsFilter(filterName)) {
                JOptionPane.showMessageDialog(this,
                        mLocalizer.msg("alreadyExists", "Filter '{0}' already exists.", filterName));
            } else {
                if (mFilter == null) {
                    mFilter = new UserFilter(mFilterNameTF.getText());
                } else {
                    mFilter.setName(mFilterNameTF.getText());
                }

                try {
                    mFilter.setRule(mFilterRuleTF.getText());
                    FilterComponentList.getInstance().store();
                    setVisible(false);
                } catch (ParserException exc) {
                    JOptionPane.showMessageDialog(this,
                            mLocalizer.msg("invalidRule", "Invalid rule: ") + exc.getMessage());
                }
            }

        } else if (o == mCancelBtn) {
            setVisible(false);
        }

    }

    public UserFilter getUserFilter() {
        return mFilter;
    }

    public void changedUpdate(DocumentEvent e) {
        updateBtns();
    }

    public void insertUpdate(DocumentEvent e) {
        updateBtns();
    }

    public void removeUpdate(DocumentEvent e) {
        updateBtns();
    }

    public void caretUpdate(javax.swing.event.CaretEvent e) {
        mColLb.setText("pos: " + mFilterRuleTF.getCaretPosition());
    }

    private static class FilterTableModel extends AbstractTableModel {

        private Vector<FilterComponent> dataVector;

        public FilterTableModel() {
            dataVector = new Vector<FilterComponent>();
        }

        public int getRowCount() {
            return dataVector.size();
        }

        public int getColumnCount() {
            return 2;
        }

        public String getColumnName(int columnIndex) {
            if (columnIndex == 0) {
                return mLocalizer.msg("filtername", "Filtername");
            } else if (columnIndex == 1) {
                return mLocalizer.msg("description", "Description");
            }
            return "?";
        }

        public Class<?> getColumnClass(int columnIndex) {
            return String.class;
        }

        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            Object row = dataVector.get(rowIndex);
            if (row instanceof FilterComponent) {
                FilterComponent comp = (FilterComponent) row;

                if (columnIndex == 0) {
                    return comp.getName();
                } else if (columnIndex == 1) {
                    return comp.getDescription();
                }

            }
            return "?";
        }

        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

        }

        public void addElement(FilterComponent fComp) {
            dataVector.add(fComp);
            fireTableRowsInserted(getRowCount(), getRowCount());
        }

        public FilterComponent getElement(int row) {
            if (row < 0 || row >= getRowCount()) {
                return null;
            }
            return dataVector.get(row);
        }

        public void removeElement(int row) {
            if (row < 0 || row >= getRowCount()) {
                return;
            }
            dataVector.remove(row);
            fireTableRowsDeleted(row, row);
        }

        public void removeElement(FilterComponent fComp) {
            if (fComp == null) {
                return;
            }
            if (dataVector.remove(fComp)) {
                fireTableDataChanged();
            }
        }

    }

    public void close() {
        setVisible(false);
    }

}