-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
1.3.0
-
generic
-
generic
Name: boT120536 Date: 03/15/2001
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
VetoableChangeSupport.fireVetoableChange() fires a PropertyChangeEvent a 2nd
time for rolling back, if anyone vetos the change. Therefore
VetoableChangeListener's method vetoableChange() will be called twice. But the
PropertyChangeEvent does not contain any information to distinguish the rolling-
back-request from simple reports.
This causes side effects, if the VetoableChangeListener class pops up a dialog
box for confirmation. The listener has actually no chance to decide effectively
if to pop up the dialog again? May be the only chance is to call getOldValue(),
getNewValue() methods of PropertyChangeEvent for discovering. But it is not
that safe to rely on values.
Sample codes
----------------------------------------------------------------
The bean itself:
package jbeans;
import java.awt.Canvas;
import java.awt.Color;
import java.beans.*;
public class SimpleBean
extends Canvas
implements java.io.Serializable
{
static final Color DEFAULT_BGCOLOR = Color.red;
static final int DEFAULT_WIDTH = 400;
static final int DEFAULT_HEIGHT = 300;
private PropertyChangeSupport changes = new PropertyChangeSupport(this);
private VetoableChangeSupport vetos = new VetoableChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener l) {
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
changes.removePropertyChangeListener(l);
}
public void addVetoableChangeListener(VetoableChangeListener l) {
vetos.addVetoableChangeListener(l);
}
public void removeVetoableChangeListener(VetoableChangeListener l) {
vetos.removeVetoableChangeListener(l);
}
private Color color = Color.green;
public Color getColor() {
return color;
}
public void setColor(Color newColor) throws PropertyVetoException {
vetos.fireVetoableChange("color", color, newColor);
Color oldColor = color;
color = newColor;
repaint();
changes.firePropertyChange("color", oldColor, newColor);
}
public void paint(java.awt.Graphics g) {
int w = getWidth();
int h = getHeight();
g.setColor(color);
g.fillRect(w/4, h/4, w/2, h/2);
}
public SimpleBean() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setBackground(DEFAULT_BGCOLOR);
}
}
----------------------------------------------------------------
The main:
package beanviewer;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.*;
import java.awt.Canvas;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.BoxLayout;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import jbeans.SimpleBean;
public class BeanFrame extends JFrame
{
static final String DEFAULT_SER_FILE = "bean.ser";
private JButton btn1 = new JButton("Change color");
private JButton btn2 = new JButton("Write");
private JButton btn3 = new JButton("Reload");
private JButton btn4 = new JButton("Bean Info");
private JPanel btnPanel = new JPanel();
private JLabel label = new JLabel();
private SimpleBean bean = new SimpleBean();
private ColorChangeListener ccl = new ColorChangeListener();
private ColorVetoListener cvl = new ColorVetoListener(this);
private void init() {
bean.addPropertyChangeListener(ccl);
bean.addVetoableChangeListener(cvl);
Container cp = this.getContentPane();
cp.setLayout(new BorderLayout());
Color c = bean.getColor();
label.setText("red: " + c.getRed() + ' ' +
"green: " + c.getGreen() + ' ' +
"blue: " + c.getBlue());
cp.add(label, BorderLayout.NORTH);
cp.add(bean, BorderLayout.CENTER);
cp.add(btnPanel, BorderLayout.SOUTH);
setSize(getPreferredSize());
}
public BeanFrame() {
btnPanel.add(btn1);
btnPanel.add(btn2);
btnPanel.add(btn3);
btnPanel.add(btn4);
btn1.addActionListener(new ChangeListener());
btn2.addActionListener(new WriteListener());
btn3.addActionListener(new ReloadListener());
init();
addWindowListener(new FrameAdapter());
this.setTitle("BeanPanel");
}
public static void main(String[] args) {
BeanFrame bf = new BeanFrame();
bf.show();
}
class ChangeListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
try {
bean.setColor(new Color((int)(256*Math.random
()),
(int)(256*Math.random()),
(int)(256*Math.random())));
Color c = bean.getColor();
label.setText("red: " + c.getRed() + ' ' +
"green: " + c.getGreen
() + ' ' +
"blue: " + c.getBlue
());
}
catch (java.beans.PropertyVetoException ex) {
label.setText("Color has not been changed");
}
finally {}
}
};
class WriteListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
write();
}
};
private void write() {
try {
FileOutputStream fos = new FileOutputStream
(DEFAULT_SER_FILE);
ObjectOutputStream s = new ObjectOutputStream(fos);
s.writeObject(bean);
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {}
}
class ReloadListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
reload();
}
};
private void reload() {
SimpleBean oldBean = bean;
try {
FileInputStream fis = new FileInputStream
(DEFAULT_SER_FILE);
ObjectInputStream s = new ObjectInputStream(fis);
bean = (SimpleBean)s.readObject();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {}
if (bean != null) {
remove(oldBean);
remove(btnPanel);
init();
}
}
class FrameAdapter extends java.awt.event.WindowAdapter
{
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
};
class ColorChangeListener implements java.beans.PropertyChangeListener
{
public void propertyChange(java.beans.PropertyChangeEvent e) {
/* System.out.println(e.getPropertyName() + " change from " +
e.getOldValue() + " to " +
e.getNewValue());
*/
}
};
class ColorVetoListener implements java.beans.VetoableChangeListener
{
private BeanFrame frame = null;
public ColorVetoListener(BeanFrame f) {
frame = f;
}
public void vetoableChange(java.beans.PropertyChangeEvent e)
throws java.beans.PropertyVetoException {
String msg = e.getPropertyName() + " change from " +
e.getOldValue() + " to " +
e.getNewValue();
int ret = JOptionPane.showConfirmDialog(frame, msg, "Change
color",
JOptionPane.YES_NO_OPTION);
if (ret == JOptionPane.NO_OPTION) {
throw new java.beans.PropertyVetoException("Don't
change the color", e);
}
}
};
(Review ID: 117475)
======================================================================
- duplicates
-
JDK-4425885 java.beans.VetoableChangeSupport.fireVetoableChange incorrectly handles vetos.
-
- Closed
-