import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.SwingPropertyChangeSupport;
public class BeanContainer extends JFrame implements FocusListener {
protected File currentDir = new File(".");
protected Component currentBean;
protected String className = "MyBean";
protected JFileChooser fileChooser = new JFileChooser();
public BeanContainer() {
super("Simple Bean Container");
getContentPane().setLayout(new FlowLayout());
setSize(300, 300);
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
JMenuBar menuBar = createMenuBar();
setJMenuBar(menuBar);
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(wndCloser);
setVisible(true);
}
protected JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu mFile = new JMenu("File");
JMenuItem mItem = new JMenuItem("New...");
ActionListener lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
NewBeanThread t = new NewBeanThread();
t.start();
}
};
mItem.addActionListener(lst);
mFile.add(mItem);
mItem = new JMenuItem("Load...");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
LoadBeanThread t = new LoadBeanThread();
t.start();
}
};
mItem.addActionListener(lst);
mFile.add(mItem);
mItem = new JMenuItem("Save...");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
SaveBeanThread t = new SaveBeanThread();
t.start();
}
};
mItem.addActionListener(lst);
mFile.add(mItem);
mFile.addSeparator();
mItem = new JMenuItem("Exit");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
};
mItem.addActionListener(lst);
mFile.add(mItem);
menuBar.add(mFile);
JMenu mEdit = new JMenu("Edit");
mItem = new JMenuItem("Delete");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (currentBean == null)
return;
getContentPane().remove(currentBean);
currentBean = null;
validate();
repaint();
}
};
mItem.addActionListener(lst);
mEdit.add(mItem);
menuBar.add(mEdit);
JMenu mLayout = new JMenu("Layout");
ButtonGroup group = new ButtonGroup();
mItem = new JRadioButtonMenuItem("FlowLayout");
mItem.setSelected(true);
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
getContentPane().setLayout(new FlowLayout());
validate();
repaint();
}
};
mItem.addActionListener(lst);
group.add(mItem);
mLayout.add(mItem);
mItem = new JRadioButtonMenuItem("GridLayout");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int col = 3;
int row = (int) Math.ceil(getContentPane().getComponentCount()
/ (double) col);
getContentPane().setLayout(new GridLayout(row, col, 10, 10));
validate();
repaint();
}
};
mItem.addActionListener(lst);
group.add(mItem);
mLayout.add(mItem);
mItem = new JRadioButtonMenuItem("BoxLayout - X");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
validate();
repaint();
}
};
mItem.addActionListener(lst);
group.add(mItem);
mLayout.add(mItem);
mItem = new JRadioButtonMenuItem("BoxLayout - Y");
lst = new ActionListener() {
public void actionPerformed(ActionEvent e) {
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
validate();
repaint();
}
};
mItem.addActionListener(lst);
group.add(mItem);
mLayout.add(mItem);
group.add(mItem);
mLayout.add(mItem);
menuBar.add(mLayout);
return menuBar;
}
public void focusGained(FocusEvent e) {
currentBean = e.getComponent();
repaint();
}
public void focusLost(FocusEvent e) {
}
// This is a heavyweight component so we override paint
// instead of paintComponent. super.paint(g) will
// paint all child components first, and then we
// simply draw over top of them.
public void paint(Graphics g) {
super.paint(g);
if (currentBean == null)
return;
Point pt = getLocationOnScreen();
Point pt1 = currentBean.getLocationOnScreen();
int x = pt1.x - pt.x - 2;
int y = pt1.y - pt.y - 2;
int w = currentBean.getWidth() + 2;
int h = currentBean.getHeight() + 2;
g.setColor(Color.black);
g.drawRect(x, y, w, h);
}
public static void main(String argv[]) {
new BeanContainer();
}
class SaveBeanThread extends Thread {
public void run() {
if (currentBean == null)
return;
fileChooser
.setDialogTitle("Please choose file to serialize bean");
fileChooser.setCurrentDirectory(currentDir);
int result = fileChooser
.showSaveDialog(BeanContainer.this);
repaint();
if (result != JFileChooser.APPROVE_OPTION)
return;
currentDir = fileChooser.getCurrentDirectory();
File fChoosen = fileChooser.getSelectedFile();
try {
FileOutputStream fStream = new FileOutputStream(
fChoosen);
ObjectOutput stream = new ObjectOutputStream(
fStream);
stream.writeObject(currentBean);
stream.close();
fStream.close();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(BeanContainer.this,
"Error: " + ex.toString(), "Warning",
JOptionPane.WARNING_MESSAGE);
}
}
}
class LoadBeanThread extends Thread{
public void run() {
fileChooser.setCurrentDirectory(currentDir);
fileChooser
.setDialogTitle("Please select file with serialized bean");
int result = fileChooser
.showOpenDialog(BeanContainer.this);
repaint();
if (result != JFileChooser.APPROVE_OPTION)
return;
currentDir = fileChooser.getCurrentDirectory();
File fChoosen = fileChooser.getSelectedFile();
try {
FileInputStream fStream = new FileInputStream(
fChoosen);
ObjectInput stream = new ObjectInputStream(fStream);
Object obj = stream.readObject();
if (obj instanceof Component) {
currentBean = (Component) obj;
currentBean
.addFocusListener(BeanContainer.this);
currentBean.requestFocus();
getContentPane().add(currentBean);
}
stream.close();
fStream.close();
validate();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(BeanContainer.this,
"Error: " + ex.toString(), "Warning",
JOptionPane.WARNING_MESSAGE);
}
repaint();
}
}
class NewBeanThread extends Thread {
public void run() {
String result = (String) JOptionPane.showInputDialog(
BeanContainer.this,
"Use the following name for demanstration",
"Input", JOptionPane.INFORMATION_MESSAGE, null,
null, className);
repaint();
if (result == null)
return;
try {
className = result;
Class cls = Class.forName(result);
Object obj = cls.newInstance();
if (obj instanceof Component) {
currentBean = (Component) obj;
currentBean
.addFocusListener(BeanContainer.this);
currentBean.requestFocus();
getContentPane().add(currentBean);
}
validate();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(BeanContainer.this,
"Error: " + ex.toString(), "Warning",
JOptionPane.WARNING_MESSAGE);
}
}
}
}
class MyBean extends JComponent implements Externalizable {
// Property names
public static final String BEAN_VALUE = "Value";
public static final String BEAN_COLOR = "Color";
// Properties
private Font beanFont; // simple
private Dimension beanDimension; // simple
private int beanValue; // bound
private Color beanColor; // constrained
private String text; // change
// Manages all PropertyChangeListeners
protected SwingPropertyChangeSupport propertySupporter = new SwingPropertyChangeSupport(
this);
// Manages all VetoableChangeListeners
protected VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(this);
protected transient ChangeEvent changeEvent = null;
protected EventListenerList listenerList = new EventListenerList();
public MyBean() {
beanFont = new Font("SanSerif", Font.BOLD | Font.ITALIC, 12);
beanDimension = new Dimension(150, 100);
beanValue = 0;
beanColor = Color.black;
text = "BakedBean #";
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(beanColor);
g.setFont(beanFont);
g.drawString(text + beanValue, 30, 30);
}
public void setBeanFont(Font font) {
beanFont = font;
}
public Font getBeanFont() {
return beanFont;
}
public void setBeanValue(int newValue) {
int oldValue = beanValue;
beanValue = newValue;
// Notify all PropertyChangeListeners
propertySupporter.firePropertyChange(BEAN_VALUE, new Integer(oldValue),
new Integer(newValue));
}
public int getBeanValue() {
return beanValue;
}
public void setBeanColor(Color newColor) throws PropertyVetoException {
Color oldColor = beanColor;
vetoableChangeSupport.fireVetoableChange(BEAN_COLOR, oldColor, newColor);
beanColor = newColor;
propertySupporter.firePropertyChange(BEAN_COLOR, oldColor, newColor);
}
public Color getBeanColor() {
return beanColor;
}
public void setBeanString(String newString) {
text = newString;
// Notify all ChangeListeners
fireStateChanged();
}
public String getBeanString() {
return text;
}
public void setPreferredSize(Dimension dim) {
beanDimension = dim;
}
public Dimension getPreferredSize() {
return beanDimension;
}
public void setMinimumSize(Dimension dim) {
beanDimension = dim;
}
public Dimension getMinimumSize() {
return beanDimension;
}
public void addPropertyChangeListener(PropertyChangeListener l) {
propertySupporter.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
propertySupporter.removePropertyChangeListener(l);
}
public void addVetoableChangeListener(VetoableChangeListener l) {
vetoableChangeSupport.addVetoableChangeListener(l);
}
public void removeVetoableChangeListener(VetoableChangeListener l) {
vetoableChangeSupport.removeVetoableChangeListener(l);
}
// Remember that EventListenerList is an array of
// key/value pairs.
// key = XXListener class reference
// value = XXListener instance
public void addChangeListener(ChangeListener l) {
listenerList.add(ChangeListener.class, l);
}
public void removeChangeListener(ChangeListener l) {
listenerList.remove(ChangeListener.class, l);
}
// EventListenerList dispatching code.
protected void fireStateChanged() {
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChangeListener.class) {
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
}
}
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(beanFont);
out.writeObject(beanDimension);
out.writeInt(beanValue);
out.writeObject(beanColor);
out.writeObject(text);
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
setBeanFont((Font) in.readObject());
setPreferredSize((Dimension) in.readObject());
// Use preferred size for minimum size..
setMinimumSize(getPreferredSize());
setBeanValue(in.readInt());
try {
setBeanColor((Color) in.readObject());
} catch (PropertyVetoException pve) {
System.out.println("Color change vetoed..");
}
setBeanString((String) in.readObject());
}
public static void main(String[] args) {
JFrame frame = new JFrame("BakedBean");
frame.getContentPane().add(new MyBean());
frame.setVisible(true);
frame.pack();
}
}
|