Inputting numbers in a textfield via button on GUI - java

I've made a simple calculator
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JFrame implements ActionListener
{
GridLayout layout = new GridLayout(5, 1);
JLabel l1 = new JLabel("Number 1:");
JLabel l2 = new JLabel("Number 2:");
JLabel l3 = new JLabel("Answer:");
JTextField t1 = new JTextField(30);
JTextField t2 = new JTextField(30);
JTextField t3 = new JTextField(30);
JButton add = new JButton("+");
JButton sub = new JButton("-");
JButton mul = new JButton("*");
JButton div= new JButton("/");
Float ans;
public Calculator()
{
super("Calculator");
setSize(250, 200);
add(l1);
add(t1);
add(l2);
add(t2);
add(l3);
add(t3);
add(add);
add(sub);
add(mul);
add(div);
setLayout(layout);
add.addActionListener(this);
sub.addActionListener(this);
mul.addActionListener(this);
div.addActionListener(this);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
String n1 = t1.getText();
String n2 = t2.getText();
Float num1 = Float.parseFloat(n1);
Float num2 = Float.parseFloat(n2);
Object clicked = e.getSource();
if(add == clicked)
{
t3.setText(String.valueOf(num1+num2));
}
else if(sub == clicked)
{
t3.setText(String.valueOf(num1-num2));
}
else if(mul == clicked)
{
t3.setText(String.valueOf(num1*num2));
}
else
{
if(num2 == 0)
t3.setText("Can't Divide By Zero");
else
t3.setText(String.valueOf(num1/num2));
}
}
}
And a class to read it
public class UseMyFrame
{
public static void main(String[] args)
{
Calculator calc = new Calculator();
calc.setVisible(true);
}
}
My problem is I want to add another feature and put 9 buttons 1-9 that when pressed will place their respective numbers on the textfield, but I don't know how to set them to appear at the textfield, I first wanna do set.text but i realized how will the button know where to put its number because if I do set.text i need to either put it on textfield1 or textfield 2. I wanna make the number appear in textfield1 first then on textfield2 if there is already a number on textfield1

