Converter.java
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Converter {
ConversionPanel metricPanel, usaPanel;
Unit[] metricDistances = new Unit[3];
Unit[] usaDistances = new Unit[4];
ConverterRangeModel dataModel = new ConverterRangeModel();
JPanel mainPane;
public Converter() {
metricDistances[0] = new Unit("Centimeters", 0.01);
metricDistances[1] = new Unit("Meters", 1.0);
metricDistances[2] = new Unit("Kilometers", 1000.0);
metricPanel = new ConversionPanel(this, "Metric System",
metricDistances,
dataModel);
usaDistances[0] = new Unit("Inches", 0.0254);
usaDistances[1] = new Unit("Feet", 0.305);
usaDistances[2] = new Unit("Yards", 0.914);
usaDistances[3] = new Unit("Miles", 1613.0);
usaPanel = new ConversionPanel(this, "U.S. System",
usaDistances,
new FollowerRangeModel(dataModel));
mainPane = new JPanel();
mainPane.setLayout(new GridLayout(2,1,5,5));
mainPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
mainPane.add(metricPanel);
mainPane.add(usaPanel);
resetMaxValues(true);
}
public void resetMaxValues(boolean resetCurrentValues) {
double metricMultiplier = metricPanel.getMultiplier();
double usaMultiplier = usaPanel.getMultiplier();
int maximum = ConversionPanel.MAX;
if (metricMultiplier > usaMultiplier) {
maximum = (int)(ConversionPanel.MAX *
(usaMultiplier/metricMultiplier));
}
dataModel.setMaximum(maximum);
if (resetCurrentValues) {
dataModel.setDoubleValue(maximum);
}
}
public static void main(String[] args) {
Converter converter = new Converter();
JFrame f = new JFrame("Converter");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setContentPane(converter.mainPane);
f.pack();
f.setVisible(true);
}
}
ConversionPanel.java
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.NumberFormat;
public class ConversionPanel extends JPanel {
DecimalField textField;
JComboBox unitChooser;
JSlider slider;
ConverterRangeModel sliderModel;
Converter controller;
Unit[] units;
String title;
final static int MAX = 10000;
ConversionPanel(Converter myController, String myTitle,
Unit[] myUnits,
ConverterRangeModel myModel) {
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder(myTitle),
BorderFactory.createEmptyBorder(5,5,5,5)));
controller = myController;
units = myUnits;
title = myTitle;
sliderModel = myModel;
NumberFormat numberFormat = NumberFormat.getNumberInstance();
numberFormat.setMaximumFractionDigits(2);
textField = new DecimalField(0, 10, numberFormat);
textField.setValue(sliderModel.getDoubleValue());
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sliderModel.setDoubleValue(textField.getValue());
}
});
unitChooser = new JComboBox();
for (int i = 0; i < units.length; i++) {
unitChooser.addItem(units[i].description);
}
unitChooser.setSelectedIndex(0);
sliderModel.setMultiplier(units[0].multiplier);
unitChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int i = unitChooser.getSelectedIndex();
sliderModel.setMultiplier(units[i].multiplier);
controller.resetMaxValues(false);
}
});
slider = new JSlider(sliderModel);
sliderModel.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
textField.setValue(sliderModel.getDoubleValue());
}
});
JPanel unitGroup = new JPanel() {
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
return new Dimension(150,
super.getPreferredSize().height);
}
public Dimension getMaximumSize() {
return getPreferredSize();
}
};
unitGroup.setBorder(BorderFactory.createEmptyBorder(
0,0,0,5));
unitGroup.setLayout(new BoxLayout(unitGroup,
BoxLayout.Y_AXIS));
unitGroup.add(textField);
unitGroup.add(slider);
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(unitGroup);
add(unitChooser);
unitGroup.setAlignmentY(TOP_ALIGNMENT);
unitChooser.setAlignmentY(TOP_ALIGNMENT);
}
public double getMultiplier() {
return sliderModel.getMultiplier();
}
public double getValue() {
return sliderModel.getDoubleValue();
}
}
ConverterRangeModel.java
import javax.swing.*;
import javax.swing.event.*;
public class ConverterRangeModel implements BoundedRangeModel {
protected ChangeEvent changeEvent = null;
protected EventListenerList listenerList = new EventListenerList();
protected int maximum = 10000;
protected int minimum = 0;
protected int extent = 0;
protected double value = 0.0;
protected double multiplier = 1.0;
protected boolean isAdjusting = false;
public ConverterRangeModel() {
}
public double getMultiplier() {
return multiplier;
}
public void setMultiplier(double multiplier) {
this.multiplier = multiplier;
fireStateChanged();
}
public int getMaximum() {
return maximum;
}
public void setMaximum(int newMaximum) {
setRangeProperties(value, extent, minimum, newMaximum, isAdjusting);
}
public int getMinimum() {
return (int)minimum;
}
public void setMinimum(int newMinimum) {
System.out.println("In ConverterRangeModel setMinimum");
}
public int getValue() {
return (int)getDoubleValue();
}
public void setValue(int newValue) {
setDoubleValue((double)newValue);
}
public double getDoubleValue() {
return value;
}
public void setDoubleValue(double newValue) {
setRangeProperties(newValue, extent, minimum, maximum, isAdjusting);
}
public int getExtent() {
return (int)extent;
}
public void setExtent(int newExtent) {
}
public boolean getValueIsAdjusting() {
return isAdjusting;
}
public void setValueIsAdjusting(boolean b) {
setRangeProperties(value, extent, minimum, maximum, b);
}
public void setRangeProperties(int newValue,
int newExtent,
int newMin,
int newMax,
boolean newAdjusting) {
System.out.println("In ConverterRangeModel setRangeProperties");
setRangeProperties((double)newValue,
newExtent,
newMin,
newMax,
newAdjusting);
}
public void setRangeProperties(double newValue,
int unusedExtent,
int unusedMin,
int newMax,
boolean newAdjusting) {
if (newMax <= minimum) {
newMax = minimum + 1;
if (DEBUG) {
System.out.println("maximum raised by 1 to " + newMax);
}
}
if (Math.round(newValue) > newMax) { //allow some rounding error
newValue = newMax;
}
boolean changeOccurred = false;
if (newValue != value) {
value = newValue;
changeOccurred = true;
}
if (newMax != maximum) {
maximum = newMax;
changeOccurred = true;
}
if (newAdjusting != isAdjusting) {
maximum = newMax;
isAdjusting = newAdjusting;
changeOccurred = true;
}
if (changeOccurred) {
fireStateChanged();
}
}
/*
* The rest of this is event handling code copied from
* DefaultBoundedRangeModel.
*/
public void addChangeListener(ChangeListener l) {
listenerList.add(ChangeListener.class, l);
}
public void removeChangeListener(ChangeListener l) {
listenerList.remove(ChangeListener.class, l);
}
protected void fireStateChanged() {
Object[] listeners = listenerList.getListenerList();
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);
}
}
}
}
DecimalField.java
import javax.swing.*;
import javax.swing.text.*;
import java.awt.Toolkit;
import java.text.*;
public class DecimalField extends JTextField {
private NumberFormat format;
public DecimalField(double value, int columns, NumberFormat f) {
super(columns);
setDocument(new FormattedDocument(f));
format = f;
setValue(value);
}
public double getValue() {
double retVal = 0.0;
try {
retVal = format.parse(getText()).doubleValue();
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("getValue: could not parse: " + getText());
}
return retVal;
}
public void setValue(double value) {
setText(format.format(value));
}
}
FollowerRangeModel.java
import javax.swing.*;
import javax.swing.event.*;
public class FollowerRangeModel extends ConverterRangeModel
implements ChangeListener {
ConverterRangeModel dataModel;
public FollowerRangeModel(ConverterRangeModel dataModel) {
this.dataModel = dataModel;
dataModel.addChangeListener(this);
}
public void stateChanged(ChangeEvent e) {
fireStateChanged();
}
public int getMaximum() {
int modelMax = dataModel.getMaximum();
double multiplyBy = dataModel.getMultiplier()/multiplier;
return (int)(modelMax * multiplyBy);
}
public void setMaximum(int newMaximum) {
dataModel.setMaximum((int)(newMaximum *
(multiplier/dataModel.getMultiplier())));
}
public int getValue() {
return (int)getDoubleValue();
}
public void setValue(int newValue) {
setDoubleValue((double)newValue);
}
public double getDoubleValue() {
return dataModel.getDoubleValue()
* dataModel.getMultiplier()
/ multiplier;
}
public void setDoubleValue(double newValue) {
dataModel.setDoubleValue(
newValue * multiplier
/ dataModel.getMultiplier());
}
public int getExtent() {
return super.getExtent();
}
public void setExtent(int newExtent) {
super.setExtent(newExtent);
}
public void setRangeProperties(int value,
int extent,
int min,
int max,
boolean adjusting) {
double multiplyBy = multiplier/dataModel.getMultiplier();
dataModel.setRangeProperties(value*multiplyBy,
extent, min,
(int)(max*multiplyBy),
adjusting);
}
}
FormattedDocument.java
import javax.swing.*;
import javax.swing.text.*;
import java.awt.Toolkit;
import java.text.*;
import java.util.Locale;
public class FormattedDocument extends PlainDocument {
private Format format;
public FormattedDocument(Format f) {
format = f;
}
public Format getFormat() {
return format;
}
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(offs, currentText.length());
String proposedResult = beforeOffset + str + afterOffset;
try {
format.parseObject(proposedResult);
super.insertString(offs, str, a);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("insertString: could not parse: "
+ proposedResult);
}
}
public void remove(int offs, int len) throws BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(len + offs,
currentText.length());
String proposedResult = beforeOffset + afterOffset;
try {
if (proposedResult.length() != 0)
format.parseObject(proposedResult);
super.remove(offs, len);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("remove: could not parse: " + proposedResult);
}
}
}
Unit.java
public class Unit {
String description;
double multiplier;
Unit(String description, double multiplier) {
super();
this.description = description;
this.multiplier = multiplier;
}
public String toString() {
String s = "Meters/" + description + " = " + multiplier;
return s;
}
}
|