Java/Swing JFC/Customized Component
Содержание
Alias Bean
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. All rights
* reserved. Software written by Ian F. Darwin and others. $Id: LICENSE,v 1.8
* 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee cup"
* logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
class AliasBean extends JPanel {
protected Vector aliVector;
protected JList aliJList;
private JTextField nameTF, addrTF;
public AliasBean() {
aliVector = new Vector();
aliJList = new JList();
// XXX MUST FIX THIS
// aliJList.setSelectionMode(JList.SINGLE_SELECTION);
aliJList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
int i = aliJList.getSelectedIndex();
if (i < 0)
return;
Alias al = (Alias) aliVector.get(i);
nameTF.setText(al.getName());
addrTF.setText(al.getAddress());
}
});
setLayout(new BorderLayout());
add(BorderLayout.WEST, new JScrollPane(aliJList));
JPanel rightPanel = new JPanel();
add(BorderLayout.EAST, rightPanel);
rightPanel.setLayout(new GridLayout(0, 1));
JPanel buttons = new JPanel();
rightPanel.add(buttons);
buttons.setLayout(new GridLayout(0, 1, 15, 15));
JButton b;
buttons.add(b = new JButton("Set"));
b.setToolTipText("Add or Change an alias");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int i = aliJList.getSelectedIndex();
if (i < 0) {
// XXX error dialog??
return;
}
setAlias(i, nameTF.getText(), addrTF.getText());
}
});
buttons.add(b = new JButton("Delete"));
b.setToolTipText("Delete the selected alias");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int i = aliJList.getSelectedIndex();
if (i < 0) {
return;
}
deleteAlias(i);
}
});
buttons.add(b = new JButton("Apply"));
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.err.println("NOT WRITTEN YET");
}
});
JPanel fields = new JPanel();
rightPanel.add(fields);
fields.setLayout(new GridLayout(2, 2));
fields.add(new JLabel("Name"));
fields.add(nameTF = new JTextField(10));
fields.add(new JLabel("Address"));
fields.add(addrTF = new JTextField(20));
}
public String expandAlias(String ali) {
Alias a = findAlias(ali);
if (a == null)
return null;
return a.getAddress();
}
public Alias findAlias(String ali) {
for (int i = 0; i < aliVector.size(); i++) {
Alias a = (Alias) aliVector.get(i);
if (a.getName().equals(ali))
return a;
}
return null; // not found
}
/** Add an Alias */
public void addAlias(Alias a) {
Alias al = findAlias(a.getName());
if (al == null) {
aliVector.addElement(a);
} else {
// aliVector.setElement(a); // XXX fuzzy
}
aliJList.setListData(aliVector);
}
/** Add an alias, by its constituent parts */
public void addAlias(String nn, String addr) {
addAlias(new Alias(nn, addr));
}
/** Replace an Alias */
public void setAlias(int n, String nam, String addr) {
// TODO find it, replace it, or add it.
aliVector.setElementAt(new Alias(nam, addr), n);
aliJList.setListData(aliVector);
}
public void deleteAlias(int i) {
aliVector.removeElementAt(i);
aliJList.setListData(aliVector);
}
}
class Alias {
/** The name for the alias */
protected String name;
/** The email address for this alias */
protected String address;
public Alias(String n, String addr) {
name = n;
address = addr;
}
public String toString() {
return name + " = " + address;
}
/** Get name */
public String getName() {
return name;
}
/** Set name */
public void setName(String name) {
this.name = name;
}
/** Get address */
public String getAddress() {
return address;
}
/** Set address */
public void setAddress(String address) {
this.address = address;
}
}
/**
* Test for AliasBean.
*
* @version $Id: AliasBeanTest.java,v 1.3 2004/02/09 03:33:48 ian Exp $
*/
public class AliasBeanTest extends JFrame {
JButton quitButton;
/** "main program" method - construct and show */
public static void main(String[] av) {
// create a JFrameDemo object, tell it to show up
new AliasBeanTest().setVisible(true);
}
/** Construct the object including its GUI */
public AliasBeanTest() {
super("AliasBeanTest");
Container cp = getContentPane();
AliasBean ab = new AliasBean();
cp.add(BorderLayout.CENTER, ab);
ab.addAlias("ian-cvs", "ian@openbsd.org");
ab.addAlias("ian-dos", "http://www.darwinsys.ru/");
cp.add(BorderLayout.SOUTH, quitButton = new JButton("Exit"));
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
});
pack();
}
}
Customized component
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.Customizer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Clock extends JButton implements Customizer, Externalizable,
Runnable {
protected PropertyChangeSupport propertyChangeSupport;
protected boolean isDigital = false;
protected Calendar calendar = Calendar.getInstance();
public Clock() {
propertyChangeSupport = new PropertyChangeSupport(this);
setBackground(Color.white);
setForeground(Color.black);
(new Thread(this)).start();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeBoolean(isDigital);
out.writeObject(getBackground());
out.writeObject(getForeground());
out.writeObject(getPreferredSize());
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
setDigital(in.readBoolean());
setBackground((Color) in.readObject());
setForeground((Color) in.readObject());
setPreferredSize((Dimension) in.readObject());
}
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
public void setDigital(boolean digital) {
propertyChangeSupport.firePropertyChange("digital", new Boolean(
isDigital), new Boolean(digital));
isDigital = digital;
repaint();
}
public boolean getDigital() {
return isDigital;
}
public void addPropertyChangeListener(PropertyChangeListener lst) {
if (propertyChangeSupport != null)
propertyChangeSupport.addPropertyChangeListener(lst);
}
public void removePropertyChangeListener(PropertyChangeListener lst) {
if (propertyChangeSupport != null)
propertyChangeSupport.removePropertyChangeListener(lst);
}
public void setObject(Object bean) {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Color colorRetainer = g.getColor();
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
calendar.setTime(new Date()); // get current time
int hrs = calendar.get(Calendar.HOUR_OF_DAY);
int min = calendar.get(Calendar.MINUTE);
g.setColor(getForeground());
if (isDigital) {
String time = "" + hrs + ":" + min;
g.setFont(getFont());
FontMetrics fm = g.getFontMetrics();
int y = (getHeight() + fm.getAscent()) / 2;
int x = (getWidth() - fm.stringWidth(time)) / 2;
g.drawString(time, x, y);
} else {
int x = getWidth() / 2;
int y = getHeight() / 2;
int rh = getHeight() / 4;
int rm = getHeight() / 3;
double ah = ((double) hrs + min / 60.0) / 6.0 * Math.PI;
double am = min / 30.0 * Math.PI;
g.drawLine(x, y, (int) (x + rh * Math.sin(ah)), (int) (y - rh
* Math.cos(ah)));
g.drawLine(x, y, (int) (x + rm * Math.sin(am)), (int) (y - rm
* Math.cos(am)));
}
g.setColor(colorRetainer);
}
public void run() {
while (true) {
repaint();
try {
Thread.sleep(30 * 1000);
} catch (InterruptedException ex) {
break;
}
}
}
public static void main(String[] a) {
JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Clock c = new Clock();
f.getContentPane().add("Center", c);
f.pack();
f.setSize(new Dimension(300, 300));
f.show();
}
}
Demonstrating the Box Component
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Polygon;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class RedBlueBox extends JComponent {
public void paintComponent(Graphics g) {
Insets insets = getInsets();
int endX = getWidth() - insets.right;
int endY = getHeight() - insets.bottom;
// get the top-left corner
int x = insets.left;
int y = insets.top;
g.setColor(Color.RED);
Polygon p = new Polygon();
p.addPoint(x, y);
p.addPoint(endX, y);
p.addPoint(x, endY);
g.fillPolygon(p);
g.setColor(Color.BLUE);
p.reset();
p.addPoint(endX, y);
p.addPoint(x, endY);
p.addPoint(endX, endY);
g.fillPolygon(p);
}
public static void main(String args[]) {
JFrame frame = new JFrame();
Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridLayout(0, 1));
JComponent comp = new RedBlueBox();
comp.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.PINK));
contentPane.add(comp);
comp = new RedBlueBox();
contentPane.add(comp);
frame.setSize(300, 200);
frame.show();
}
}
FontChooser dialog
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// FontPicker.java
//A quick test of the FontChooser dialog. (see FontChooser.java)
//
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
public class FontPicker extends JFrame {
Color c;
public FontPicker() {
super("JColorChooser Test Frame");
setSize(200, 100);
final JButton go = new JButton("Show FontChooser");
go.addActionListener(new ActionListener() {
final FontChooser chooser = new FontChooser(FontPicker.this);
boolean first = true;
public void actionPerformed(ActionEvent e) {
chooser.setVisible(true);
// If we got a real font choice, then update our go button
if (chooser.getNewFont() != null) {
go.setFont(chooser.getNewFont());
go.setForeground(chooser.getNewColor());
}
}
});
getContentPane().add(go);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String args[]) {
FontPicker fp = new FontPicker();
fp.setVisible(true);
}
}
//FontChooser.java
//A font chooser that allows users to pick a font by name, size, style, and
//color. The color selection is provided by a JColorChooser pane. This
//dialog builds an AttributeSet suitable for use with JTextPane.
//
class FontChooser extends JDialog implements ActionListener {
JColorChooser colorChooser;
JComboBox fontName;
JCheckBox fontBold, fontItalic;
JTextField fontSize;
JLabel previewLabel;
SimpleAttributeSet attributes;
Font newFont;
Color newColor;
public FontChooser(Frame parent) {
super(parent, "Font Chooser", true);
setSize(450, 450);
attributes = new SimpleAttributeSet();
// Make sure that any way the user cancels the window does the right
// thing
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
closeAndCancel();
}
});
// Start the long process of setting up our interface
Container c = getContentPane();
JPanel fontPanel = new JPanel();
fontName = new JComboBox(new String[] { "TimesRoman", "Helvetica",
"Courier" });
fontName.setSelectedIndex(1);
fontName.addActionListener(this);
fontSize = new JTextField("12", 4);
fontSize.setHorizontalAlignment(SwingConstants.RIGHT);
fontSize.addActionListener(this);
fontBold = new JCheckBox("Bold");
fontBold.setSelected(true);
fontBold.addActionListener(this);
fontItalic = new JCheckBox("Italic");
fontItalic.addActionListener(this);
fontPanel.add(fontName);
fontPanel.add(new JLabel(" Size: "));
fontPanel.add(fontSize);
fontPanel.add(fontBold);
fontPanel.add(fontItalic);
c.add(fontPanel, BorderLayout.NORTH);
// Set up the color chooser panel and attach a change listener so that
// color
// updates get reflected in our preview label.
colorChooser = new JColorChooser(Color.black);
colorChooser.getSelectionModel().addChangeListener(
new ChangeListener() {
public void stateChanged(ChangeEvent e) {
updatePreviewColor();
}
});
c.add(colorChooser, BorderLayout.CENTER);
JPanel previewPanel = new JPanel(new BorderLayout());
previewLabel = new JLabel("Here"s a sample of this font.");
previewLabel.setForeground(colorChooser.getColor());
previewPanel.add(previewLabel, BorderLayout.CENTER);
// Add in the Ok and Cancel buttons for our dialog box
JButton okButton = new JButton("Ok");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
closeAndSave();
}
});
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
closeAndCancel();
}
});
JPanel controlPanel = new JPanel();
controlPanel.add(okButton);
controlPanel.add(cancelButton);
previewPanel.add(controlPanel, BorderLayout.SOUTH);
// Give the preview label room to grow.
previewPanel.setMinimumSize(new Dimension(100, 100));
previewPanel.setPreferredSize(new Dimension(100, 100));
c.add(previewPanel, BorderLayout.SOUTH);
}
// Ok, something in the font changed, so figure that out and make a
// new font for the preview label
public void actionPerformed(ActionEvent ae) {
// Check the name of the font
if (!StyleConstants.getFontFamily(attributes).equals(
fontName.getSelectedItem())) {
StyleConstants.setFontFamily(attributes, (String) fontName
.getSelectedItem());
}
// Check the font size (no error checking yet)
if (StyleConstants.getFontSize(attributes) != Integer.parseInt(fontSize
.getText())) {
StyleConstants.setFontSize(attributes, Integer.parseInt(fontSize
.getText()));
}
// Check to see if the font should be bold
if (StyleConstants.isBold(attributes) != fontBold.isSelected()) {
StyleConstants.setBold(attributes, fontBold.isSelected());
}
// Check to see if the font should be italic
if (StyleConstants.isItalic(attributes) != fontItalic.isSelected()) {
StyleConstants.setItalic(attributes, fontItalic.isSelected());
}
// and update our preview label
updatePreviewFont();
}
// Get the appropriate font from our attributes object and update
// the preview label
protected void updatePreviewFont() {
String name = StyleConstants.getFontFamily(attributes);
boolean bold = StyleConstants.isBold(attributes);
boolean ital = StyleConstants.isItalic(attributes);
int size = StyleConstants.getFontSize(attributes);
//Bold and italic don"t work properly in beta 4.
Font f = new Font(name, (bold ? Font.BOLD : 0)
+ (ital ? Font.ITALIC : 0), size);
previewLabel.setFont(f);
}
// Get the appropriate color from our chooser and update previewLabel
protected void updatePreviewColor() {
previewLabel.setForeground(colorChooser.getColor());
// Manually force the label to repaint
previewLabel.repaint();
}
public Font getNewFont() {
return newFont;
}
public Color getNewColor() {
return newColor;
}
public AttributeSet getAttributes() {
return attributes;
}
public void closeAndSave() {
// Save font & color information
newFont = previewLabel.getFont();
newColor = previewLabel.getForeground();
// Close the window
setVisible(false);
}
public void closeAndCancel() {
// Erase any font information and then close the window
newFont = null;
newColor = null;
setVisible(false);
}
}
Oval Panel
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class OvalPanel extends JPanel {
Color color;
public OvalPanel() {
this(Color.black);
}
public OvalPanel(Color color) {
this.color = color;
}
public void paintComponent(Graphics g) {
int width = getWidth();
int height = getHeight();
g.setColor(color);
g.drawOval(0, 0, width, height);
}
public static void main(String args[]) {
JFrame frame = new JFrame("Oval Sample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = frame.getContentPane();
content.setLayout(new GridLayout(2, 2));
Color colors[] = { Color.red, Color.blue, Color.green, Color.yellow };
for (int i = 0; i < 4; i++) {
OvalPanel panel = new OvalPanel(colors[i]);
content.add(panel);
}
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Ploygon Button
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JToolTip;
import javax.swing.Timer;
public class PolygonButton extends JComponent implements MouseListener,
MouseMotionListener {
static public Color ACTIVE_COLOR = Color.red;
static public Color INACTIVE_COLOR = Color.darkGray;
protected String text;
protected Polygon polygon;
protected Rectangle rectangle;
protected boolean isActive;
protected static PolygonButton button;
public PolygonButton(Polygon p, String text) {
polygon = p;
setText(text);
setOpaque(false);
addMouseListener(this);
addMouseMotionListener(this);
rectangle = new Rectangle(polygon.getBounds()); // Bug alert!
rectangle.grow(1, 1);
setBounds(rectangle);
polygon.translate(-rectangle.x, -rectangle.y);
}
public void setText(String t) {
text = t;
}
public String getText() {
return text;
}
public void mouseMoved(MouseEvent e) {
if (!rectangle.contains(e.getX(), e.getY()) || e.isConsumed()) {
if (isActive) {
isActive = false;
repaint();
}
return; // quickly return, if outside our rectangle
}
int x = e.getX() - rectangle.x;
int y = e.getY() - rectangle.y;
boolean active = polygon.contains(x, y);
if (isActive != active)
setState(active);
if (active)
e.consume();
}
public void mouseDragged(MouseEvent e) {
}
protected void setState(boolean active) {
isActive = active;
repaint();
if (active) {
if (button != null)
button.setState(false);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
button = null;
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
mouseMoved(e);
}
public void mouseEntered(MouseEvent e) {
mouseMoved(e);
}
public void paint(Graphics g) {
g.setColor(isActive ? ACTIVE_COLOR : INACTIVE_COLOR);
g.drawPolygon(polygon);
}
public static void main(String[] argv) {
JFrame f = new JFrame();
f.setSize(400, 300);
Polygon p = new Polygon();
p.addPoint(10, 10);
p.addPoint(100, 300);
p.addPoint(300, 300);
p.addPoint(10, 10);
PolygonButton btn = new PolygonButton(p, "button");
f.getContentPane().add(btn);
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
f.addWindowListener(wndCloser);
f.setVisible(true);
}
}
The MyBean JavaBean Component
import java.awt.Point;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class MyBean {
private String names[];
private Point p;
private int length;
public String[] getNames() {
return names;
}
public Point getPoint() {
return p;
}
public int getLength() {
return length;
}
public void setNames(String newValue[]) {
names = newValue;
}
public void setPoint(Point newValue) {
p = newValue;
}
public void setLength(int newValue) {
length = newValue;
}
public static void main(String args[]) throws IOException {
// Create
MyBean saveme = new MyBean();
saveme.setNames(new String[] { "one", "two", "three" });
saveme.setPoint(new Point(15, 27));
saveme.setLength(6);
// Save
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream("saveme.xml")));
encoder.writeObject(saveme);
encoder.close();
}
}
The TrafficLight Component
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditorSupport;
import java.beans.SimpleBeanInfo;
import java.util.TooManyListenersException;
import java.util.Vector;
import javax.swing.JComponent;
public class TrafficLight extends JComponent {
public static String STATE_RED = "RED";
public static String STATE_YELLOW = "YELLOW";
public static String STATE_GREEN = "GREEN";
private static int DELAY = 3000;
private String defaultLightState;
private String currentLightState;
private boolean debug;
private Thread runner;
private transient ActionListener listener;
public TrafficLight() {
defaultLightState = currentLightState = STATE_RED;
setPreferredSize(new Dimension(100, 200));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Paint the outline of the traffic light
g.setColor(Color.white);
g.fillRect(2, 2, 96, 196);
// Debug
if (debug) {
System.out.println("Current light state is: " + currentLightState);
}
// Which light is on?
if (currentLightState.equals(STATE_RED)) {
g.setColor(Color.red);
g.fillOval(30, 30, 40, 40);
} else if (currentLightState.equals(STATE_YELLOW)) {
g.setColor(Color.yellow);
g.fillOval(30, 80, 40, 40);
} else if (currentLightState.equals(STATE_GREEN)) {
g.setColor(Color.green);
g.fillOval(30, 130, 40, 40);
}
}
public String getCurrentLightState() {
return currentLightState;
}
public void setCurrentLightState(String currentLightState) {
this.currentLightState = currentLightState;
if (currentLightState != STATE_YELLOW) {
if (debug) {
System.out.println("Firing action event");
}
ActionEvent ae = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, currentLightState);
fireActionPerformed(ae);
}
repaint();
}
public void setDefaultLightState(String defaultLightState) {
this.defaultLightState = defaultLightState;
currentLightState = defaultLightState;
repaint();
}
public String getDefaultLightState() {
return defaultLightState;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public boolean isDebug() {
return debug;
}
public void initiate() {
if (debug) {
System.out.println("Initiate traffic light cycle!");
}
startCycle();
}
private void startCycle() {
if (runner == null) {
Runnable runnable = new Runnable() {
public void run() {
if (debug) {
System.out.println("Started cycle");
}
while (runner != null) {
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
}
if (currentLightState.equals(STATE_RED)) {
setCurrentLightState(STATE_GREEN);
} else if (currentLightState.equals(STATE_GREEN)) {
setCurrentLightState(STATE_YELLOW);
} else {
setCurrentLightState(STATE_RED);
}
if (currentLightState.equals(defaultLightState)) {
runner = null;
}
}
}
};
runner = new Thread(runnable);
runner.start();
}
}
public void lightChange(ActionEvent x) {
String command = x.getActionCommand();
if (debug) {
System.out.println("Received event from traffic light: "
+ defaultLightState + " command: go to " + command);
}
if (command.equals(STATE_RED)) {
if (!currentLightState.equals(STATE_GREEN)) {
currentLightState = STATE_GREEN;
repaint();
}
} else if (command.equals(STATE_GREEN)) {
if (!currentLightState.equals(STATE_RED)) {
currentLightState = STATE_YELLOW;
repaint();
try {
Thread.sleep(DELAY);
} catch (InterruptedException e) {
}
currentLightState = STATE_RED;
repaint();
}
}
}
public synchronized void removeActionListener(ActionListener l) {
if (debug) {
System.out.println("Deregistering listener");
}
if (listener == l) {
listener = null;
}
}
public synchronized void addActionListener(ActionListener l)
throws TooManyListenersException {
if (debug) {
System.out.println("Registering listener");
}
if (listener == null) {
listener = l;
} else {
throw new TooManyListenersException();
}
}
protected void fireActionPerformed(ActionEvent e) {
if (debug) {
System.out.println("Firing action event");
}
if (listener != null) {
listener.actionPerformed(e);
}
}
}
class LightColorEditor extends PropertyEditorSupport {
public String[] getTags() {
String values[] = { TrafficLight.STATE_RED, TrafficLight.STATE_YELLOW,
TrafficLight.STATE_GREEN };
return values;
}
}
class TrafficLightBeanInfo extends SimpleBeanInfo {
public PropertyDescriptor[] getPropertyDescriptors() {
try {
PropertyDescriptor pd1 = new PropertyDescriptor("debug",
TrafficLight.class);
PropertyDescriptor pd2 = new PropertyDescriptor(
"defaultLightState", TrafficLight.class);
pd2.setPropertyEditorClass(LightColorEditor.class);
PropertyDescriptor result[] = { pd1, pd2 };
return result;
} catch (IntrospectionException e) {
System.err.println("Unexpected exception: " + e);
return null;
}
}
}
class MyBean {
private transient Vector actionListeners;
public synchronized void removeActionListener(ActionListener l) {
if (actionListeners != null && actionListeners.contains(l)) {
Vector v = (Vector) actionListeners.clone();
v.removeElement(l);
actionListeners = v;
}
}
public synchronized void addActionListener(ActionListener l) {
Vector v = (actionListeners == null) ? new Vector(2)
: (Vector) actionListeners.clone();
if (!v.contains(l)) {
v.addElement(l);
actionListeners = v;
}
}
protected void fireActionPerformed(ActionEvent e) {
if (actionListeners != null) {
Vector listeners = actionListeners;
int count = listeners.size();
for (int i = 0; i < count; i++) {
((ActionListener) listeners.elementAt(i)).actionPerformed(e);
}
}
}
}