Java/Swing Components/Data Binding Value Types

Материал из Java эксперт
Перейти к: навигация, поиск

Demonstrates how to bind different value types to Swing components

/*
 * Copyright (c) 2002-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *  o Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer. 
 *     
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *     
 *  o Neither the name of JGoodies Karsten Lentzsch nor the names of 
 *    its contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 *     
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
package com.jgoodies.binding.tutorial.basics;
import java.text.NumberFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.*;
import com.jgoodies.binding.PresentationModel;
import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.adapter.ruboBoxAdapter;
import com.jgoodies.binding.adapter.SingleListSelectionAdapter;
import com.jgoodies.binding.beans.Model;
import com.jgoodies.binding.extras.SpinnerAdapterFactory;
import com.jgoodies.binding.list.ArrayListModel;
import com.jgoodies.binding.list.ObservableList;
import com.jgoodies.binding.list.SelectionInList;
import com.jgoodies.binding.tutorial.Album;
import com.jgoodies.binding.tutorial.TutorialUtils;
import com.jgoodies.binding.value.ConverterFactory;
import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
/**
 * Demonstrates how to bind different value types to Swing components.
 * 
 * @author Karsten Lentzsch
 * @version $Revision: 1.7 $
 * 
 * @see com.jgoodies.binding.adapter.BasicComponentFactory
 * @see com.jgoodies.binding.adapter.Bindings
 */
public class ComponentsExample {
    // Holds an ExampleBean and vends ValueModels that adapt its properties.
    private final ExamplePresentationModel presentationModel;
    // Text Components
    private JTextField     textField;
    private JTextArea      textArea;
    private JPasswordField passwordField;
    private JLabel         textLabel;
    // Formatted Input
    private JFormattedTextField dateField;
    private JFormattedTextField integerField;
    private JFormattedTextField longField;
    // Lists
    private JComboBox comboBox;
    private JList     list;
    private JTable    table;
    // Choice
    private JRadioButton leftIntRadio;
    private JRadioButton centerIntRadio;
    private JRadioButton rightIntRadio;
    private JComboBox    alignmentIntCombo;
    private JRadioButton leftObjectRadio;
    private JRadioButton centerObjectRadio;
    private JRadioButton rightObjectRadio;
    private JComboBox    alignmentObjectCombo;
    // Misc
    private JCheckBox checkBox;
    private JSlider   slider;
    private JLabel    floatLabel;
    private JSpinner  spinner;
    
