import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
// For this app, in addition to implementing an ActionListener that will
// tell us about button and radio button clicks, we also implement a
// KeyListener that will tell us about keypress events.
public class Temperatures extends JFrame
implements ActionListener, KeyListener
{
// Here are the Swing components that we want to access within the
// various event functions
private JTextField textLowTemperature; // for entry and display of a low temperature
private JTextField textHighTemperature; // for entry and display of high temperature
private JLabel labelMean; // for display of the average (mean) temperature
// And here are two Temperature objects that we'll use in this app
private Temperature highTemperature;
private Temperature lowTemperature;
// Again, here is where we define what our window looks like and what's inside it.
public Temperatures()
{
// Set the title bar and size of the window
setTitle("Temperatures");
setSize(500,150);
// This time, adding a label to the NORTH (top) of the BorderLayout
add(new JLabel("Enter the high and low temperatures:"), BorderLayout.NORTH);
// The JPanel in the center of the BorderLayout will have two
// JTextFields (each preceded by a JLabel), and another JLabel that
// will be used to display the mean temperature that we compute.
JPanel middlePanel = new JPanel();
middlePanel.add(new JLabel("High temperature:"));
textHighTemperature = new JTextField("100",4);
// Add a KeyListener to the text field
textHighTemperature.addKeyListener(this);
middlePanel.add(textHighTemperature);
middlePanel.add(new JLabel("Low temperature:"));
textLowTemperature = new JTextField("0",4);
// Add another KeyListener
textLowTemperature.addKeyListener(this);
middlePanel.add(textLowTemperature);
middlePanel.add(new JLabel("Mean:"));
// The Unicode character 00B0 is a degree symbol. To put a special Unicode
// character in a string, use \\u followed by the hexadecimal value. So
// here we use \\u00b0 (okay, I had to use \\ to show it to you here to
// prevent compiler errors, even though this is within a comment!)
// The "C" is at the end because I DO want "C" for Celsius!
labelMean = new JLabel("50\u00b0C");
middlePanel.add(labelMean);
add(middlePanel, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
// You make the radio buttons work together by
// adding them to a ButtonGroup.
ButtonGroup scaleGroup = new ButtonGroup();
// Here's the first radio button. Use an ActionListener to handle
// click events with radio buttons.
JRadioButton radioFahrenheit = new JRadioButton("Fahrenheit",false);
radioFahrenheit.addActionListener(this);
// Since there are multiple radio buttons, set a unique ActionCommand
// for each.
radioFahrenheit.setActionCommand("Fahrenheit");
// Add it to the ButtonGroup so the radio buttons act together in a
// group, and add it to the JPanel it displays in our window.
scaleGroup.add(radioFahrenheit);
bottomPanel.add(radioFahrenheit);
// Here are the other two radio buttons. Copy above. Paste. Edit.
JRadioButton radioCelsius = new JRadioButton("Celsius",true);
radioCelsius.addActionListener(this);
radioCelsius.setActionCommand("Celsius");
scaleGroup.add(radioCelsius);
bottomPanel.add(radioCelsius);
JRadioButton radioKelvin = new JRadioButton("Kelvin",true);
radioKelvin.addActionListener(this);
radioKelvin.setActionCommand("Kelvin");
scaleGroup.add(radioKelvin);
bottomPanel.add(radioKelvin);
// Add the radio button JPanel to the bottom of the window's BorderLayout
add(bottomPanel, BorderLayout.SOUTH);
// Now that the components for our window are all created, initialize
// other variables. Here we create two Temperature instances with
// starting values 100 and 0 degrees Celsius. The default constructor will
// use 0 degrees Celsius.
highTemperature = new Temperature(100.0);
lowTemperature = new Temperature();
}
// These are the ActionListener events for the clicks on the
// radio buttons.
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Fahrenheit"))
{
// This tells ALL our Temperature instances to use Fahrenheit
// as the current input and output scale. This is a static
// method, and the flag you use to indicate the currently-used
// scale should also be static so that it applies to ALL
// temperature instances.
Temperature.useFahrenheit();
redisplay(); // see this method below
}
else if (e.getActionCommand().equals("Celsius"))
{
// another static method
Temperature.useCelsius();
redisplay();
}
else if (e.getActionCommand().equals("Kelvin"))
{
// and one more static method
Temperature.useKelvin();
redisplay();
}
}
// KeyListener tells us about three Key Events, and if we implement
// a KeyListener we MUST provide methods to handle all three. Here
// we're acting on keyReleased because we want to look at the text
// fields AFTER the new keypress entered into it.
public void keyReleased(KeyEvent e)
{
// To distinguish between which JTextField generated the
// key event, we can use e.getSource(). textHighTemperature is
// one of the two JTextFields to which we attached KeyListeners.
if (e.getSource() == textHighTemperature)
{
// After the keypress, get the content of the text field
String s = textHighTemperature.getText();
// We just want the numeric value, so we have to remove the
// degree symbol and C, F, or K if they are there. Use some
// String methods to do so.
// First get the location of the degree symbol, IF there is one.
int degreeSymbol = s.indexOf('\u00b0');
// -1 if not there.
if (degreeSymbol>=0)
// if it was there, extract only the characters before it
s = s.substring(0,degreeSymbol);
// and convert those numerals (we hope!) to type double
double value = Double.parseDouble(s);
// use the Temperature object's set method!
highTemperature.set(value);
showMean(); // see this method below.
}
// Do the same for the other text field. The "if" here is really
// redundant, since there is only this one other possibility.
else if (e.getSource() == textLowTemperature)
{
String s = textLowTemperature.getText();
int degreeSymbol = s.indexOf('\u00b0');
if (degreeSymbol>=0)
s = s.substring(0,degreeSymbol);
double value = Double.parseDouble(s);
lowTemperature.set(value);
showMean();
}
}
// Three keyListener methods are required when you "implement KeyListener"
// These are the other two that are required, but we don't use them.
// So these are just "stubs" with no code:
public void keyPressed(KeyEvent e) {}
public void keyTyped(KeyEvent e){}
// The sequence of key events is keyPressed -> keyTyped -> keyReleased
// keyTyped lets us check the key code before it is actually put into
// the text field.
// Re-display the contents of the text boxes using the current Temperature
// scale, then re-compute and display the mean temperature.
private void redisplay()
{
textHighTemperature.setText(""+highTemperature);
textLowTemperature.setText(""+lowTemperature);
showMean();
}
// Re-compute the mean temperature using the Temperature object's
// "mean" method, then display the result in the output JLabel
private void showMean()
{
Temperature mean = highTemperature.mean(lowTemperature);
labelMean.setText(""+mean);
}
//The same GUI startup. Copy. Paste. Edit.
public static void main(String args[])
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Temperatures frame = new Temperatures();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
private static final long serialVersionUID = 1L;
}