cz.lidinsky.editor.TableCellEditor.java Source code

Java tutorial

Introduction

Here is the source code for cz.lidinsky.editor.TableCellEditor.java

Source

package cz.lidinsky.editor;

/*
 *  Copyright 2013, 2014, 2015 Jiri Lidinsky
 *
 *  This file is part of control4j.
 *
 *  control4j 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, version 3.
 *
 *  control4j 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 control4j.  If not, see <http://www.gnu.org/licenses/>.
 */

import cz.lidinsky.tools.reflect.Setter;
import cz.lidinsky.tools.reflect.ObjectMapDecorator;
import cz.lidinsky.tools.reflect.ObjectMapUtils;

import org.apache.commons.collections4.PredicateUtils;

import java.lang.reflect.Method;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
//import javax.swing.table.TableCellEditor;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JComboBox;
import javax.swing.JCheckBox;
import javax.swing.Icon;
import javax.swing.JList;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.TreePath;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import control4j.gui.Changer;

/**
 *  Choose and return appropriate edit component, for property table.
 *  The decision is based mainly on the datatype of the edited value.
 *  But may depend even on the class to which the property belongs to.
 */
public class TableCellEditor extends AbstractCellEditor implements javax.swing.table.TableCellEditor,
        ActionListener, TreeSelectionListener, java.awt.event.FocusListener {

    private Color currentColor;
    private JButton button;
    private JColorChooser colorChooser;
    private JDialog dialog;
    private JTextField textField;
    private JComboBox comboBox;
    private JCheckBox checkBox;
    private int type;
    private final static int TEXT = 0;
    private final static int COLOR = 1;
    private final static int COMBO = 2;
    private final static int CHECK = 3;
    private Class valueClass;
    private Object selected;

    /**
     *  Initialize all of the components
     */
    public TableCellEditor() {
        // color chooser
        button = new JButton();
        button.setActionCommand("edit");
        button.addActionListener(this);
        button.setBorderPainted(false);
        button.addFocusListener(this);
        colorChooser = new JColorChooser();
        colorChooser.addChooserPanel(new AliasChooser());
        colorChooser.addFocusListener(this);
        dialog = JColorChooser.createDialog(button, "Pick a Color", true, colorChooser, this, null);
        // text editor
        textField = new JTextField();
        textField.addFocusListener(this);
        // combo chooser
        comboBox = new JComboBox();
        comboBox.addFocusListener(this);
        // check box
        checkBox = new JCheckBox();
        checkBox.addFocusListener(this);
    }

    /**
     *  Only for color chooser
     */
    public void actionPerformed(ActionEvent e) {
        if ("edit".equals(e.getActionCommand())) {
            button.setBackground(currentColor);
            colorChooser.setColor(currentColor);
            dialog.setVisible(true);
            fireEditingStopped();
        } else
            currentColor = colorChooser.getColor();
    }

    /**
     *  Returns new value
     */
    public Object getCellEditorValue() {
        if (type == TEXT) {
            String text = textField.getText();
            if (String.class.isAssignableFrom(valueClass))
                return text;
            if (double.class.isAssignableFrom(valueClass))
                return Double.parseDouble(text);
            if (int.class.isAssignableFrom(valueClass))
                return Integer.parseInt(text);
            return text;
        } else if (type == COLOR)
            return currentColor;
        else if (type == CHECK)
            return checkBox.isSelected();
        else
            return comboBox.getSelectedItem();
    }

    /**
     *  Returnes appropriate component based on the value datatype.
     */
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
            int column) {
        KeyValueTableModel tableModel = (KeyValueTableModel) table.getModel();
        valueClass = tableModel.getCellClass(row, column);
        if (Color.class.isAssignableFrom(valueClass)) {
            type = COLOR;
            currentColor = (Color) value;
            return button;
        } else if (selected instanceof Changer && ((String) table.getValueAt(row, 0)).equals("Property")) {
            type = COMBO;
            // get appropriate object
            Changer changer = (Changer) selected;
            // get parent of the object
            Object parent = changer.getParent();
            // get list of appropriate methods
            fillComboBox(parent, changer.getPropertyClass());
            // create component
            // return it
            return comboBox;
        } else if (Method.class.isAssignableFrom(valueClass) && selected instanceof Changer) {
            type = COMBO;
            // get appropriate object
            Changer changer = (Changer) selected;
            // get parent of the object
            Object parent = changer.getParent();
            // get list of appropriate methods
            fillComboBox(parent, changer.getPropertyClass());
            // create component
            // return it
            return comboBox;
        } else if (valueClass == boolean.class) {
            type = CHECK;
            checkBox.setSelected(((Boolean) value).booleanValue());
            return checkBox;
        } else {
            type = TEXT;
            if (value == null)
                value = "";
            textField.setText(value.toString());
            return textField;
        }
    }

    /**
     *  It fills combo box for a chenger property. It fills the keys
     *  of the parent component.
     *
     *  @param object
     *             a parent object of the changer
     *
     *  @param _class
     *             a data type
     */
    private void fillComboBox(Object object, Class _class) {
        // initialize object map
        ObjectMapDecorator<Object> map = new ObjectMapDecorator<Object>(Object.class)
                .setGetterFilter(PredicateUtils.falsePredicate())
                .setSetterFilter(PredicateUtils.allPredicate(ObjectMapUtils.hasAnnotationPredicate(Setter.class),
                        ObjectMapUtils.getSetterDataTypeCheckPredicate(_class)))
                .setSetterKeyTransformer(ObjectMapUtils.getSetterKeyTransformer());
        map.setDecorated(object);
        // fill in the keys
        comboBox.removeAllItems();
        for (String key : map.keySet()) {
            comboBox.addItem(key);
        }
    }

    public void valueChanged(TreeSelectionEvent e) {
        TreePath selectedPath = e.getNewLeadSelectionPath();
        if (selectedPath != null)
            selected = selectedPath.getLastPathComponent();
        else
            selected = null;
    }

    @Override
    protected void fireEditingCanceled() {
        super.fireEditingCanceled();
    }

    public void focusGained(java.awt.event.FocusEvent e) {
    }

    public void focusLost(java.awt.event.FocusEvent e) {
        if (!e.isTemporary()) {
            if (!(e.getOppositeComponent() instanceof JTable)) {
                cancelCellEditing();
            }
        }
    }

    /**
     *
     */
    private class AliasChooser extends AbstractColorChooserPanel
            implements javax.swing.event.ListSelectionListener {

        protected void buildChooser() {
            JList list = new JList(ColorAliases.getAliases());
            list.addListSelectionListener(this);
            add(list);
        }

        public String getDisplayName() {
            return "Color class";
        }

        public Icon getLargeDisplayIcon() {
            return null;
        }

        public Icon getSmallDisplayIcon() {
            return null;
        }

        public void updateChooser() {
        }

        public void valueChanged(javax.swing.event.ListSelectionEvent e) {
            String alias = (String) ((JList) e.getSource()).getSelectedValue();
            javax.swing.colorchooser.ColorSelectionModel model = getColorSelectionModel();
            model.setSelectedColor(control4j.gui.Color.getColor(alias));
        }

    }
}