/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly
*/
// Sketch.java
//A sketching application with two dials: one for horizontal movement, one
//for vertical movement. The dials are instances of the JogShuttle class.
//
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
public class Sketch extends JPanel implements PropertyChangeListener,
ActionListener {
JogShuttle shuttle1;
JogShuttle shuttle2;
JPanel board;
JButton clear;
int lastX, lastY; // Keep track of the last point we drew.
public Sketch() {
super(true);
setLayout(new BorderLayout());
board = new JPanel(true);
board.setPreferredSize(new Dimension(300, 300));
board.setBorder(new LineBorder(Color.black, 5));
clear = new JButton("Clear Drawing Area");
clear.addActionListener(this);
shuttle1 = new JogShuttle(0, 300, 150);
lastX = shuttle1.getValue();
shuttle2 = new JogShuttle(0, 300, 150);
lastY = shuttle2.getValue();
shuttle1.setValuePerRevolution(100);
shuttle2.setValuePerRevolution(100);
shuttle1.addPropertyChangeListener(this);
shuttle2.addPropertyChangeListener(this);
shuttle1.setBorder(new BevelBorder(BevelBorder.RAISED));
shuttle2.setBorder(new BevelBorder(BevelBorder.RAISED));
add(board, BorderLayout.NORTH);
add(shuttle1, BorderLayout.WEST);
add(clear, BorderLayout.CENTER);
add(shuttle2, BorderLayout.EAST);
}
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName() == "value") {
Graphics g = board.getGraphics();
g.setColor(getForeground());
g.drawLine(lastX, lastY, shuttle1.getValue(), shuttle2.getValue());
lastX = shuttle1.getValue();
lastY = shuttle2.getValue();
}
}
public void actionPerformed(ActionEvent e) {
// The button must have been pressed.
Insets insets = board.getInsets();
Graphics g = board.getGraphics();
g.setColor(board.getBackground());
g.fillRect(insets.left, insets.top, board.getWidth() - insets.left
- insets.right, board.getHeight() - insets.top - insets.bottom);
}
public static void main(String[] args) {
UIManager.put(JogShuttleUI.UI_CLASS_ID, "BasicJogShuttleUI");
Sketch s = new Sketch();
JFrame frame = new JFrame("Sample Sketch Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(s);
frame.pack();
frame.setVisible(true);
}
}
//JogShuttle.java
//A custom jog shuttle component. (Some VCRs have such a thing for doing
//variable speed fast-forward and fast-reverse.) An example of using the
//JogShuttle can be found in Sketch.java.
//
class JogShuttle extends JComponent implements ChangeListener {
private BoundedRangeModel model;
// The dialInsets property tells how far the dial is inset
// from the sunken border.
private Insets dialInsets = new Insets(3, 3, 3, 3);
// The valuePerRevolution property tells how many units the dial
// takes to make a complete revolution.
private int valuePerRevolution;
// Constructors
public JogShuttle() {
init(new DefaultBoundedRangeModel());
}
public JogShuttle(BoundedRangeModel m) {
init(m);
}
public JogShuttle(int min, int max, int value) {
init(new DefaultBoundedRangeModel(value, 1, min, max));
}
protected void init(BoundedRangeModel m) {
setModel(m);
valuePerRevolution = m.getMaximum() - m.getMinimum();
setMinimumSize(new Dimension(80, 80));
setPreferredSize(new Dimension(80, 80));
updateUI();
}
public void setUI(JogShuttleUI ui) {
super.setUI(ui);
}
public void updateUI() {
setUI((JogShuttleUI) UIManager.getUI(this));
invalidate();
}
public String getUIClassID() {
return JogShuttleUI.UI_CLASS_ID;
}
public void setModel(BoundedRangeModel m) {
BoundedRangeModel old = model;
if (old != null)
old.removeChangeListener(this);
if (m == null)
model = new DefaultBoundedRangeModel();
else
model = m;
model.addChangeListener(this);
firePropertyChange("model", old, model);
}
public BoundedRangeModel getModel() {
return model;
}
// Methods
public void resetToMinimum() {
model.setValue(model.getMinimum());
}
public void resetToMaximum() {
model.setValue(model.getMaximum());
}
public void stateChanged(ChangeEvent e) {
repaint();
}
// Accessors and mutators
public int getMinimum() {
return model.getMinimum();
}
public void setMinimum(int m) {
int old = getMinimum();
if (m != old) {
model.setMinimum(m);
firePropertyChange("minimum", old, m);
}
}
public int getMaximum() {
return model.getMaximum();
}
public void setMaximum(int m) {
int old = getMaximum();
if (m != old) {
model.setMaximum(m);
firePropertyChange("maximum", old, m);
}
}
public int getValue() {
return model.getValue();
}
public void setValue(int v) {
int old = getValue();
if (v != old) {
model.setValue(v);
firePropertyChange("value", old, v);
}
}
// Display-specific properties
public int getValuePerRevolution() {
return valuePerRevolution;
}
public void setValuePerRevolution(int v) {
int old = getValuePerRevolution();
if (v != old) {
valuePerRevolution = v;
firePropertyChange("valuePerRevolution", old, v);
}
repaint();
}
public void setDialInsets(Insets i) {
dialInsets = i;
}
public void setDialInsets(int top, int left, int bottom, int right) {
dialInsets = new Insets(top, left, bottom, right);
}
public Insets getDialInsets() {
return dialInsets;
}
}
//JogShuttleUI.java
//Fill out the proper UIClassID information for our JogShuttle.
//
abstract class JogShuttleUI extends ComponentUI {
public static final String UI_CLASS_ID = "JogShuttleUI";
}