All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lyonesgamer.propertygrid.properties.BooleanProperty Maven / Gradle / Ivy

The newest version!
package com.lyonesgamer.propertygrid.properties;

import com.lyonesgamer.propertygrid.PGProperty;

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.*;
import java.util.List;

/**
 * A property that represents an on/off state.
 *
 * @author Tristan Patch
 * @since 1.0
 */
public class BooleanProperty extends PGProperty {

    /**
     * The value of the property.
     */
    protected boolean value;

    /**
     * If true, uses a combo box; otherwise, uses a checkbox.
     */
    protected boolean useComboBox;

    /**
     * The editor to use for combo editing.
     */
    protected final BooleanComboEditor comboEditor = new BooleanComboEditor();

    /**
     * The check box editor to use.
     */
    protected final BooleanCheckEditor checkEditor = new BooleanCheckEditor();

    /**
     * The renderer to use if using a combo box.
     */
    protected final BooleanComboRenderer comboRenderer = new BooleanComboRenderer();

    /**
     * The renderer to use if using a check box.
     */
    protected final BooleanCheckRenderer checkRenderer = new BooleanCheckRenderer();

    /**
     * The words to use for true and false in rendering.
     */
    public static final Map names = new HashMap<>();

    static {
        names.put(true, "True");
        names.put(false, "False");
    }

    public BooleanProperty(String name, boolean value) {
        super(name);

        this.value = value;
    }

    /**
     * The type of component used to render. If true, uses a combo box. If false, uses a check box.
     * @return True for combo box, false for check box.
     */
    public boolean isComboBox() {
        return useComboBox;
    }

    /**
     * Sets the type of component used to render. If true, uses a combo box. If false, uses a check box.
     * @param comboBox True for combo box, false for check box.
     */
    public void setComponentType(boolean comboBox) {
        this.useComboBox = comboBox;
    }

    /**
     * Does nothing. Can be overridden by subclasses.
     *
     * @see com.lyonesgamer.propertygrid.PGProperty#doAfterAdded()
     */
    @Override
    protected void doAfterAdded() {}

    /**
     * Should validate potential values of this property. In reality, all booleans are valid.
     *
     * @param value The value to be validated.
     * @return True because there are no invalid booleans.
     */
    @Override
    public boolean onValidateValue(Boolean value) {
        return true;
    }

    /**
     * Converts the value to a boolean using {@link Boolean#booleanValue()}, then sets it.
     * @param value The value to set to.
     */
    @Override
    public void onSetValue(Boolean value) {
        if (parent != null)
            parent.firePropertyChangeEvent(this, value);
        this.value = value;
    }

    /**
     * Uses {@link Boolean#parseBoolean(String)} to convert the value to a string. If this fails, attempts to read it as
     * a number; values of 0 are false and all others are true.
     *
     * @param value The string to attempt to set from.
     */
    @Override
    public void setValueFromString(String value) {
        try {
            setValue(Boolean.parseBoolean(value));
        } catch (NumberFormatException e) {
            setValue(Integer.parseInt(value) != 0);
        }
    }

    /**
     * Converts 0 to a value of false and all others to true.
     *
     * @param value The int to set this value from.
     */
    @Override
    public void setValueFromLong(long value) {
        setValue(value != 0);
    }

    @Override
    public Boolean getValue() {
        return value;
    }

    /**
     * Converts the string to a boolean based on loose rules for "truthy" values.
     *
     * @param value The value to convert to a value type of this property.
     * @return The parsed value as a boolean.
     */
    @Override
    public Boolean stringToValue(String value) {
        try {
            return Boolean.parseBoolean(value);
        } catch (NumberFormatException e) {
            try {
                return Integer.parseInt(value) != 0;
            } catch (NumberFormatException ex) {
                return !value.isEmpty();
            }
        }
    }

    /**
     * Converts the int to a boolean value.
     *
     * @param value The value to convert to a value type of this property.
     * @return False if the number is 0, or true otherwise.
     */
    @Override
    public Boolean longToValue(long value) {
        return value != 0;
    }