but I don't know how to set them to appear at the textfield
The Action you add to your JButton should extend TextAction. The TextAction has access to the last focused text component (so you don't have to keep track of this information yourself). Your code would be something like:
public class AddDigitAction extends TextAction
{
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
String digit = button.getActionCommand();
JTextComponent target = getTextComponent(e);
target.replaceSelection(digit);
}
You can use the same Action for all your buttons. The replaceSelection() method is an easy way to add text to the textfield. It will insert text at the last location of the caret in the text field.

So you need to create a boolean variable that will help you keep track of which field to put the number in. Then in the action of the button you can use that to decide.
if(first){
textField1.setText("1");
first = false;
}else{
textField2.setText("1");
first = true;
}
Now, this snippet is very simple and does not consider all the possibilities. It simply toggles between the two fields. You can extend it to what you need.

If you only want to have single digits:
if(t1.getText().length() == 0)
t1.setText(...);
else
t2.setText(...);
Better: Find out which textfield has the current focus (see javadocs) and put the digit at the end of that text:
tFocused.setText(tFocused.getText() + digit)

first set global int curs = 0 and global string screen
then at each numeric button put that code (all about concatenation of strings )
if(curs==0){
screen="1"; // change the number for each button
jTextField1.setText(screen);
a=Double.parseDouble(screen);
curs++;
}else{
screen=screen+"1"; // // change the number for each button
jTextField1.setText(screen);
a=Double.parseDouble(screen);
curs++;
}

Related

For some reason dynamically changing a Jlabel in my program, causes it to spam a bunch of errors, but not crash

When I try to dynamically update my jlabel1 with 'j1.setText("");' it doesn't work and causes it to spam out a ton of errors, any insight to a solution to this issue would be greatly appreciated. For testing purposes enter the sin: 130692544.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class SinChecker extends JFrame
{ //naming variables
JTextField t1;
static JLabel j, j1, j2, j3;
ButtonListener bl1;
ButtonListener2 bl2;
public SinChecker ()
{ //Get the container
Container c = getContentPane ();
//Set absolute layout
c.setLayout (null);
//Set Background Color
c.setBackground (Color.WHITE);
//Creating label Guess my number text
JLabel j = new JLabel ("Social Insurance Calculator");
j.setForeground (Color.BLUE);
j.setFont (new Font ("tunga", Font.BOLD, 24));
j.setSize (270, 20);
j.setLocation (30, 35);
//Creating label Enter a number.....
JLabel j1 = new JLabel ("Enter your S.I.N. below.");
j1.setFont (new Font ("tunga", Font.PLAIN, 17));
j1.setSize (270, 20);
j1.setLocation (66, 60);
//Creating a label Instuctions
JLabel j2 = new JLabel ("Enter a 9-digit Social Insurance Number");
j2.setFont (new Font ("tunga", Font.PLAIN, 17));
j2.setSize (270, 20);
j2.setLocation (10, 165);
//Creating a label Instuctions
JLabel j3 = new JLabel ("with no spaces between the digits please.");
j3.setFont (new Font ("tunga", Font.PLAIN, 17));
j3.setSize (270, 20);
j3.setLocation (10, 180);
//Creating TextField for x input guess
t1 = new JTextField (10);
t1.setSize (70, 30);
t1.setLocation (100, 80);
//creating 2 buttons
JButton b1 = new JButton ("Proceed");
b1.setSize (120, 30);
b1.setLocation (70, 200);
bl1 = new ButtonListener ();
b1.addActionListener (bl1);
JButton b2 = new JButton ("Re-enter");
b2.setSize (120, 30);
b2.setLocation (70, 250);
bl2 = new ButtonListener2 ();
b2.addActionListener (bl2);
//Place the components in the pane
c.add (j);
c.add (j1);
c.add (j2);
c.add (j3);
c.add (t1);
c.add (b1);
c.add (b2);
//Set the title of the window
setTitle ("Social Insurance Number Checker");
//Set the size of the window and display it
setSize (300, 350);
setVisible (true);
setDefaultCloseOperation (EXIT_ON_CLOSE);
}
//implement first action listener
private class ButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
int a = Integer.parseInt (t1.getText ());
boolean evenDigit = false; //alternates between true and false
int sum = 0; //accumulates the sum of the digits (as modified)
while (a > 0)
{
int nextDigit = a % 10; //grab the last digit
a = a / 10; //discard that digit
if (evenDigit)
{
//double it, then add the two digits of the result
nextDigit = 2 * nextDigit;
nextDigit = (nextDigit / 10) + (nextDigit % 10);
} // if(evenDigit)
sum = sum + nextDigit;
evenDigit = !evenDigit; //toggle the flag each time
} // end while
if (0 == sum % 10)
{
j1.setText ("That is a valid S.I.N.");
}
else
{
j1.setText ("That is not a valid S.I.N.");
}
t1.requestFocus ();
t1.selectAll ();
}
}
private class ButtonListener2 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
//reset the label messages
t1.setText ("");
t1.requestFocus ();
t1.selectAll ();
}
}
public static void main (String[] args)
{
new SinChecker ();
}
}
There are two problems...
The user of static for what should be instance fields
Variable shadowing
For example...
class SinChecker extends JFrame
{ //naming variables
// This is a BAD idea
static JLabel j, j1, j2, j3;
public SinChecker ()
{ //Get the container
//...
// Now what does SinCheck.j1 actually equal?
//Creating label Enter a number.....
JLabel j1 = new JLabel ("Enter your S.I.N. below.");
j1 is re-declared as a local variable within the constructor of SinChecker, making SinCheker.j1 still null
Even if you fix this issue, you should then ask yourself the question, what happens if you create a second copy of SinCheck? Which label are you now referencing...
Start by removing the static reference and the declaration of your labels in the constructor
class SinChecker extends JFrame
{ //naming variables
private JLabel j, j1, j2, j3;
public SinChecker ()
{ //Get the container
//...
// Now what does SinCheck.j1 actually equal?
//Creating label Enter a number.....
j1 = new JLabel ("Enter your S.I.N. below.");
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
Take a closer look at Laying Out Components Within a Container for more details
Your are re-declaring the JLabels in the method. You have already declared them as fields. And they become treated as local variables.
Replace:
JLabel j1 = new JLabel ("Enter your S.I.N. below.");
with
j1 = new JLabel ("Enter your S.I.N. below.");

Java Scroll bar

I want to add scroll bar to my text area so that if the user inputs a number greater than 20 the text are should have a scroll bar.
Basically I am trying to make a application where user inputs a number he wants the multiplication table and also he inputs up to what number he wants the table to be displayed.But my application show table up to 20 e.g 12 X 20 = 240. and the rest is hidden.
public class LayoutM extends JFrame implements ActionListener {
private JTextField num1;
private JTextField num2;
private JTextArea answer;
private JButton go;
private int num11;
private int num22;
public LayoutM(){
super("Multiplication");
setLayout(new FlowLayout());
Dimension numDim = new Dimension(60,20);
Dimension ansDim = new Dimension(200,300);
Dimension goDim = new Dimension(60,20);
num1 = new JTextField("Number");
num1.setPreferredSize(numDim);
num2 = new JTextField("Upto");
num2.setPreferredSize(numDim);
go = new JButton("GO");
num2.setPreferredSize(goDim);
answer = new JTextArea(20,20);
answer.setPreferredSize(ansDim);
answer.setEditable(false);
add(num1, BorderLayout.CENTER);
add(num2,BorderLayout.CENTER);
add(go,BorderLayout.CENTER);
add(answer,BorderLayout.SOUTH);
go.addActionListener(this);
}
public static void main(String[] args){
LayoutM ob = new LayoutM();
ob.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ob.setVisible(true);
ob.setSize(300,400);
ob.setResizable(false);
ob.setLocationRelativeTo(null);
}
public void actionPerformed(ActionEvent event){
try{
answer.setText(" ");
num11 = Integer.parseInt(num1.getText());
num22 = Integer.parseInt(num2.getText());
for(int count = 1; count < num22+1;count++){
answer.append(num11+ " X "+ count+" = " + num11*count+" \n");
}
}catch(Exception e){
JOptionPane.showMessageDialog(null, "No decimals allowed");
}
}
}
You should put the answer object into a new JScrollPane object, and add the scroll pane to your LayoutM.
So, in your fields you should add:
private JScrollPane scroll;
Instead of using
add(answer,BorderLayout.SOUTH);
You should use
add(scroll,BorderLayout.SOUTH);
And in your actionPerformed() method, you should change the number of rows according to the number you got from the user. Put this before the for loop:
if ( num22 > 20 ) {
answer.setRows(num22);
} else {
answer.setRows(20);
}

Program freezing(not responding) after button click no a Java app

Ok so I'm building to show students how a loop goes through an array, I have added 2 images to help explain and the code, the first is the result I get after I click go then it freezes . The Second image is what I'd like it to do after you put in the values of 1 in start, 15 in stop, 3 in step and click the Go Button. And then to be cleared on the click of Clear button. I think they probably related. Can anyone see the problem? Thanks in advanced!
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import javax.swing.JOptionPane;
public class Checkerboard extends Frame implements ActionListener
{
int[] blocksTextField = new int[15];
Panel blocksPanel = new Panel();
TextArea blocksDisplay[] = new TextArea[16];
TextField start = new TextField (3);
TextField stop = new TextField (3);
TextField step = new TextField (3);
//Colors
Color Red = new Color(255, 90, 90);
Color Green = new Color(140, 215, 40);
Color white = new Color(255,255,255);
//textField ints
int inputStart;
int inputStop;
int inputStep;
//Lables
Label custStartLabel = new Label ("Start : ");
Label custStopLabel = new Label ("Stop : ");
Label custStepLabel = new Label ("Step : ");
//Buttons
Button goButton = new Button("Go");
Button clearButton = new Button("Clear");
//panel for input textFields and lables
Panel textInputPanel = new Panel();
//Panel for buttons
Panel buttonPanel = new Panel();
public Checkerboard()
{//constructor method
//set the 3 input textFields to 0
inputStart = 0;
inputStop = 0;
inputStep = 0;
//set Layouts for frame and three panels
this.setLayout(new BorderLayout());
//grid layout (row,col,horgap,vertgap)
blocksPanel.setLayout(new GridLayout(4,4,10,10));
textInputPanel.setLayout(new GridLayout(2,3,20,10));
buttonPanel.setLayout(new FlowLayout());
//setEditable()
//setText()
//add components to blocks panel
for (int i = 0; i<16; i++)
{
blocksDisplay[i] = new TextArea(null,3,5,3);
if(i<6)
blocksDisplay[i].setText(" " +i);
else
blocksDisplay[i].setText(" " +i);
blocksDisplay[i].setEditable(false);
// blocksDisplay[i].setBackground(Red);
blocksPanel.add(blocksDisplay[i]);
}//end for
//add componets to panels
//add text fields
textInputPanel.add(start);
textInputPanel.add(stop);
textInputPanel.add(step);
//add lables
textInputPanel.add(custStartLabel);
textInputPanel.add(custStopLabel);
textInputPanel.add(custStepLabel);
//add button to panel
buttonPanel.add(goButton);
buttonPanel.add(clearButton);
//ADD ACTION LISTENRS TO BUTTONS (!IMPORTANT)
goButton.addActionListener(this);
clearButton.addActionListener(this);
add(blocksPanel, BorderLayout.NORTH);
add(textInputPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
//overridding the windowcClosing() method will allow the user to clisk the Close button
addWindowListener(
new WindowAdapter()
{
public void windowCloseing(WindowEvent e)
{
System.exit(0);
}
}
);
}//end of constructor method
public void actionPerformed(ActionEvent e)
{
//if & else if to see what button clicked and pull user input
if(e.getSource() == goButton) //if go clicked ...
{
System.out.println("go clicked");
try{
String inputStart = start.getText();
int varStart = Integer.parseInt(inputStart);
if (varStart<=0 || varStart>=15 )throw new NumberFormatException();
System.out.println("start = " + varStart);
// roomDisplay[available].setBackground(lightRed);
String inputStop = stop.getText();
int varStop = Integer.parseInt(inputStop);
if (varStop<=0 || varStart>=15 )throw new NumberFormatException();
System.out.println("stop = " + varStop);
String inputStep = step.getText();
int varStep = Integer.parseInt(inputStep);
if (varStep<=0 || varStep>=15 )throw new NumberFormatException();
System.out.println("step = " + varStep);
for (int i = varStart; i<varStop; varStep++)//ADD WHILE LOOP
{
blocksDisplay[i].setBackground(Red);
blocksDisplay[i].setText(" " +i);
}
}
catch (NumberFormatException ex)
{
JOptionPane.showMessageDialog(null, "You must enter a Start, Stop and Step value greater than 0 and less than 15",
"Error",JOptionPane.ERROR_MESSAGE);
}
}
else if(e.getSource() == clearButton ) //else if clear clicked ...
{
System.out.println("clear clicked");
}
//int available = room.bookRoom(smoking.getState());
//if (available > 0)//Rooms is available
}//end action performed method
public static void main(String[]args)
{
Checkerboard frame = new Checkerboard ();
frame.setBounds(50, 100, 300, 410);//changed size to make text feilds full charater size
frame.setTitle("Checkerboarder Array");
frame.setVisible(true);
}//end of main method
}
The problem is your loop: your loop variable name is i but you change the varStep variable instead of i so basically the loop variable never changes and thus the exit condition will never be true.
I believe you want to step i with varStep, so change your loop to:
for (int i = varStart; i<varStop; i += varStep)
// stuff inside loop
Take a look at this loop.
for (int i = varStart; i<varStop; varStep++)//ADD WHILE LOOP
{
blocksDisplay[i].setBackground(Red);
blocksDisplay[i].setText(" " +i);
}
It ends when i >= varStop, but neither i nor varStop change as a consequence of its execution, so it can never stop. You only increment varStep.
I think you want to increment i by varStep on each iteration instead, i.e. i += varStep
You use varStep++ in your for loop. I think you meant to do i+varStep.
The application freezes because you're never increasing i, resulting in an endless loop.

How can I determine which JCheckBox caused an event when the JCheckBox text is the same

I am working on a program that needs to determine which JCheckBox was selected. I am using three different button groups, two of which have overlapping text. I need to be able to determine which triggered the event so I can add the appropriate charge (COSTPERROOM vs COSTPERCAR) to the total(costOfHome). What I cant figure out is how to differentiate the checkbox source if the text is the same. I was thinking of trying to change the text on one button group to strings like "one" "two" etc, but that introduces a bigger problem with how I have created the checkboxes in the first place. Any ideas would be appreciated, thanks in advance!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JMyNewHome extends JFrame implements ItemListener {
// class private variables
private int costOfHome = 0;
// class arrays
private String[] homeNamesArray = {"Aspen", "Brittany", "Colonial", "Dartmour"};
private int[] homeCostArray = {100000, 120000, 180000, 250000};
// class constants
private final int MAXROOMS = 3;
private final int MAXCARS = 4;
private final int COSTPERROOM = 10500;
private final int COSTPERCAR = 7775;
JLabel costLabel = new JLabel();
// constructor
public JMyNewHome ()
{
super("My New Home");
setSize(450,150);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Font labelFont = new Font("Time New Roman", Font.BOLD, 24);
setJLabelString(costLabel, costOfHome);
costLabel.setFont(labelFont);
add(costLabel);
JCheckBox[] homesCheckBoxes = new JCheckBox[homeNamesArray.length];
ButtonGroup homeSelection = new ButtonGroup();
for (int i = 0; i < homeNamesArray.length; i++)
{
homesCheckBoxes[i] = new JCheckBox(homeNamesArray[i], false);
homeSelection.add(homesCheckBoxes[i]);
homesCheckBoxes[i].addItemListener(this);
add(homesCheckBoxes[i]);
}
JLabel roomLabel = new JLabel("Number of Rooms in Home");
add(roomLabel);
ButtonGroup roomSelection = new ButtonGroup();
JCheckBox[] roomCheckBoxes = new JCheckBox[MAXROOMS];
for (int i = 0; i < MAXROOMS; i++)
{
String intToString = Integer.toString(i + 2);
roomCheckBoxes[i] = new JCheckBox(intToString);
roomSelection.add(roomCheckBoxes[i]);
roomCheckBoxes[i].addItemListener(this);
add(roomCheckBoxes[i]);
}
JLabel carLabel = new JLabel("Size of Garage (number of cars)");
add(carLabel);
ButtonGroup carSelection = new ButtonGroup();
JCheckBox[] carCheckBoxes = new JCheckBox[MAXCARS];
for (int i = 0; i < MAXCARS; i++)
{
String intToString = Integer.toString(i);
carCheckBoxes[i] = new JCheckBox(intToString);
carSelection.add(carCheckBoxes[i]);
carCheckBoxes[i].addItemListener(this);
add(carCheckBoxes[i]);
}
setVisible(true);
}
private void setJLabelString(JLabel label, int cost)
{
String costOfHomeString = Integer.toString(cost);
label.setText("Cost of Configured Home: $ " + costOfHomeString + ".00");
invalidate();
validate();
repaint();
}
public void itemStateChanged(ItemEvent e) {
JCheckBox source = (JCheckBox) e.getItem();
String sourceText = source.getText();
//JLabel testLabel = new JLabel(sourceText);
//add(testLabel);
//invalidate();
//validate();
//repaint();
for (int i = 0; i < homeNamesArray.length; i++)
{
if (sourceText == homeNamesArray[i])
{
setJLabelString(costLabel, costOfHome + homeCostArray[i]);
}
}
}
}
I would
Use JRadioButtons for this rather than JCheckBoxes since I think it is GUI standard to have a set of JRadioButtons that only allow one selection rather than a set of JCheckBoxes.
Although you may have "overlapping text" you can set the button's actionCommand to anything you want to. So one set of buttons could have actionCommands that are "room count 2", "room count 3", ...
But even better, the ButtonGroup can tell you which toggle button (either check box or radio button) has been selected since if you call getSelection() on it, it will get you the ButtonModel of the selected button (or null if none have been selected), and then you can get the actionCommand from the model via its getActionCommand() method. Just first check that the model selected isn't null.
Learn to use the layout managers as they can make your job much easier.
For instance, if you had two ButtonGroups:
ButtonGroup fooBtnGroup = new ButtonGroup();
ButtonGroup barBtnGroup = new ButtonGroup();
If you add a bunch of JRadioButtons to these ButtonGroups, you can then check which buttons were selected for which group like so (the following code is in a JButton's ActionListener):
ButtonModel fooModel = fooBtnGroup.getSelection();
String fooSelection = fooModel == null ? "No foo selected" : fooModel.getActionCommand();
ButtonModel barModel = barBtnGroup.getSelection();
String barSelection = barModel == null ? "No bar selected" : barModel.getActionCommand();
System.out.println("Foo selected: " + fooSelection);
System.out.println("Bar selected: " + barSelection);
Assuming of course that you've set the actionCommand for your buttons.
Checkboxes have item listeners like any other swing component. I would decouple them, and simply add listeners to each
{
checkBox.addActionListener(actionListener);
}
http://www.java2s.com/Code/Java/Swing-JFC/CheckBoxItemListener.htm

Java button question

I am trying to get the user to input 2 fields. One is the volume of the pool and one is the volume of the hut tub. This then calculates the price of each, what I am having trouble is with if the user enters volume for the pool, then they can't enter anything for the hot tub and vise versa. This is what I have so far. Do I need to have 2 separate fields for this, or how can it be done?
Pretty much the string errors = ""; can be removed once I figure out how to only allow them to enter one set of numbers. Here is the calculate portion, the other part of the code is just the 3 labels.
pricePanel = new JPanel(new FlowLayout());
final JRadioButton poolPrice= new JRadioButton("Pool");
final JRadioButton tubPrice = new JRadioButton("Hot Tub");
poolPrice.setSelected(true);
ButtonGroup group = new ButtonGroup();
group.add(poolPrice);
group.add(tubPrice);
pricePanel.add(poolPrice);
pricePanel.add(tubPrice);
pricePanel.add(new JLabel("Enter the pool's volume: "));
final JTextField poolField = new JTextField(10);
pricePanel.add(poolField);
pricePanel.add(new JLabel("Enter the tub's volume: "));
final JTextField tubField = new JTextField(10);
pricePanel.add(tubField);
JButton calculatePrice = new JButton("Calculate Price");
calculatePrice.setMnemonic('C');
pricePanel.add(calculatePrice);
pricePanel.add(createExitButton());
pricePanel.add(new JLabel("The price is:$ "));
final JTextField priceField = new JTextField(10);
priceField.setEditable(false);
pricePanel.add(priceField);
calculatePrice.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
double pool = Double.parseDouble (poolField.getText());
double tub = Double.parseDouble(tubField.getText());
double price;
if (poolPrice.isSelected()) {
price = pool * 100;
} else {
price = tub * 75;
}
priceField.setText(df.format(price));
}
});
};
ActionListener priceListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == poolPrice) {
tubLabel.setEnabled(false);
tubField.setEnabled(false);
messageArea.setVisible(true);
} else if (e.getSource() == tubPrice) {
poolLabel.setEnabled(false);
poolField.setEnabled(false);
messageArea.setVisible(true);
}
}
};
poolPrice.addActionListener(priceListener);
tubPrice.addActionListener(priceListener);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hotTubsPanel = new JPanel(new FlowLayout());
final JRadioButton roundTub = new JRadioButton("Round Tub");
final JRadioButton ovalTub = new JRadioButton("Oval Tub");
roundTub.setSelected(true);
ButtonGroup group = new ButtonGroup();
group.add(roundTub);
group.add(ovalTub);
hotTubsPanel.add(roundTub);
hotTubsPanel.add(ovalTub);
hotTubsPanel.add(new JLabel("Enter the tub's length: "));
final JTextField lengthField = new JTextField(10);
hotTubsPanel.add(lengthField);
final JLabel widthLabel = new JLabel("Enter the tub's width*: ");
widthLabel.setEnabled(false);
hotTubsPanel.add(widthLabel);
final JTextField widthField = new JTextField(10);
widthField.setEnabled(false);
hotTubsPanel.add(widthField);
hotTubsPanel.add(new JLabel("Enter the tub's depth: "));
final JTextField depthField = new JTextField(10);
hotTubsPanel.add(depthField);
JButton calculateVolume = new JButton("Calculate Volume");
calculateVolume.setMnemonic('C');
hotTubsPanel.add(calculateVolume);
hotTubsPanel.add(createExitButton());
hotTubsPanel.add(new JLabel("The tub's volume is: "));
final JTextField volumeField = new JTextField(10);
volumeField.setEditable(false);
hotTubsPanel.add(volumeField);
final JTextArea messageArea = createMessageArea(1, 25,
"*Width will be set to the same value as length");
hotTubsPanel.add(messageArea);
calculateVolume.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (roundTub.isSelected()) {
widthField.setText(lengthField.getText());
}
ValidationResult result = validateFields(new JTextField[] {
lengthField, widthField, depthField });
String errors = "";
if (result.filled != 3) {
errors += "Please fill out all fields! ";
}
if (result.valid != 3 && result.filled != result.valid) {
errors += "Please enter valid numbers!";
}
if (errors != "") {
messageArea.setText(errors);
messageArea.setVisible(true);
} else {
messageArea.setVisible(false);
double length = Double.parseDouble(lengthField.getText());
double width = Double.parseDouble(widthField.getText());
double depth = Double.parseDouble(depthField.getText());
double volume;
if (roundTub.isSelected()) {
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
} else {
volume = Math.PI * Math.pow(length * width, 2) * depth;
}
volumeField.setText(df.format(volume));
}
}
});
ActionListener tubsListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == roundTub) {
widthLabel.setEnabled(false);
widthField.setEnabled(false);
widthField.setText(lengthField.getText());
messageArea.setText("Tub's width set to length");
messageArea.setVisible(true);
} else if (e.getSource() == ovalTub) {
widthLabel.setEnabled(true);
widthField.setEnabled(true);
messageArea.setVisible(false);
}
}
};
roundTub.addActionListener(tubsListener);
ovalTub.addActionListener(tubsListener);
}
Two text fields and only one result field could be confusing for the user. If there's only going to be one result field, there should only be one text field as well. The radio buttons Stian suggested would work, or even having two buttons, one for pool and one for hot tub (this would require only one click to get the other price). You should also have something in the result field indicating which one has been calculated, like "Pool price: $XX.XX" or "Hot tub price: $XX.XX". If you went with the buttons idea and labeled the buttons "Pool" and "Hot Tub", you could even do something fancy with the result, like setText(e.getActionCommand()+" price:"+price);.
Also, if (errors != "") is always going to be true. You are testing if your errors object is the same object as a new String object you are creating; it never will be. You should instead test for if (!errors.equals("")) or if (errors.length()!=0).

Categories

Resources