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).
Related
New programmer here, I have been working for a few days on this bit of code that is meant to create a UI where I input a basement's perimeter length (textfield integer), if a new pump is needed (combobox string), if there is an outlet nearby (combobox string), and how many hours It will take to prepare a site (textfield integer), and I calculate my costs to complete a job. I was able to set up a UI where I can enter the inputs and press a button to calculate but I'm having trouble connecting the button I made to the formula I made to generate a price. Here is my code:
package packagepackage;
import packagepackage.HintTextFieldUI;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CP_GUI implements ActionListener {
String[] sumpo = {"New sump pump","Existing sump pump"};
String[] electo = {"There is an outlet within 6 feet of sump pump","There is no outlet nearby, or I do not need a new one"};
Integer estimatex = 0;
String esto = String.valueOf(estimatex);
public volatile String estimatoof = "Estimated Cost: ${}".format(esto);
private JComboBox sump = new JComboBox(sumpo);
private JComboBox elec = new JComboBox(electo);
private JTextField linear = new JTextField();
private JTextField prep = new JTextField();
private JLabel title = new JLabel("Drain Tile Calculator");
private JButton calculate = new JButton("Calculate!");
public JLabel estimate = new JLabel(estimatoof);
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
public CP_GUI() {
linear.addActionListener(this);
calculate.addActionListener(this);
elec.addActionListener(this);
sump.addActionListener(this);
prep.addActionListener(this);
// the panel with the button and text
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(400, 400, 100, 100));
panel.setLayout(new GridLayout(0, 1));
panel.add(linear);
panel.add(sump);
panel.add(elec);
panel.add(prep);
frame.add(panel, BorderLayout.CENTER);
panel.add(title);
calculate.addActionListener(this);
panel.add(calculate);
// set up the frame and display it
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Drain Tile Calculator");
frame.pack();
frame.setVisible(true);
linear.setUI(new HintTextFieldUI("Perimeter length", true));
prep.setUI(new HintTextFieldUI("Hours of preptime", true));}
// create one Frame
public static void main(String[] args) {
new CP_GUI();
}
#Override
public void actionPerformed(ActionEvent e){
// TODO Auto-generated method stub
if(e.getSource()==linear) {String input = linear.getText();
Integer pars = Integer.parseInt(input);
Integer distVar = pars *= 13;
estimatex += distVar;
} else if (e.getSource()==sump) {String inputa = sump.getToolTipText();
int sumpa = 0;
if(inputa == "New sump pump" | inputa == "yes") {
sumpa += 260;}
estimatex += sumpa;
} else if (e.getSource()==elec) {String inputb =elec.getToolTipText();
int eleca = 0;
if("There is an outlet within 6 feet of the sump pump".equals(inputb)) {
eleca += 1;
}
eleca *= 280;
estimatex += eleca;
}
else if (e.getSource()==prep) {String inputc = prep.getText();
int parsa = Integer.parseInt(inputc);
int prepCost = parsa += 1;
prepCost *= 110;
estimatex += prepCost;
} else if (e.getSource()==linear) {
String disto = linear.getText();
int di = Integer.parseInt(disto);
di *= 13;
String pumpo = (String)sump.getSelectedItem();
int sumpo = 0;
if ("New sump pump".equals(pumpo)) {
sumpo += 260;
}
String ele = (String)elec.getSelectedItem();
int elc = Integer.parseInt(ele);
elc *= 280;
String clea = prep.getText();
int cla = Integer.parseInt(clea);
cla += 1;
cla *= 110;
int cali = 0;
cali += di;
cali += sumpo;
cali += elc;
cali += cla;
estimatex = cali;
}
}
}
Edit: Made the suggested edits made so far and now the UI opens and works, the only issue is that the estimated price does not show up. Am I connecting the action listener correctly?
Your "primary" problem is right here...
String disto = String.valueOf(linear);
where linear is a JTextField, so the above call will generate something like...
javax.swing.JTextField[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.apple.laf.AquaTextFieldBorder#4e323305,flags=288,maximumSize=,minimumSize=,preferredSize=,caretColor=javax.swing.plaf.ColorUIResource[r=0,g=0,b=0],disabledTextColor=javax.swing.plaf.ColorUIResource[r=128,g=128,b=128],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=com.apple.laf.AquaImageFactory$SystemColorProxy[r=0,g=0,b=0],selectionColor=com.apple.laf.AquaImageFactory$SystemColorProxy[r=165,g=205,b=255],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]
which is obviously not what you're looking for.
You should probably be just doing something like...
String disto = linear.getText();
pumpo == "New sump pump" is also not how you compare a String in Java, you should be using "New sump pump".equals(pumpo) ... but I suspect you're going to have the same issues as mentioned above.
I really recommend you take the time to read through Creating a GUI With Swing as well as taking the time to come to grips with the core basics of the language
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);
}
This is my 1st post here and I am hoping if I could get some help on a school project I have. The project is to make a calculator in Java and I have made it and it works fine for the most part, only problem I am having is that when I get an answer - lets say 5+5=10 and 10 is displayed, when I want to enter another number lets say I want to enter in 8*10 and in order to do that I write in 8, instead of deleting the previous answer which is 10 and write 8 instead of that number it will write 8 after 10, so it will be 108. What I want is for the previous answer to be deleted once I enter in a new number after an answer has been give. I hope I explained it good, here is my code and I would love some assistance on the matter since everything I tried hasn't worked. Thanks in advance.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator_UI implements ActionListener {
JFrame frame = new JFrame("Calculator");
JPanel panel = new JPanel();
JTextArea text = new JTextArea(1, 20);
JButton but1 = new JButton("1");
JButton but2 = new JButton("2");
JButton but3 = new JButton("3");
JButton but4 = new JButton("4");
JButton but5 = new JButton("5");
JButton but6 = new JButton("6");
JButton but7 = new JButton("7");
JButton but8 = new JButton("8");
JButton but9 = new JButton("9");
JButton but0 = new JButton("0");
JButton butadd = new JButton("+");
JButton butsub = new JButton("-");
JButton butmulti = new JButton("*");
JButton butdiv = new JButton("/");
JButton buteq = new JButton("=");
JButton butclear = new JButton("C");
Double number1, number2, result;
int addc = 0, subc = 0, multic = 0, divc = 0;
public void ui() {
frame.setVisible(true);
frame.setSize(230, 200);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
panel.add(text);
panel.add(but1);
panel.add(but2);
panel.add(but3);
panel.add(but4);
panel.add(but5);
panel.add(but6);
panel.add(but7);
panel.add(but8);
panel.add(but9);
panel.add(but0);
panel.add(butadd);
panel.add(butsub);
panel.add(butmulti);
panel.add(butdiv);
panel.add(buteq);
panel.add(butclear);
but1.addActionListener(this);
but1.setBackground(Color.cyan);
but2.addActionListener(this);
but2.setBackground(Color.cyan);
but3.addActionListener(this);
but3.setBackground(Color.cyan);
but4.addActionListener(this);
but4.setBackground(Color.cyan);
but5.addActionListener(this);
but5.setBackground(Color.cyan);
but6.addActionListener(this);
but6.setBackground(Color.cyan);
but7.addActionListener(this);
but7.setBackground(Color.cyan);
but8.addActionListener(this);
but8.setBackground(Color.cyan);
but9.addActionListener(this);
but9.setBackground(Color.cyan);
but0.addActionListener(this);
but0.setBackground(Color.cyan);
butadd.addActionListener(this);
butadd.setBackground(Color.cyan);
butsub.addActionListener(this);
butsub.setBackground(Color.cyan);
butmulti.addActionListener(this);
butmulti.setBackground(Color.cyan);
butdiv.addActionListener(this);
butdiv.setBackground(Color.cyan);
buteq.addActionListener(this);
buteq.setBackground(Color.cyan);
butclear.addActionListener(this);
butclear.setBackground(Color.cyan);
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == butclear) {
number1 = 0.0;
number2 = 0.0;
text.setText("");
}
if (source == but1) {
text.append("1");
}
if (source == but2) {
text.append("2");
}
if (source == but3) {
text.append("3");
}
if (source == but4) {
text.append("4");
}
if (source == but5) {
text.append("5");
}
if (source == but6) {
text.append("6");
}
if (source == but7) {
text.append("7");
}
if (source == but8) {
text.append("8");
}
if (source == but9) {
text.append("9");
}
if (source == but0) {
text.append("0");
}
if (source == butadd) {
number1 = number_reader();
text.setText("");
addc = 1;
subc = 0;
multic = 0;
divc = 0;
}
if (source == butsub) {
number1 = number_reader();
text.setText("");
addc = 0;
subc = 1;
multic = 0;
divc = 0;
}
if (source == butmulti) {
number1 = number_reader();
text.setText("");
addc = 0;
subc = 0;
multic = 1;
divc = 0;
}
if (source == butdiv) {
number1 = number_reader();
text.setText("");
addc = 0;
subc = 0;
multic = 0;
divc = 1;
}
if (source == buteq) {
number2 = number_reader();
if (addc == 1) {
result = number1 + number2;
text.setText(Double.toString(result));
}
if (subc == 1) {
result = number1 - number2;
text.setText(Double.toString(result));
}
if (multic == 1) {
result = number1 * number2;
text.setText(Double.toString(result));
}
if (divc == 1) {
result = number1 / number2;
text.setText(Double.toString(result));
}
}
}
public double number_reader() {
Double num1;
String s;
s = text.getText();
num1 = Double.valueOf(s);
return num1;
}
}
When the user presses = and the result is printed, you should set a flag to true, so that the next time a number button is pressed, the result is first erased.
In fact you should even transform your whole logic into a state diagram, because if, for example, the user presses + twice, you should probably display an error message or ignore the second +, instead of reading the current number. Each state should define what happens when any button is pressed, and what the next state is depending on which button is pressed.
Since a GUI can be smarter than a real calculator, each state could also define which buttons are enabled and which ones are disabled.
I was able to program this, and I don't have any errors that I can see, and it even displays the gui. I'm pretty sure I assigned the buttons properly. But the GUI is temperamental, and when I run it, it displays but sometimes the insides of the gui disappear when I enter values. But it calculates nCr, just not pCr.
I have a driver class. Pretty sure it's implemented properly. Here's my panel class. I'm wondering what's wrong and why the GUI doesn't function properly
I realize this is a lot of code. I'm not expecting anyone to rewrite this for me. I just want to know what I'm doing wrong, and how I can go about correcting it.
Thanks.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import javax.swing.JOptionPane;
public class PermCombCalc extends JPanel {
JButton permButton = new JButton();
JButton combButton = new JButton();
JButton clearButton = new JButton();
JTextField npermField = new JTextField();
JTextField rperField = new JTextField();
JTextField nchooseField = new JTextField();
JTextField rchooseField = new JTextField();
JTextField pAnswerField = new JTextField();
JTextField cAnswerField = new JTextField();
public PermCombCalc() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(1000, 700));
JLabel permLabel = new JLabel("Permutation:");
permLabel.setBounds(10, 20, 100, 20);
permLabel.setForeground(Color.BLACK);
add(permLabel);
JLabel combLabel = new JLabel("Combination:");
combLabel.setBounds(215, 20, 75, 20);
combLabel.setForeground(Color.BLACK);
add(combLabel);
// Creating Permutation Button
JLabel PnrLabel = new JLabel("P (n,r)");
PnrLabel.setForeground(Color.black);
permButton.setBounds(10, 115, 100, 25);
add(permButton);
permButton.add(PnrLabel);
// Action Listener for permbutton
permButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
permButton.setActionCommand("Perm");
permButton.addActionListener(new ButtonListener());
}
});
// Creating combination button
JLabel CnrLabel = new JLabel("C(n, r)");
CnrLabel.setForeground(Color.black);
combButton.setBounds(190, 115, 100, 25);
add(combButton);
combButton.add(CnrLabel);
// ActionListener
combButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
combButton.setActionCommand("comb");
combButton.addActionListener(new ButtonListener());
}
});
// Text fields for n and r
npermField.setBounds(23, 50, 60, 20);
add(npermField);
nchooseField.setBounds(230, 50, 60, 20);
add(nchooseField);
rperField.setBounds(23, 80, 60, 20);
add(rperField);
rchooseField.setBounds(230, 80, 60, 20);
add(rchooseField);
// Input fields
JLabel npLabel = new JLabel("n:");
npLabel.setForeground(Color.black);
npLabel.setBounds(10, 55, 10, 10);
add(npLabel);
JLabel ncLabel = new JLabel("n:");
ncLabel.setForeground(Color.BLACK);
ncLabel.setBounds(217, 55, 10, 10);
add(ncLabel);
JLabel rpLabel = new JLabel("r:");
rpLabel.setForeground(Color.BLACK);
rpLabel.setBounds(10, 85, 10, 10);
add(rpLabel);
JLabel rcLabel = new JLabel("r:");
rcLabel.setForeground(Color.BLACK);
rcLabel.setBounds(217, 85, 10, 10);
add(rcLabel);
// Fields for answers
JLabel pAnswerJLabel = new JLabel("<-Answers->");
pAnswerJLabel.setForeground(Color.BLACK);
pAnswerJLabel.setBounds(115, 155, 74, 10);
add(pAnswerJLabel);
pAnswerField.setBounds(10, 150, 100, 20);
add(pAnswerField);
cAnswerField.setBounds(190, 150, 100, 20); // where is this field?!
add(cAnswerField);
// Buttons
//clearButton.setBounds(10, 210, 110, 25);
//add(clearButton);
//JLabel clearLabel = new JLabel("Clear Fields");
//clearLabel.setForeground(Color.BLACK);
//clearButton.add(clearLabel);
// clearButton.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// clearButton.setActionCommand("Clear");
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("perm")) {
// contentPane.setBackground(Color.red);
long Pnr = Permutation();
if (Pnr != 0) {
pAnswerField.setText(Pnr + "");
}
} else if (e.getActionCommand().equals("comb")) {
// contentPane.setBackground(Color.black);
long Cnr = Combination();
if (Cnr != 0) {
cAnswerField.setText(Cnr + "");
}
} else if (e.getActionCommand().equals("Clear")) {
// contentPane.setBackground(Color.lightGray);
npermField.setText(null);
rperField.setText(null);
pAnswerField.setText(null);
nchooseField.setText(null);
rchooseField.setText(null);
cAnswerField.setText(null);
}
}
public long Permutation() {
String npString = npermField.getText();
String rpString = rperField.getText();
int npint = 0;
int rpint = 0;
try {
npint = Integer.parseInt(npString);
rpint = Integer.parseInt(rpString);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
return 0;
}
if (npint <= 0 || rpint <= 0) {
JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
return 0;
}
if (npint < rpint) {
JOptionPane.showMessageDialog(null,"ERROR! The value of 'r' must be less than \n or equal to the value of 'n.'");
return 0;
}
long Pnr = 1;
int mult = npint;
int nmr = (npint - rpint);
while (mult > nmr) {
Pnr = Pnr * mult;
mult--;
}
return Pnr;
}
public long Combination() {
String ncString = nchooseField.getText();
String rcString = rchooseField.getText();
int ncint = 0;
int rcint = 0;
try {
ncint = Integer.parseInt(ncString);
rcint = Integer.parseInt(rcString);
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null,"ERROR! The values for 'n' and 'r' \n must be positive integers");
return 0;
}
if (ncint <= 0 || rcint <= 0) {
JOptionPane.showMessageDialog(null,"Error! The values for 'n' and 'r' \n must be positive integers");
return 0;
}
if (ncint < rcint) {
JOptionPane.showMessageDialog(null,"ERROR! The value of 'r' must be less than \n or equal to the value of 'n.'");
return 0;
}
long nfact = 1;
for (int i = 2; i <= ncint; i++) {
nfact = nfact * i;
}
long rfact = 1;
for (int i = 2; i <= rcint; i++) {
rfact = rfact * i;
}
long nmr = ncint - rcint;
int nmrfact = 1;
for (int i = 2; i <= nmr; i++) {
nmrfact = nmrfact * i;
}
long Cnr = (nfact / (rfact * nmrfact));
return Cnr;
}
}
}
You are using BorderLayout, but you aren't actually specifying the placements of your components, so they are being rendered in unexpected places.
Here is a screenshot of your application with an orange border around pAnswerField and a red border around cAnswerField
You should take a look at the A Visual Guide to Layout Managers for help on using the Layout Managers properly.
For your application, GridLayout is probably a resonable balance between complexity and layout flexibility
GridBagLayout or SpringLayout will give you the most flexibility, but they can be frustratingly complex to work with.
EDIT Another minor problem which is causing the permButton to misbehave.
In your button creation code you have:
permButton.setActionCommand("Perm");
In your action listener you have: if (e.getActionCommand().equals("perm"))
As written your ActionListener will never get invoked when permButton gets pressed... Either switch to equalsIgnoreCase or define a constant rather than using string literals.
I find adding colored borders to be very helpful when doing layout work. Here's a quick example of how to do this:
npermField.setBounds(23, 50, 60, 20);
add(npermField);
nchooseField.setBounds(230, 50, 60, 20);
// add a border to make the component easier to see during layout.
npermField.setBorder(BorderFactory.createLineBorder(Color.ORANGE));
add(nchooseField);
If you like your ButtonListener class the way it is (I don't; will comment about it after the main issue), you can simply reword the buttons' setup:
.
.
.
add(permButton);
permButton.add(PnrLabel);
// Action Listener for permbutton
permButton.setActionCommand("Perm");
permButton.addActionListener(new ButtonListener());
.
.
.
(and likewise for the other buttons).
See? There is no need to add an ActionListener more than once AND also no need to add an ActionListener in order to add the real ActionListener.
The way your application was:
it didn't work on the first button press (since only then the correct listener is set up);
after the first button press, each new press would add another listener, eventually producing unexpected results (I didn't analyzed it thoroughly, and frankly I will not).
About the ButtonListener
Roughly speaking, your class does:
if (typeA) {
doActionA();
} else if (typeB) {
doActionB();
} else if (typeC) {
doActionC();
}
You could simply create 3 separate ActionListeners, each doing just one thing (either doActionA(), or B or C), without ifs. Then set up each button with only the appropriate ActionListener. This way you could also remove the lines setActionCommand(type);, since they would become useless.
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++;
}