    /**
     * Converts the value to a string.
     *
     * @param value The value to convert.
     * @return The localized names for "true" and "false", as set by
     * {@link com.lyonesgamer.propertygrid.JPropertyGrid#setBooleanNames(String, String)}, or "true"/false" if not set.
     */
    @Override
    public String valueToString(Boolean value) {
        return names.get(value);
    }

    @Override
    public PGCellEditor getEditor() {
       if (useComboBox)
           return comboEditor;
       else
           return checkEditor;
    }

    @Override
    public PGCellRenderer getRenderer() {
        if (useComboBox)
            return comboRenderer;
        else
            return checkRenderer;
    }

    protected class BooleanComboEditor extends JComboBox implements PGCellEditor {

        //No need to use an EventListenerList if we only have one listener type
        protected final List listeners = new ArrayList<>();
        protected final Set listenersToRemove = new HashSet<>();

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            this.setRenderer(new BooleanRenderer());
            this.addItem(true);
            this.addItem(false);
            this.addActionListener(this);
            return this;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            onSetValue((Boolean)this.getSelectedItem());
        }

        @Override
        public Object getCellEditorValue() {
            return valueToString(getValue());
        }

        @Override
        public boolean isCellEditable(EventObject anEvent) {
            return !disabled;
        }

        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean stopCellEditing() {
            fireEditingStopped();
            return true;
        }

        @Override
        public void cancelCellEditing() {
            fireEditingCancelled();
        }

        public void fireEditingCancelled() {
            ChangeEvent event = new ChangeEvent(this);

            for (CellEditorListener l : listeners)
                l.editingCanceled(event);

            doClearListeners();
        }

        public void fireEditingStopped() {
            ChangeEvent event = new ChangeEvent(this);

            for (CellEditorListener l : listeners)
                l.editingStopped(event);

            doClearListeners();
        }

        @Override
        public void addCellEditorListener(CellEditorListener l) {
            listeners.add(l);
        }

        @Override
        public void removeCellEditorListener(CellEditorListener l) {
            listenersToRemove.add(l);
        }

        protected void doClearListeners() {
            listeners.removeAll(listenersToRemove);
            listenersToRemove.clear();
        }

        public class BooleanRenderer extends JLabel implements ListCellRenderer {
            @Override
            public Component getListCellRendererComponent(JList list, Boolean value, int index, boolean isSelected, boolean cellHasFocus) {
                this.setText(names.get(value));
                return this;
            }
        }
    }

    protected class BooleanCheckEditor extends JCheckBox implements PGCellEditor {

        //No need to use an EventListenerList if we only have one listener type
        protected final List listeners = new ArrayList<>();

        protected final Set listenersToRemove = new HashSet<>();

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            this.setSelected(getValue());
            return this;
        }

        @Override
        public Object getCellEditorValue() {
            return getValue();
        }

        @Override
        public boolean isCellEditable(EventObject anEvent) {
            return !disabled;
        }

        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean stopCellEditing() {
            fireEditingStopped();

            onSetValue(this.isSelected());
            return true;
        }

        @Override
        public void cancelCellEditing() {
            fireEditingCancelled();
        }

        public void fireEditingCancelled() {
            ChangeEvent event = new ChangeEvent(this);

            for (CellEditorListener l : listeners)
                l.editingCanceled(event);

            doClearListeners();
        }

        public void fireEditingStopped() {
            ChangeEvent event = new ChangeEvent(this);

            for (CellEditorListener l : listeners)
                l.editingStopped(event);

            doClearListeners();
        }

        @Override
        public void addCellEditorListener(CellEditorListener l) {
            listeners.add(l);
        }

        @Override
        public void removeCellEditorListener(CellEditorListener l) {
            listenersToRemove.add(l);
        }

        protected void doClearListeners() {
            listeners.removeAll(listenersToRemove);
            listenersToRemove.clear();
        }
    }

    protected class BooleanComboRenderer extends JLabel implements PGCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setText(valueToString(getValue()));
            setToolTipText(helpString);
            return this;
        }
    }

    protected class BooleanCheckRenderer extends JCheckBox implements PGCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setSelected(getValue());
            setToolTipText(helpString);
            return this;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy