/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 3 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, see http://www.gnu.org/licenses/ */ package com.bc.ceres.swing.binding; import com.bc.ceres.binding.PropertyContainer; import com.bc.ceres.binding.ValueRange; import com.bc.ceres.binding.ValueSet; import com.bc.ceres.binding.Validator; import com.bc.ceres.binding.Property; import com.bc.ceres.binding.ValidationException; import com.bc.ceres.swing.binding.BindingContext; import com.bc.ceres.swing.binding.BindingProblem; import com.bc.ceres.swing.binding.BindingProblemListener; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.WindowConstants; import javax.swing.DefaultComboBoxModel; import javax.swing.border.EmptyBorder; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; public class BindingContextUI { String name; int age; double height; String eyeColor; Gender gender; String country; boolean healthy; JPanel controlPanel; BindingContext bindingContext; enum Gender { male, female } public BindingContextUI() { name = "Urte"; age = 20; height = 1.50; eyeColor = "brown"; gender = Gender.female; country = "Germany"; healthy = true; final PropertyContainer vc = PropertyContainer.createObjectBacked(this); vc.getProperty("name").getDescriptor().setNotEmpty(true); vc.getProperty("age").getDescriptor().setValueRange(new ValueRange(1, 150)); vc.getProperty("height").getDescriptor().setValueRange(new ValueRange(0.5, 2.5)); vc.getProperty("gender").getDescriptor().setValueSet(new ValueSet(new Object[]{Gender.female, Gender.male})); vc.getProperty("eyeColor").getDescriptor().setNotEmpty(true); vc.getProperty("eyeColor").getDescriptor().setValidator(new LettersOnlyValidator()); vc.getProperty("country").getDescriptor().setValueSet(new ValueSet(new Object[]{"France", "Italy", "Spain", "Germany", "United Kingdom", "United States"})); bindingContext = new BindingContext(vc); bindingContext.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { System.out.println(this + ": '" + evt.getPropertyName() + "' changed from '" + evt.getOldValue() + "' to '" + evt.getNewValue() + "'"); } }); bindingContext.addProblemListener(new BindingProblemListener() { @Override public void problemReported(BindingProblem newProblem, BindingProblem oldProblem) { System.out.println("problemReported: newProblem = " + newProblem); System.out.println(" oldProblem = " + oldProblem); } @Override public void problemCleared(BindingProblem oldProblem) { System.out.println("problemCleared: oldProblem = " + oldProblem); } }); bindingContext.bind("name", new JTextField(16)); bindingContext.bind("age", new JTextField(4)); bindingContext.bind("height", new JTextArea(1, 7)); final JComboBox comboBox = new JComboBox(new DefaultComboBoxModel(new String[]{"brown", "blue", "green"})); comboBox.setEditable(true); bindingContext.bind("eyeColor", comboBox); final JRadioButton r1 = new JRadioButton("Female"); final JRadioButton r2 = new JRadioButton("Male"); final ButtonGroup bg = new ButtonGroup(); bg.add(r1); bg.add(r2); bindingContext.bind("gender", bg); bindingContext.bind("country", new JComboBox()); bindingContext.bind("healthy", new JCheckBox("Yes, I am not ill")); final GridBagConstraints gbc = new GridBagConstraints(); controlPanel = new JPanel(new GridBagLayout()); gbc.anchor = GridBagConstraints.BASELINE; gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridy = 0; gbc.gridx = 0; controlPanel.add(new JLabel("Name: "), gbc); gbc.gridx = 1; controlPanel.add(getPrimaryComponent(bindingContext, "name"), gbc); gbc.gridy++; gbc.gridx = 0; controlPanel.add(r1, gbc); gbc.gridx = 1; controlPanel.add(r2, gbc); gbc.gridy++; gbc.gridx = 0; controlPanel.add(new JLabel("Age: "), gbc); gbc.gridx = 1; controlPanel.add(getPrimaryComponent(bindingContext, "age"), gbc); gbc.gridy++; gbc.gridx = 0; controlPanel.add(new JLabel("Height: "), gbc); gbc.gridx = 1; controlPanel.add(getPrimaryComponent(bindingContext, "height"), gbc); gbc.gridy++; gbc.gridx = 0; controlPanel.add(new JLabel("Eye colour: "), gbc); gbc.gridx = 1; controlPanel.add(getPrimaryComponent(bindingContext, "eyeColor"), gbc); gbc.gridy++; gbc.gridx = 0; controlPanel.add(new JLabel("Country: "), gbc); gbc.gridx = 1; controlPanel.add(getPrimaryComponent(bindingContext, "country"), gbc); gbc.gridy++; gbc.gridx = 0; gbc.gridwidth = 2; controlPanel.add(getPrimaryComponent(bindingContext, "healthy"), gbc); } private static JComponent getPrimaryComponent(BindingContext ctx, String s) { return ctx.getBinding(s).getComponents()[0]; } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { // ok } final JFrame frame = new JFrame(BindingContextUI.class.getSimpleName() + " - Main"); final JButton modalButton = new JButton("Modal"); modalButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createDlg(frame, true); } }); final JButton modelessButton = new JButton("Modeless"); modelessButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createDlg(frame, false); } }); final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 2, 2)); buttonPanel.add(modalButton); buttonPanel.add(modelessButton); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(buttonPanel); frame.pack(); frame.setVisible(true); } private static void createDlg(JFrame frame, final boolean modal) { final JButton applyButton = new JButton(modal ? "OK" : "Apply"); final JButton closeButton = new JButton(modal ? "Cancel" : "Close"); final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 2, 2)); buttonPanel.add(applyButton); buttonPanel.add(closeButton); final BindingContextUI ui = new BindingContextUI(); final JPanel panel = new JPanel(new BorderLayout(4, 4)); panel.setBorder(new EmptyBorder(4, 4, 4, 4)); panel.add(ui.controlPanel, BorderLayout.CENTER); panel.add(buttonPanel, BorderLayout.SOUTH); final JDialog dlg = new JDialog(frame, BindingContextUI.class.getSimpleName() + " - " + (modal ? "Modal" : "Modeless"), modal); dlg.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); dlg.setContentPane(panel); dlg.pack(); dlg.setLocation(frame.getX() + frame.getWidth(), frame.getY()); dlg.getRootPane().setDefaultButton(applyButton); applyButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final BindingProblem[] bindingProblems = ui.bindingContext.getProblems(); if (bindingProblems.length > 0) { for (int i = 0; i < bindingProblems.length; i++) { BindingProblem bindingProblem = bindingProblems[i]; System.out.println("bindingProblem[" + i + "] = " + bindingProblem.getCause().getMessage()); } JOptionPane.showMessageDialog(dlg, "Problems!"); } else { System.out.println("Apply!"); if (modal) { dlg.dispose(); } } } }); ui.bindingContext.preventPropertyChanges(closeButton); closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Close!"); dlg.dispose(); } }); dlg.setVisible(true); } private static class LettersOnlyValidator implements Validator { @Override public void validateValue(Property property, Object value) throws ValidationException { for (char c : ((String) value).toCharArray()) { if (!Character.isLetter(c)) { throw new ValidationException("Only letters!"); } } } } }