    // Launching **************************************************************
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
        } catch (Exception e) {
            // Likely PlasticXP is not in the class path; ignore.
        }
        JFrame frame = new JFrame();
        frame.setTitle("Binding Tutorial :: Components");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        ComponentsExample example = new ComponentsExample();
        JComponent panel = example.build();
        frame.getContentPane().add(panel);
        frame.pack();
        TutorialUtils.locateOnScreenCenter(frame);
        frame.setVisible(true);
    }
    
    // Instance Creation ******************************************************
    /**
     * Constructs the "Components" example on an instance of ExampleBean.
     */
    public ComponentsExample() {
        presentationModel = new ExamplePresentationModel(new ExampleBean());
    }
    
    // Component Creation and Initialization **********************************
    /**
     * Creates, binds and configures the UI components.<p>
     * 
     * If possible, the components are created using the BasicComponentFactory,
     * or the Bindings class.
     */
    private void initComponents() {
        // Text Components
        textField = BasicComponentFactory.createTextField(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_TEXT));
        textArea = BasicComponentFactory.createTextArea(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_TEXT));
        passwordField = BasicComponentFactory.createPasswordField(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_TEXT));
        textLabel = BasicComponentFactory.createLabel(presentationModel
                .getModel(ExampleBean.PROPERTYNAME_TEXT));
        // Formatted Input
        dateField = BasicComponentFactory.createDateField(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_DATE));
        integerField = BasicComponentFactory.createIntegerField(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_INT_VALUE));
        longField = BasicComponentFactory.createLongField(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_LONG_VALUE));
        // Choice
        ValueModel intChoiceModel = presentationModel.getModel(ExampleBean.PROPERTYNAME_INT_CHOICE);
        leftIntRadio = BasicComponentFactory.createRadioButton(
                intChoiceModel, ExampleBean.LEFT_INTEGER, "Left");
        centerIntRadio = BasicComponentFactory.createRadioButton(
                intChoiceModel, ExampleBean.CENTER_INTEGER, "Center");
        rightIntRadio = BasicComponentFactory.createRadioButton(
                intChoiceModel, ExampleBean.RIGHT_INTEGER, "Right");
        alignmentIntCombo = new JComboBox();
        alignmentIntCombo.setModel(
                new ComboBoxAdapter(ExampleBean.INTEGER_CHOICES, intChoiceModel));
        
        ValueModel objectChoiceModel = presentationModel.getModel(ExampleBean.PROPERTYNAME_OBJECT_CHOICE);
        leftObjectRadio = BasicComponentFactory.createRadioButton(
                objectChoiceModel, ExampleBean.LEFT, "Left");
        centerObjectRadio = BasicComponentFactory.createRadioButton(
                objectChoiceModel, ExampleBean.CENTER, "Center");
        rightObjectRadio = BasicComponentFactory.createRadioButton(
                objectChoiceModel, ExampleBean.RIGHT, "Right");
        alignmentObjectCombo = new JComboBox();
        alignmentObjectCombo.setModel(
                new ComboBoxAdapter(ExampleBean.OBJECT_CHOICES, objectChoiceModel));
        
      
        // Lists
        comboBox = BasicComponentFactory.createComboBox(
                presentationModel.getSelectionInList(),
                TutorialUtils.createAlbumListCellRenderer());
        
        list = BasicComponentFactory.createList(
                presentationModel.getSelectionInList(),
                TutorialUtils.createAlbumListCellRenderer());
        
        table = new JTable();
        table.setModel(TutorialUtils.createAlbumTableModel(
                presentationModel.getSelectionInList()));
        table.setSelectionModel(new SingleListSelectionAdapter(
                presentationModel.getSelectionInList().getSelectionIndexHolder()));
        
        // Misc
        checkBox = BasicComponentFactory.createCheckBox(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_BOOLEAN_VALUE),
                "available");
        
        ValueModel floatModel = presentationModel.getModel(ExampleBean.PROPERTYNAME_FLOAT_VALUE);
        slider = new JSlider();
        slider.setModel(new BoundedRangeAdapter(
                ConverterFactory.createFloatToIntegerConverter(floatModel, 100),
                0, 0, 100));
        floatLabel = BasicComponentFactory.createLabel(
                ConverterFactory.createStringConverter(
                        floatModel,
                        NumberFormat.getPercentInstance()));
        spinner = new JSpinner();
        spinner.setModel(SpinnerAdapterFactory.createNumberAdapter(
                presentationModel.getModel(ExampleBean.PROPERTYNAME_INT_LIMITED),
                0,
                100,
                5));
    }
    
    // Building ***************************************************************
    /**
     * Builds the pane.
     * 
     * @return the built panel
     */
    public JComponent build() {
        initComponents();
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.putClientProperty("jgoodies.noContentBorder", Boolean.TRUE);
        tabbedPane.addTab("Text",      buildTextPanel());
        tabbedPane.addTab("Formatted", buildFormattedPanel());
        tabbedPane.addTab("Choices",   buildChoicesPanel());
        tabbedPane.addTab("List",      buildListPanel());
        tabbedPane.addTab("Misc",      buildMiscPanel());
        return tabbedPane;
    }
    private JPanel buildTextPanel() {
        FormLayout layout = new FormLayout(
                "right:max(50dlu;pref), 3dlu, 50dlu",
                "p, 3dlu, p, 3dlu, p, 14dlu, 3dlu, p");
        layout.setRowGroups(new int[][]{{1, 3, 5}});
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addLabel("JTextField",          cc.xy  (1, 1));
        builder.add(textField,                  cc.xy  (3, 1));
        builder.addLabel("JPasswordField",      cc.xy  (1, 3));
        builder.add(passwordField,              cc.xy  (3, 3));
        builder.addLabel("JTextArea",           cc.xy  (1, 5));
        builder.add(new JScrollPane(textArea),  cc.xywh(3, 5, 1, 2));
        builder.addLabel("JLabel",              cc.xy  (1, 8));
        builder.add(textLabel,                  cc.xy  (3, 8));
        return builder.getPanel();
    }
    private JPanel buildFormattedPanel() {
        FormLayout layout = new FormLayout(
                "right:max(50dlu;pref), 3dlu, 50dlu", 
                "p, 3dlu, p, 3dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addLabel("Date",                cc.xy(1, 1));
        builder.add(dateField,                  cc.xy(3, 1));
        builder.addLabel("Integer",             cc.xy(1, 3));
        builder.add(integerField,               cc.xy(3, 3));
        builder.addLabel("Long",                cc.xy(1, 5));
        builder.add(longField,                  cc.xy(3, 5));
        return builder.getPanel();
    }
    
    private JPanel buildChoicesPanel() {
        FormLayout layout = new FormLayout(
                "right:max(50dlu;pref), 3dlu, p, 6dlu, p, 6dlu, p, 0:grow", 
                "p, 3dlu, p, 3dlu, p, 9dlu, p, 3dlu, p, 3dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addSeparator("Integer Choice",  cc.xyw(1,  1, 8));
        builder.addLabel("JRadioButton",        cc.xy (1,  3));
        builder.add(leftIntRadio,               cc.xy (3,  3));
        builder.add(centerIntRadio,             cc.xy (5,  3));
        builder.add(rightIntRadio,              cc.xy (7,  3));
        builder.addLabel("JComboBox",           cc.xy (1,  5));
        builder.add(alignmentIntCombo,          cc.xyw(3,  5, 3));
        
        builder.addSeparator("Object Choice",   cc.xyw(1,  7, 8));
        builder.addLabel("JRadioButton",        cc.xy (1,  9));
        builder.add(leftObjectRadio,            cc.xy (3,  9));
        builder.add(centerObjectRadio,          cc.xy (5,  9));
        builder.add(rightObjectRadio,           cc.xy (7,  9));
        builder.addLabel("JComboBox",           cc.xy (1, 11));
        builder.add(alignmentObjectCombo,       cc.xyw(3, 11, 3));
        return builder.getPanel();
    }
    
    private JPanel buildListPanel() {
        FormLayout layout = new FormLayout(
                "right:max(50dlu;pref), 3dlu, 150dlu", 
                "fill:60dlu, 6dlu, fill:60dlu, 6dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addLabel("JList",               cc.xy(1, 1, "right, top"));
        builder.add(new JScrollPane(list),      cc.xy(3, 1));
        builder.addLabel("JTable",              cc.xy(1, 3, "right, top"));
        builder.add(new JScrollPane(table),     cc.xy(3, 3));
        builder.addLabel("JComboBox",           cc.xy(1, 5));
        builder.add(comboBox,                   cc.xy(3, 5));
        return builder.getPanel();
    }
    
    private JPanel buildMiscPanel() {
        FormLayout layout = new FormLayout(
                "right:max(50dlu;pref), 3dlu, 50dlu, 9dlu, 50dlu", 
                "p, 3dlu, p, 3dlu, p");
        layout.setRowGroups(new int[][]{{1, 3, 5}});
        PanelBuilder builder = new PanelBuilder(layout);
        builder.setDefaultDialogBorder();
        CellConstraints cc = new CellConstraints();
        builder.addLabel("JCheckBox",           cc.xy(1, 1));
        builder.add(checkBox,                   cc.xy(3, 1));
        builder.addLabel("JSlider",             cc.xy(1, 3));
        builder.add(slider,                     cc.xy(3, 3));
        builder.add(floatLabel,                 cc.xy(5, 3));
        builder.addLabel("JSpinner",            cc.xy(1, 5));
        builder.add(spinner,                    cc.xy(3, 5));
        return builder.getPanel();
    }
    
    
    // Helper Code ************************************************************
    
    public static final class ExampleBean extends Model {
        // Names of the Bound Bean Properties *************************************
        public static final String PROPERTYNAME_BOOLEAN_VALUE  = "booleanValue";
        public static final String PROPERTYNAME_DATE           = "date";
        public static final String PROPERTYNAME_FLOAT_VALUE    = "floatValue";
        public static final String PROPERTYNAME_INT_CHOICE     = "intChoice";
        public static final String PROPERTYNAME_INT_LIMITED    = "intLimited";
        public static final String PROPERTYNAME_INT_VALUE      = "intValue";
        public static final String PROPERTYNAME_LIST_SELECTION = "listSelection";
        public static final String PROPERTYNAME_LONG_VALUE     = "longValue";
        public static final String PROPERTYNAME_OBJECT_CHOICE  = "objectChoice";
        public static final String PROPERTYNAME_TEXT           = "text";
        
        // Constants **************************************************************
        // An int based enumeration.
        public static final Integer LEFT_INTEGER   = new Integer(0);
        public static final Integer CENTER_INTEGER = new Integer(1);
        public static final Integer RIGHT_INTEGER  = new Integer(2);
               static final Integer[] INTEGER_CHOICES = 
            { LEFT_INTEGER, CENTER_INTEGER, RIGHT_INTEGER };
        // An object based enumeration (using an enum from the JGoodies Forms)
        public static final Object LEFT   = ColumnSpec.LEFT;
        public static final Object CENTER = ColumnSpec.CENTER;
        public static final Object RIGHT  = ColumnSpec.RIGHT;
               static final Object[] OBJECT_CHOICES = 
            { LEFT, CENTER, RIGHT };
               
               
        private static final int NO_DATE = -1;
        
        // Fields *****************************************************************
        private boolean booleanValue;
        private long  date;
        private float floatValue;
        private int intChoice;
        private int intLimited; // for a spinner
        private int intValue;
        private long longValue;
        private Object objectChoice;
        private String text;
        private ObservableList listModel;
        private Object listSelection;
        
        // Instance Creation ******************************************************
        
        public ExampleBean() {
            booleanValue = true;
            date = new GregorianCalendar(1967, 11, 5).getTime().getTime();
            floatValue = 0.5f;
            intChoice = LEFT_INTEGER.intValue();
            intLimited = 15;
            intValue = 42;
            longValue = 42L;
            objectChoice = LEFT;
            text = "Text";
            listModel = new ArrayListModel();
            listModel.addAll(Album.ALBUMS);
            listSelection = listModel.get(0);
        }
        
        // Accessors **************************************************************
        public boolean getBooleanValue() {
            return booleanValue;
        }
        public void setBooleanValue(boolean newBooleanValue) {
            boolean oldBooleanValue = getBooleanValue();
            booleanValue = newBooleanValue;
            firePropertyChange(PROPERTYNAME_BOOLEAN_VALUE, oldBooleanValue,
                    newBooleanValue);
        }
        
        public Date getDate() {
            return date == NO_DATE ? null : new Date(date);
        }
        public void setDate(Date newDate) {
            Date oldDate = getDate();
            date = newDate == null ? NO_DATE : newDate.getTime();
            firePropertyChange(PROPERTYNAME_DATE, oldDate, newDate);
        }

        public float getFloatValue() {
            return floatValue;
        }
        public void setFloatValue(float newFloatValue) {
            float oldFloatValue = getFloatValue();
            floatValue = newFloatValue;
            firePropertyChange(PROPERTYNAME_FLOAT_VALUE, oldFloatValue, newFloatValue);
        }
        
        public int getIntChoice() {
            return intChoice;
        }
        public void setIntChoice(int newIntChoice) {
            int oldIntChoice = getIntChoice();
            intChoice = newIntChoice;
            firePropertyChange(PROPERTYNAME_INT_CHOICE, oldIntChoice,
                    newIntChoice);
        }
        
        public int getIntLimited() {
            return intLimited;
        }
        public void setIntLimited(int newIntLimited) {
            int oldIntLimited = getIntLimited();
            intLimited = newIntLimited;
            firePropertyChange(PROPERTYNAME_INT_LIMITED, oldIntLimited, newIntLimited);
        }
        
        public int getIntValue() {
            return intValue;
        }
        public void setIntValue(int newIntValue) {
            int oldIntValue = getIntValue();
            intValue = newIntValue;
            firePropertyChange(PROPERTYNAME_INT_VALUE, oldIntValue, newIntValue);
        }
        
        public long getLongValue() {
            return longValue;
        }
        public void setLongValue(long newLongValue) {
            long oldLongValue = getLongValue();
            longValue = newLongValue;
            firePropertyChange(PROPERTYNAME_LONG_VALUE, oldLongValue,
                    newLongValue);
        }
        
        public Object getObjectChoice() {
            return objectChoice;
        }
        public void setObjectChoice(Object newObjectChoice) {
            Object oldObjectChoice = getObjectChoice();
            objectChoice = newObjectChoice;
            firePropertyChange(PROPERTYNAME_OBJECT_CHOICE, oldObjectChoice,
                    newObjectChoice);
        }
        
        
        public String getText() {
            return text;
        }
        public void setText(String newText) {
            String oldText = getText();
            text = newText;
            firePropertyChange(PROPERTYNAME_TEXT, oldText, newText);
        }
        
        
        public ListModel getListModel() {
            return listModel;
        }
        
        
        public Object getListSelection() {
            return listSelection;
        }
        
        public void setListSelection(Object newListSelection) {
            Object oldListSelection = getListSelection();
            listSelection = newListSelection;
            firePropertyChange(PROPERTYNAME_LIST_SELECTION, oldListSelection, newListSelection);
        }
    }
    
    
    // A custom PresentationModel that provides a SelectionInList
    // for the bean"s ListModel and the bean"s list selection.
    private static final class ExamplePresentationModel extends PresentationModel {
        
        /**
         * Holds the bean"s list model plus a selection.
         */
        private final SelectionInList selectionInList;
        
        // Instance Creation -----------------------------------------
        
        private ExamplePresentationModel(ExampleBean exampleBean) {
            super(exampleBean);
            selectionInList = new SelectionInList(
                    new ValueHolder(exampleBean.getListModel()),
                    getModel(ExampleBean.PROPERTYNAME_LIST_SELECTION));
        }
        
        
        // Custom Models ---------------------------------------------
        
        public SelectionInList getSelectionInList() {
            return selectionInList;
        }
        
    }
    
}