706 lines
26 KiB
Java
Executable File
706 lines
26 KiB
Java
Executable File
/*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
|
*
|
|
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
|
|
*
|
|
* The contents of this file are subject to the terms of either the GNU
|
|
* General Public License Version 2 only ("GPL") or the Common
|
|
* Development and Distribution License("CDDL") (collectively, the
|
|
* "License"). You may not use this file except in compliance with the
|
|
* License. You can obtain a copy of the License at
|
|
* http://www.netbeans.org/cddl-gplv2.html
|
|
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
|
* specific language governing permissions and limitations under the
|
|
* License. When distributing the software, include this License Header
|
|
* Notice in each file and include the License file at
|
|
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Sun in the GPL Version 2 section of the License file that
|
|
* accompanied this code. If applicable, add the following below the
|
|
* License Header, with the fields enclosed by brackets [] replaced by
|
|
* your own identifying information:
|
|
* "Portions Copyrighted [year] [name of copyright owner]"
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* The Original Software is NetBeans. The Initial Developer of the Original
|
|
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
|
|
* Microsystems, Inc. All Rights Reserved.
|
|
*
|
|
* If you wish your version of this file to be governed by only the CDDL
|
|
* or only the GPL Version 2, indicate your decision by adding
|
|
* "[Contributor] elects to include this software in this distribution
|
|
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
|
* single choice of license, a recipient has the option to distribute
|
|
* your version of this file under either the CDDL, the GPL Version 2 or
|
|
* to extend the choice of license to its licensees as provided above.
|
|
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
|
* Version 2 license, then the option applies only if the new code is
|
|
* made subject to such option by the copyright holder.
|
|
*/
|
|
|
|
package org.netbeans.modules.jbi.apisupport.xmlmv.ui;
|
|
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import org.netbeans.modules.jbi.apisupport.xmlmv.Error;
|
|
import org.netbeans.modules.jbi.apisupport.xmlmv.Refreshable;
|
|
import org.netbeans.modules.jbi.apisupport.xmlmv.Utils;
|
|
import org.netbeans.modules.jbi.apisupport.xmlmv.cookies.ErrorLocator;
|
|
import org.netbeans.modules.jbi.apisupport.xmlmv.cookies.LinkCookie;
|
|
import org.openide.util.RequestProcessor;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.text.JTextComponent;
|
|
import java.awt.*;
|
|
import java.awt.event.FocusEvent;
|
|
import java.awt.event.FocusListener;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
|
|
/**
|
|
* This class represents a panel that is contained in <code>SectionPanel</code>,
|
|
* i.e. an inner panel as the name implies. This class provides support for registering
|
|
* UI components that modify the model by means of various <code>addModifier</code> and
|
|
* <code>addImmediateModifier</code> methods. See javadocs of those for
|
|
* more details.
|
|
*
|
|
* @author mkuchtiak
|
|
*/
|
|
public abstract class SectionInnerPanel extends javax.swing.JPanel implements LinkCookie, ErrorLocator {
|
|
private SectionView sectionView;
|
|
private java.util.List refreshableList = new LinkedList();
|
|
|
|
private boolean localFocusListenerInitialized = false;
|
|
private FocusListener localFocusListener = new FocusListener() {
|
|
public void focusGained(FocusEvent evt) {
|
|
final FocusListener[] focusListeners = getFocusListeners();
|
|
for (int i = 0; i < focusListeners.length; i++) {
|
|
focusListeners[i].focusGained(evt);
|
|
}
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
processFocusEvent(evt);
|
|
}
|
|
};
|
|
|
|
private RequestProcessor.Task refreshTask = RequestProcessor.getDefault().create(new Runnable() {
|
|
public void run() {
|
|
refreshView();
|
|
}
|
|
});
|
|
|
|
private static final int REFRESH_DELAY = 50;
|
|
private FlushFocusListener activeListener = null;
|
|
private boolean closing = false;
|
|
|
|
/** Constructor that takes the enclosing SectionView object as its argument
|
|
* @param sectionView enclosing SectionView object
|
|
*/
|
|
public SectionInnerPanel(SectionView sectionView) {
|
|
this.sectionView = sectionView;
|
|
}
|
|
|
|
public synchronized void addFocusListener(FocusListener l) {
|
|
super.addFocusListener(l);
|
|
if (!localFocusListenerInitialized) {
|
|
localFocusListenerInitialized = true;
|
|
Container container = this;
|
|
FocusListener focusListener = localFocusListener;
|
|
addFocusListenerRecursively(container, focusListener);
|
|
}
|
|
}
|
|
|
|
private void addFocusListenerRecursively(Container container, FocusListener focusListener) {
|
|
final Component[] components = container.getComponents();
|
|
for (int i = 0; i < components.length; i++) {
|
|
Component component = components[i];
|
|
if (component.isFocusable() && !(component instanceof JLabel)) {
|
|
component.addFocusListener(focusListener);
|
|
}
|
|
if (component instanceof Container) {
|
|
if (!(component instanceof SectionNodePanel)) {
|
|
addFocusListenerRecursively((Container) component, focusListener);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Getter for section view
|
|
* @return sectionView enclosing SectionView object
|
|
*/
|
|
public SectionView getSectionView() {
|
|
return sectionView;
|
|
}
|
|
|
|
/**
|
|
* Callback method called on focus lost event after the value was checked for correctness
|
|
* (in case <code>source</code> was registered using one of the <code>addModifier</code> methods
|
|
* of this class, if <code>addImmediateModifier</code> was used instead, this method
|
|
* gets called immediately when the state of <code>source</code> changes).
|
|
* @param source the last focused JComponent or whose state was changed.
|
|
* @param value the value that has been set (typed) in the component
|
|
*/
|
|
public abstract void setValue(JComponent source, Object value);
|
|
|
|
/** Callback method called on document change event. This is called for components that
|
|
* require just-in-time validation.
|
|
* @param source JTextComponent being actually edited
|
|
* @param value the actual value of the component
|
|
*/
|
|
public void documentChanged(javax.swing.text.JTextComponent source, String value) {
|
|
}
|
|
|
|
/** Callback method called on focus lost event after the value was checked for correctness.
|
|
* and the result is that the value is wrong. The value should be rollbacked from the model.
|
|
* @param source last focused JComponent
|
|
*/
|
|
public void rollbackValue(javax.swing.text.JTextComponent source) {
|
|
}
|
|
|
|
/** Adds text component to the set of JTextComponents that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* @param tc JTextComponent whose content is related to data model
|
|
*/
|
|
public final void addModifier(final JTextComponent tc) {
|
|
tc.addFocusListener(new ModifyFocusListener(tc));
|
|
}
|
|
|
|
/** Adds text component to the set of JTextComponents that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
*
|
|
* @param tc JTextComponent whose content is related to data model
|
|
* @param test indicates whether the original value should be tested against the current value when focus is lost
|
|
*/
|
|
public final void addModifier(final JTextComponent tc, boolean test) {
|
|
tc.addFocusListener(new ModifyFocusListener(tc, test));
|
|
}
|
|
|
|
/**
|
|
* Adds combo box component to the set of JComboBoxes that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* @param comboBox JComboBox whose content is related to data model
|
|
*/
|
|
public final void addModifier(final JComboBox comboBox) {
|
|
comboBox.addFocusListener(new ComboBoxModifyFocusListener(comboBox));
|
|
}
|
|
|
|
/**
|
|
* Adds combo box component to the set of JComboBoxes that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
*
|
|
* @param comboBox JComboBox whose content is related to data model
|
|
* @param test indicates whether the original value should be tested against the current value when focus is lost
|
|
*/
|
|
public final void addModifier(final JComboBox comboBox, boolean test) {
|
|
comboBox.addFocusListener(new ComboBoxModifyFocusListener(comboBox, test));
|
|
}
|
|
|
|
|
|
/**
|
|
* Adds radio button component to the set of JRadioButtons that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* @param radioButton JRadioButton whose content is related to data model
|
|
*/
|
|
public final void addModifier(final JRadioButton radioButton){
|
|
radioButton.addFocusListener(new RadioButtonModifyFocusListener(radioButton));
|
|
}
|
|
|
|
/**
|
|
* Adds check box component to the set of JCheckBox that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* @param checkBox JCheckBox whose content is related to data model
|
|
*/
|
|
public final void addModifier(final JCheckBox checkBox){
|
|
checkBox.addFocusListener(new CheckBoxModifyFocusListener(checkBox));
|
|
}
|
|
|
|
/**
|
|
* Adds check box component to the set of JCheckBoxes that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* Unlike <code>addModifier</code>, this method will cause <code>setValue()</code>
|
|
* to be called on each action event related to the given <code>checkBox</code>. Note
|
|
* that the same component should not be added both as a regular modifier and
|
|
* as an immediate modifier.
|
|
* @param checkBox JCheckBox whose content is related to data model
|
|
*/
|
|
public final void addImmediateModifier(final JCheckBox checkBox){
|
|
checkBox.addActionListener(new CheckBoxActionListener(checkBox));
|
|
}
|
|
|
|
/**
|
|
* Adds the given <code>radioButton</code> to the set of JRadioButtons that modify the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* Unlike <code>addModifier</code>, this method will cause <code>setValue()</code>
|
|
* to be called on each action event related to the given <code>checkBox</code>. Note
|
|
* that the same component should not be added both as a regular modifier and
|
|
* as an immediate modifier.
|
|
* @param radioButton the radio button whose content is related to the data model
|
|
*/
|
|
public final void addImmediateModifier(final JRadioButton radioButton){
|
|
radioButton.addActionListener(new RadioButtonActionListener(radioButton));
|
|
}
|
|
|
|
/**
|
|
* Adds combo box component to the set of JComboBoxes that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* Unlike <code>addModifier</code>, this method will cause <code>setValue()</code>
|
|
* to be called on each action event related to the given <code>comboBox</code>.Note
|
|
* that the same component should not be added both as a regular modifier and
|
|
* as an immediate modifier.
|
|
* @param comboBox JComboBox whose content is related to data model
|
|
*/
|
|
public final void addImmediateModifier(final JComboBox comboBox) {
|
|
comboBox.addActionListener(new ComboBoxActionListener(comboBox));
|
|
}
|
|
|
|
/** Adds text component to the set of JTextComponents that modifies the model.
|
|
* After the value in this component is changed the setValue() method is called.
|
|
* Unlike <code>addModifier</code>, this method will cause <code>setValue()</code>
|
|
* to be called on every change related to the given <code>tc</code>.Note
|
|
* that the same component should not be added both as a regular modifier and
|
|
* as an immediate modifier.
|
|
* @param tc JTextComponent whose content is related to data model
|
|
*/
|
|
public final void addImmediateModifier(final JTextComponent tc) {
|
|
tc.getDocument().addDocumentListener(new TextListener(tc, true));
|
|
}
|
|
|
|
/** Adds text component to the set of JTextComponents that should be validated for correctness.
|
|
* After the value in this component is changed either setValue() method is called(value is correct)
|
|
* or rollbackValue() method is called(value is incorrect). Also the documentChanged() method is called during editing.
|
|
* @param tc JTextComponent whose content is related to data model and should be validated before saving to data model.
|
|
*/
|
|
public final void addValidatee(final JTextComponent tc) {
|
|
tc.getDocument().addDocumentListener(new TextListener(tc));
|
|
tc.addFocusListener(new ValidateFocusListener(tc));
|
|
}
|
|
|
|
protected void scheduleRefreshView() {
|
|
refreshTask.schedule(REFRESH_DELAY);
|
|
}
|
|
|
|
/**
|
|
* Reloads data from data model
|
|
*/
|
|
public void refreshView() {
|
|
for (Iterator it = refreshableList.iterator(); it.hasNext();) {
|
|
((Refreshable) it.next()).refresh();
|
|
}
|
|
}
|
|
|
|
protected void addRefreshable(Refreshable refreshable) {
|
|
refreshableList.add(refreshable);
|
|
}
|
|
|
|
public void dataModelPropertyChange(Object source, String propertyName, Object oldValue, Object newValue) {
|
|
scheduleRefreshView();
|
|
}
|
|
|
|
private class TextListener implements javax.swing.event.DocumentListener {
|
|
|
|
private JTextComponent tc;
|
|
private boolean setValue = false;
|
|
|
|
TextListener(JTextComponent tc) {
|
|
this(tc, false);
|
|
}
|
|
|
|
TextListener(JTextComponent tc, boolean setValue) {
|
|
this.tc = tc;
|
|
this.setValue = setValue;
|
|
}
|
|
|
|
/**
|
|
* Method from DocumentListener
|
|
*/
|
|
public void changedUpdate(javax.swing.event.DocumentEvent evt) {
|
|
update(evt);
|
|
}
|
|
|
|
/**
|
|
* Method from DocumentListener
|
|
*/
|
|
public void insertUpdate(javax.swing.event.DocumentEvent evt) {
|
|
update(evt);
|
|
}
|
|
|
|
/**
|
|
* Method from DocumentListener
|
|
*/
|
|
public void removeUpdate(javax.swing.event.DocumentEvent evt) {
|
|
update(evt);
|
|
}
|
|
|
|
private void update(javax.swing.event.DocumentEvent evt) {
|
|
if (setValue){
|
|
startUIChange();
|
|
setValue(tc, tc.getText());
|
|
signalUIChange();
|
|
endUIChange();
|
|
} else {
|
|
documentChanged(tc, tc.getText());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private abstract class FlushFocusListener extends java.awt.event.FocusAdapter {
|
|
public abstract boolean flushData();
|
|
}
|
|
|
|
private class ValidateFocusListener extends FlushFocusListener {
|
|
private String orgValue;
|
|
private boolean viewIsBuggy;
|
|
private final JTextComponent tc;
|
|
/**
|
|
* Prevents 'fix now' dialog from popping up multiple times.
|
|
*/
|
|
private boolean disable;
|
|
|
|
public ValidateFocusListener(JTextComponent tc) {
|
|
this.tc = tc;
|
|
}
|
|
|
|
public void focusGained(FocusEvent evt) {
|
|
activeListener = this;
|
|
orgValue = tc.getText();
|
|
if (sectionView.getErrorPanel().getError() != null) {
|
|
viewIsBuggy = true;
|
|
} else {
|
|
viewIsBuggy = false;
|
|
}
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
if (!closing) {
|
|
if (!flushData()) {
|
|
Utils.runInAwtDispatchThread(new Runnable() {
|
|
public void run() {
|
|
//todo: make sure the panel is visible
|
|
tc.requestFocus();
|
|
}
|
|
});
|
|
} else {
|
|
disable = false;
|
|
activeListener = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean flushData() {
|
|
Error error = sectionView.getErrorPanel().getError();
|
|
if (error != null && error.isEditError() && tc == error.getFocusableComponent()) {
|
|
if (Error.TYPE_WARNING == error.getSeverityLevel() && !disable) {
|
|
org.openide.DialogDescriptor desc = new RefreshSaveDialog(sectionView.getErrorPanel());
|
|
Dialog dialog = org.openide.DialogDisplayer.getDefault().createDialog(desc);
|
|
dialog.show();
|
|
Integer opt = (Integer) desc.getValue();
|
|
if (opt.equals(RefreshSaveDialog.OPTION_FIX)) {
|
|
disable = true;
|
|
return false;
|
|
} else if (opt.equals(RefreshSaveDialog.OPTION_REFRESH)) {
|
|
rollbackValue(tc);
|
|
sectionView.checkValidity();
|
|
} else {
|
|
startUIChange();
|
|
setValue(tc, tc.getText());
|
|
signalUIChange();
|
|
endUIChange();
|
|
sectionView.checkValidity();
|
|
}
|
|
} else if (!disable){
|
|
org.openide.DialogDescriptor desc = new RefreshDialog(sectionView.getErrorPanel());
|
|
Dialog dialog = org.openide.DialogDisplayer.getDefault().createDialog(desc);
|
|
dialog.show();
|
|
Integer opt = (Integer) desc.getValue();
|
|
if (opt.equals(RefreshDialog.OPTION_FIX)) {
|
|
disable = true;
|
|
return false;
|
|
} else if (opt.equals(RefreshDialog.OPTION_REFRESH)) {
|
|
rollbackValue(tc);
|
|
sectionView.checkValidity();
|
|
}
|
|
}
|
|
} else {
|
|
if (!tc.getText().equals(orgValue)) {
|
|
startUIChange();
|
|
setValue(tc, tc.getText());
|
|
signalUIChange();
|
|
endUIChange();
|
|
sectionView.checkValidity();
|
|
} else {
|
|
if (viewIsBuggy) {
|
|
sectionView.checkValidity();
|
|
}
|
|
}
|
|
}
|
|
disable = false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private class ModifyFocusListener extends FlushFocusListener {
|
|
private String orgValue;
|
|
private final JTextComponent tc;
|
|
// indicates whether the original value (orgValue) should be tested against the current value when focus is lost
|
|
private boolean test;
|
|
|
|
public ModifyFocusListener(JTextComponent tc) {
|
|
this(tc, true);
|
|
}
|
|
|
|
public ModifyFocusListener(JTextComponent tc, boolean test) {
|
|
this.tc = tc;
|
|
this.test = test;
|
|
}
|
|
|
|
public void focusGained(FocusEvent evt) {
|
|
orgValue = tc.getText();
|
|
activeListener = this;
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
if (!closing) {
|
|
flushData();
|
|
activeListener = null;
|
|
}
|
|
}
|
|
|
|
public boolean flushData() {
|
|
if (!test || !tc.getText().equals(orgValue)) {
|
|
startUIChange();
|
|
setValue(tc, tc.getText());
|
|
signalUIChange();
|
|
endUIChange();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listener attached to combo boxes that modify the model.
|
|
*/
|
|
private class ComboBoxModifyFocusListener extends FlushFocusListener {
|
|
private Object orgValue;
|
|
private final JComboBox comboBox;
|
|
// indicates whether the original value (orgValue) should be tested against the current value when focus is lost
|
|
private boolean test;
|
|
|
|
public ComboBoxModifyFocusListener(JComboBox comboBox) {
|
|
this(comboBox, true);
|
|
}
|
|
|
|
public ComboBoxModifyFocusListener(JComboBox comboBox, boolean test) {
|
|
this.comboBox = comboBox;
|
|
this.test = test;
|
|
}
|
|
|
|
public void focusGained(FocusEvent evt) {
|
|
orgValue = comboBox.getSelectedItem();
|
|
activeListener = this;
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
if (!closing) {
|
|
flushData();
|
|
activeListener = null;
|
|
}
|
|
}
|
|
|
|
public boolean flushData() {
|
|
Object newValue = comboBox.getSelectedItem();
|
|
boolean newEqualsOld = (newValue==null ? orgValue==null : newValue.equals(orgValue));
|
|
if (!test || !newEqualsOld) {
|
|
startUIChange();
|
|
setValue(comboBox, comboBox.getSelectedItem());
|
|
signalUIChange();
|
|
endUIChange();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listener attached to radio buttons that modify the model.
|
|
*/
|
|
private class RadioButtonModifyFocusListener extends FlushFocusListener {
|
|
private boolean orgValue;
|
|
private final JRadioButton radioButton;
|
|
|
|
public RadioButtonModifyFocusListener(JRadioButton radioButton) {
|
|
this.radioButton = radioButton;
|
|
}
|
|
|
|
public void focusGained(FocusEvent evt) {
|
|
orgValue = radioButton.isSelected();
|
|
activeListener = this;
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
if (!closing) {
|
|
flushData();
|
|
activeListener = null;
|
|
}
|
|
}
|
|
|
|
public boolean flushData() {
|
|
if (!(radioButton.isSelected() == orgValue)) {
|
|
startUIChange();
|
|
setValue(radioButton, Boolean.valueOf(radioButton.isSelected()));
|
|
signalUIChange();
|
|
endUIChange();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public boolean canClose() {
|
|
closing = true;
|
|
try {
|
|
if (activeListener != null) {
|
|
return activeListener.flushData();
|
|
}
|
|
return true;
|
|
} finally {
|
|
closing = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base class for action listeners for components that require setValue to be called
|
|
* immediately on action event (instead of when focus is gained/lost).
|
|
*/
|
|
private abstract class FlushActionListener implements ActionListener {
|
|
|
|
public final void actionPerformed(ActionEvent e) {
|
|
startUIChange();
|
|
doSetValue(e);
|
|
signalUIChange();
|
|
endUIChange();
|
|
}
|
|
|
|
/**
|
|
* Does the actual setting of the value to the model. Subclasses
|
|
* should usually invoke <code>setValue</code> method here.
|
|
*/
|
|
public abstract void doSetValue(ActionEvent e);
|
|
}
|
|
|
|
/**
|
|
* Action listener for combo boxes that require setValue to be called
|
|
* immediately on action event (instead of when focus is gained/lost).
|
|
*/
|
|
private class ComboBoxActionListener extends FlushActionListener{
|
|
|
|
private final JComboBox comboBox;
|
|
|
|
public ComboBoxActionListener(JComboBox comboBox){
|
|
this.comboBox = comboBox;
|
|
}
|
|
|
|
public void doSetValue(ActionEvent e) {
|
|
setValue(comboBox, comboBox.getSelectedItem());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Action listener for checkboxes that require setValue to be called
|
|
* immediately on action event (instead of when focus is gained/lost).
|
|
*/
|
|
private class CheckBoxActionListener extends FlushActionListener{
|
|
|
|
private final JCheckBox checkBox;
|
|
|
|
public CheckBoxActionListener(JCheckBox checkBox){
|
|
this.checkBox = checkBox;
|
|
}
|
|
|
|
public void doSetValue(ActionEvent e) {
|
|
setValue(checkBox, Boolean.valueOf(checkBox.isSelected()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Action listener for radio buttons that require setValue to be called
|
|
* immediately on action event (instead of when focus is gained/lost).
|
|
*/
|
|
private class RadioButtonActionListener extends FlushActionListener{
|
|
|
|
private final JRadioButton radioButton;
|
|
|
|
public RadioButtonActionListener(JRadioButton radioButton){
|
|
this.radioButton = radioButton;
|
|
}
|
|
|
|
public void doSetValue(ActionEvent e) {
|
|
setValue(radioButton, Boolean.valueOf(radioButton.isSelected()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listener attached to check boxes that modify the model.
|
|
*/
|
|
private class CheckBoxModifyFocusListener extends FlushFocusListener {
|
|
private boolean orgValue;
|
|
private final JCheckBox checkBox;
|
|
|
|
public CheckBoxModifyFocusListener(JCheckBox checkBox) {
|
|
this.checkBox = checkBox;
|
|
}
|
|
|
|
public void focusGained(FocusEvent evt) {
|
|
orgValue = checkBox.isSelected();
|
|
activeListener = this;
|
|
}
|
|
|
|
public void focusLost(FocusEvent evt) {
|
|
if (!closing) {
|
|
flushData();
|
|
activeListener = null;
|
|
}
|
|
}
|
|
|
|
public boolean flushData() {
|
|
if (!(checkBox.isSelected() == orgValue)) {
|
|
startUIChange();
|
|
setValue(checkBox, Boolean.valueOf(checkBox.isSelected()));
|
|
signalUIChange();
|
|
endUIChange();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public boolean canClose() {
|
|
closing = true;
|
|
try {
|
|
if (activeListener != null) {
|
|
return activeListener.flushData();
|
|
}
|
|
return true;
|
|
} finally {
|
|
closing = false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/** This will be called after model is changed from this panel
|
|
* @deprecated use {@link SectionInnerPanel#endUIChange} instead
|
|
*/
|
|
protected void signalUIChange() {
|
|
}
|
|
|
|
/** This will be called before model is changed from this panel
|
|
*/
|
|
protected void startUIChange() {
|
|
}
|
|
|
|
/** This will be called after model is changed from this panel
|
|
*/
|
|
protected void endUIChange() {
|
|
}
|
|
|
|
}
|