I am writing an tip calculator app in java applet with GUI, my question is how I make sure the error message will pop up if users enter letter instead of number
it is my first time asking question, please be easy on me! Thanks!!!
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// Typing in the text field and hitting return adds text to text area.
// Clicking on button erases the text area.
public class TextApplet extends Controller implements ActionListener
{
private static final int ROWS = 1; // rows in TextArea
private static final int COLS = 10; // cols in text field & area
private String amount;
private float number;
private JTextField inField, output; // Input field
private JButton clear, calc;
// button to clear output
public void begin()
{
Container contentPane = getContentPane();
JPanel topPanel = new JPanel(); // prepare text field & label
JLabel inLabel = new JLabel("Bill Cost: ");
inField = new JTextField(COLS);
inField.addActionListener(this);
JLabel topTitle = new JLabel("Tip Calculator", JLabel.CENTER);
JPanel combinePanel = new JPanel();
combinePanel.add ( inLabel );
combinePanel.add ( inField );
JPanel combinePanel1 = new JPanel();
combinePanel1.add ( topTitle );
topPanel.add ( combinePanel1 );
topPanel.add ( combinePanel );
topPanel.setLayout ( new GridLayout ( 3,1) );
contentPane.add(topPanel,BorderLayout.NORTH);
JPanel centerPanel = new JPanel(); // prepare text area & label
JLabel outLabel = new JLabel("Bill + Tip:");
output = new JTextField(COLS);
output.setEditable(false); // Prevent user from wrting in output
centerPanel.add(outLabel);
centerPanel.add(output);
contentPane.add(centerPanel,BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
// create button
clear = new JButton(" Clear ");
calc = new JButton("Calculate");
calc.addActionListener(this);
clear.addActionListener(this);
bottomPanel.add(calc);
bottomPanel.add(clear);
contentPane.add(bottomPanel,BorderLayout.SOUTH);
validate();
}
// add text to area if user hits return, else erase text area
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
}
There are any number of ways you might achieve this, you could use
An InputVerifier
A JFormattedTextField
A JSpinner
Or a DocumentFilter and examples
Take a look at javax.swing.InputVerifier. That can be easily attached to a JTextField
JTextField inputField = new JTextField();
inputField.setInputVerifier(new NumericInputVerifier());
private class NumericInputVerifier extends InputVerifier
{
#Override
public boolean verify(JComponent input)
{
if (((JTextField) input).getText().matches("[0-9]+"))
{
return true;
}
else
{
JOptionPane.showMessageDialog(input, "Only numbers are allowed", "Warning", JOptionPane.WARNING_MESSAGE);
return false;
}
}
}
A complete example can be found here.
Edit Added an example of how to use InputVerifier to limit to numeric input. You'll want to double check the regex, but the basic idea is there...
Use a JFormattedTextField or a DocumentFilter. Then the user won't even be able to enter a non-numeric digit. See:
How to Use Formatted Text Fields
Implementing a Document Filter
For the document filter you will need to check each chraacter as it is entered to make sure it is a digit.
It is always better to do simple edits like that as the user types, rather than wait until you click on a button to do processing.
Hello Friend I will give a suggestion
please add validation when call actionPerformed method
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
if(validate()){
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else{
// show message for inter valid number or any other
}
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
boolean validate(){
try{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
return true;
}
catch(Exception e){
return false;
}
}
If you try to call Float.parseFloat on a String that cannot be converted to a float, it will throw a NumberFormatException. You need to catch this exception.
try {
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
} catch(NumberFormatException e) {
//code to show error message here
}
Well considering, you'd have to turn the string into an integer to do the math, you could do this:
try {
int number = Ineger.parseInt(inField.getText());
} catch (NumberFormatException e) {
//SHOW WARNING
}
if (Label1.getText().matches("[0-9]+"))
// does Label1 containts numbers.
{
// do math
}
else
{
// warning
Lavbel1.setText("");
}
Related
hello i was wondering how do i link my logic class to my gui class?
i have wrote a logic class which is the structure then had to give it an interface; so i wrote another class which is the gui class but idk how to make the GUI class grab the variable from the logic class.
P.S: its a number guessing game that the user has to guess a numb btw 1-10.
LOGIC CLASS
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;
public class GG {
public static void main(String[] args)
{
//random number
Random rand = new Random();
int answer = rand.nextInt(10) +1;
int guess = 0;
int attempts = 0;
public
//user's guess
Scanner keyboard = new Scanner(System.in);
GuessingGameGui gui = new GuessingGameGui();
gui.setVisible(true);
while(answer != guess)
{
try
{
System.out.print("Guess a number between 1 and 10: ");
attempts++;
guess = keyboard.nextInt();
if (guess < 1 || guess > 10)
//throw new BadGuessException()
throw new BadGuessException("invalid entry (" + attempts + " attempts so far)");
}
catch (BadGuessException e)
{
System.out.println(e.getMessage());
}
catch (InputMismatchException e)
{
System.out.println("Please enter integers only, and try again");
keyboard.next(); //to get rid of infinite loop issue
}
}
System.out.println("YOU GOT IT (" + attempts + "attempts )");
}
}
GUI CLASS
public class GuessingGameGui extends JFrame {
public GuessingGameGui() {
final int WINDOW_WIDTH = 650; // Window width in pixels
final int WINDOW_HEIGHT = 250; // Window height in pixels
setTitle("Guessing Game");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel north = new JPanel();
JLabel lab1 = new JLabel("Guess a number between 1 and 10?");
setLayout(new FlowLayout());
north.add(lab1);
add( north );
JPanel center = new JPanel();
final JTextField titleText = new JTextField();
titleText.setPreferredSize( new Dimension( 200, 24 ) );
setLayout(new FlowLayout());
JButton button = new JButton("Guess");
Action action = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
String typed = titleText.getText();
int guess = Integer.parseInt(typed);
}
};
titleText.addActionListener( action );
button.addActionListener( action );
center.add(titleText);
center.add(button);
add( center );
JPanel south = new JPanel();
JLabel lab2 = new JLabel("YOU GOT IT " + attempts);
south.add(lab2);
add( south );
}
}
A common way is to add the Logic object to the GUI, for example through the constructor. Then whenever something is happening on the GUI you need to call the correct methods on the Logic object and update the display if needed.
So I'm making a Java Calculator and walking into some errors upon clicking the function buttons (it compiles perfectly fine though).
The error on the 1st line in my CMD was a NumberFormat Exception. After some searching I figured out that somewhere in my code I was trying to get a double out of an empty string (basically what I'm trying to do is parse a double from the label text). I'm guessing it's this part:
// if statement that puts the labels text into the first or second number
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
Basically the problems are when i push the / * + or - button i get a NumberFormatExeption: For input string "/" etc.
I can't quite figure out how i have to fix this error (I'm still (somewhat) a beginner in Java).
Further down the line of errors (there were quite alot) were a whole lot of errors I didn't understand such as EventDispatchThread, EventQueue and many others. I couldn't find an explanation on my level of experience either so I'm asking for help here.
The numeric buttons all work fine.
At run: [http://gyazo.com/71cb4dde449ccf7ece44017388a71a0f]
Putting in numbers: [http://gyazo.com/5c7ab6c54ac6da180845c66866d66f8f]
All other buttons give errors in my CMD.
Here's my code (the spacing might be messed up in some parts):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
// import for Nimbus look
import javax.swing.UIManager.*;
public class Calculator extends JFrame implements ActionListener
{
private JPanel bottom = new JPanel(); private JPanel top = new JPanel();
private JLabel label = new JLabel(" ");
private JButton[] buttons = new JButton[16];
// booleans for calculator functions
boolean add = false, substract = false, devide = false, multiply = false, firstNumber = true;
// numbers that will be calculated
double number1, number2;
public Calculator()
{
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
// bottom panel
bottom.setPreferredSize(new Dimension(100,100));
bottom.setLayout(new BorderLayout());
//add bottom panel to frame
add(bottom);
// top panel
top.setPreferredSize(new Dimension(300,400));
top.setLayout(new GridLayout(4,4,3,3));
top.setBackground(Color.BLACK);
//dont add top panel to frame: you want top to be on bottom
// add top panel to bottom panel
bottom.add(top);
// label
label.setFont(new Font("Courier", Font.PLAIN, 20));
label.setBackground(Color.BLACK);
label.setForeground(Color.WHITE);
label.setHorizontalAlignment(SwingConstants.RIGHT); // text is right-aligned
label.setOpaque(true);
// add the label to the bottom panel
bottom.add(label, BorderLayout.NORTH);
// creating buttons
for(int i = 0; i < buttons.length; i++)
{
buttons[i] = new JButton("789/456*123+c0=-".substring(i, i+1));
buttons[i].addActionListener(this);
// add them to the top panel
top.add(buttons[i]);
}
// Nimbus look
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
//set to default somehow o.o
}
// frame setters
setTitle("Calculator");
setSize(400,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void Clear()
{
label.setText(" ");
}
#Override
public void actionPerformed(ActionEvent e)
{
//if's for all function buttons
if(e.getSource() == buttons[3])
{
// devide
devide = true;
substract = false;
add = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("/");
}
if(e.getSource() == buttons[7])
{
// multiply
multiply = true;
substract = false;
devide = false;
add = false;
firstNumber = false;
Clear();
label.setText("*");
}
if(e.getSource() == buttons[11])
{
// add
add = true;
substract = false;
devide = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("+");
}
if(e.getSource() == buttons[12])
{
// clear
label.setText("0");
number1 = 0.00;
number2 = 0.00;
add = false;
substract = false;
devide = false;
multiply = false;
firstNumber = true;
Clear();
}
if(e.getSource() == buttons[15])
{
// substract
substract = true;
add = false;
devide = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("-");
}
// for loops that add the numbers on the buttons to the label
for(int i = 0; i < 3; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 4; i < 7; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 8; i < 11; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 13; i < 14; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
// if statement that puts the labels text into the first or second number
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
// calculation
if(e.getSource() == buttons[14])
{
// calculate
if(devide){number1 = ((double)(number1) / (double)(number2)); }
if(multiply){number1 = ((double)(number1) * (double)(number2)); }
if(add){number1 = ((double)(number1) + (double)(number2)); }
if(substract){number1 = ((double)(number1) - (double)(number2)); }
label.setText(Double.toString(number1));
}
}
public static void main(String[] args)
{
new Calculator();
}
}
Lastly, the calculations made by the calculator are incorrect. I also can't wrap my head around what's causing that. Please bear in mind that I'm a beginner at Java and this is my first question on stackoverflow. Thanks in advance for helping me, whoever will :)
UPDATE: i fixed the errors by putting my code as follows:
if(e.getSource() == buttons[15])
{
// substract
substract = true;
add = false;
devide = false;
multiply = false;
firstNumber = false;
isNumberKey = false;
if(isNumberKey)
{
if(firstNumber)
{
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
number1 = Double.parseDouble(label.getText().trim());
} else {
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
number2 = Double.parseDouble(label.getText().trim());
}
}
Clear();
label.setText("-");
}
All i need to do now is fix the calculations...
Thanks for the help everyone!
Cannot delve totaly into your logic there, but here's some hints:
First, you don't have to guess where the error is. In case of uncaught exception like here, thread that produced it will print it's stack trace to console. It looks like this:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "/"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
at java.lang.Double.parseDouble(Double.java:510)
at mypackage.Calculator.actionPerformed(Calculator.java:229)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6297)
From here you see that exception happened in thread named AWT-EventQueue-0, which is swing's standard event dispatching thread (all GUI applications handles events in single thread). Another thing you search in stack trace is to find what line in your code thrown it. Here it's the line:
at mypackage.Calculator.actionPerformed(Calculator.java:229)
In source, it is line:
number2 = Double.parseDouble(label.getText().trim());
, so you guessed right. What you can do is add another boolean there which will be set only if number button is hit, and then change that part of code to something like:
if( isNumber){
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
}
Apart from that, instead of using multiple boolean flags for operation, use Java enum type
enum Operation {devide, substract, add, multiply};
your code will be more readable and "java" styled.
Good starting point, just go ahead!
Disclaimer: I'm on my phone so it's hard to parse your code; with that being said, I believe your number format exception deals with what is stored in the label text.
From the looks of it if you hit an operator button (like multiply), the labelText will be "*", then if you hit number button (like 5), the labelText will be "*5". Finally, if you hit the enter button now to go calculate the answer, Double.parseDouble(label.getText().trim()), will be ran which will throw the NumberFormatException. Using the operation flags, it looks like you don't even need to store the operator (unless you're trying to display the operator to the user); in that case you need to strip the operator from the string before trying the parse the double.
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
As for the other exceptions, in eclipse you can set a breakpoint to halt the program when a specific exception occurs. This will help you debug your code further.
more info on that here
I have a button. If I click this button, a popup appears. The popup asking me to write a word. if I write a word 6 letter, 6 jlabels appear, but if I enter another word shorter, the JLabels do not disappear
I want my JLabels may decrease according to a shorter word, but i don't know :(
thx for your great help !
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//BUTTON 1 WORD
Controller c = new Controller();
try {
final JFrame popup = new JFrame();
//display popup
word = JOptionPane.showInputDialog(popup, "Enter one word", null);
//control the length of the word
c.controleW(word);
//display jlabel lenght of word
keyNumber.setText(String.valueOf(word.length()));
//JLabels displays depending on the word length
int pixels = 50;
for (int i = 0; i < word.length(); i++) {
label = new JLabel("_");
label.setBounds(pixels, 200, 30, 30);
add(label);
label.repaint();
pixels += 20;
}
} catch (Exception e) {
System.out.println(e);
}
}
And my class to control the length of the word
public String controleW(String word) {
boolean flag = false;
final JFrame popup = new JFrame();
while (flag == false) {
if (word.length() <= 3) {
word = JOptionPane.showInputDialog(popup, "Enter one word", null);
} else {
flag = true;
}
};
return null;
}
You are always adding labels in your method, never removing any, thus running the code twice will indeed add labels twice. To fix it, you can simply add a removeAll(); in jButton1ActionPerformed before you add any labels. This makes sure that any previously added components will be removed.
i am developing a project to a class and i came up with a stand-still.
So, what i want to do is to refresh the label when the user presses enter in the textfield to verify the ID.
Here is my code to catch when "enter" key is pressed, it's an event of the textfield "txtNbi":
if (evt.getKeyCode() == 10) {
this.BI = txtNbi.getText();
String BIs[];
BIs = DadosAplicacao.getInstance().getBIs();
for (int i = 0; i < BIs.length; i++) {
System.out.println("BI: " + this.BI + "\nBIlista: " + BIs[i]);
if (this.BI.equals(BIs[i])) {
encontrou.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Ok.png")));
this.repaint();
} else {
encontrou.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Cross.png")));
this.repaint();
}
}
}
txtNbi = name of my textfield;
BIs = array of strings that get pre-inserted IDs from the 'DadosAplicacao' class;
encontrou = name of my label that receives the image as an icon
So here is my problem:
I have the following data:
- BIs[0] = 12345678
- BIs[1] = 87654321
- BIs[2] = 54321678
When i type in the first 2 the label doesn't change to the "Ok.png" icon, but when i type the last one the label changes his icon to "Ok.png"!
Can anyone help me fix this?
You need to use the DocumentListener class:
txtNbi.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent documentEvent) {
//add the code handling the different conditions here
}
});
you need a break after you found the typed ID
if(this.BI.equals(BIs[i]))
{
encontrou.setIcon(newjavax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Ok.png")));
this.repaint();
break;
}
I am having issues trying to get this program to run, the applet loads, but when I enter a number and click ok, nothing seems to happen... I am not sure if I have an issue with the array or where my issue might lie.
I can't seem to figure out what exactly I am doing wrong.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.JOptionPane;
public class LargestApplet extends Applet implements ActionListener {
private static final long serialVersionUID = 1L;
int number =0;
double highNumber=-1;
double lowNumber=-1;
// Create components for applet
Label numberLabel = new Label("Enter a number:");
TextField numberField = new TextField(5);
Button okButton = new Button("OK");
Button cancelButton = new Button("Cancel");
Label highNumberOutputLabel = new Label("The Highest number is: 0 ");
public void init() {
add(numberLabel);
add(numberField);
numberField.requestFocus();
add(okButton);
add(cancelButton);
add(highNumberOutputLabel);
setSize(400, 500); // Sets the size of the applet window
}
public void actionPerformed(ActionEvent e) {
int number = 0, highNumber = -1;
if (numberField.getText().length() == 0) {
numberField.requestFocus();
JOptionPane.showMessageDialog(null,
"Number Cannot blank", "D A T A E R R O R",
JOptionPane.ERROR_MESSAGE);
return;
}
try {
number = Integer.parseInt(numberField.getText());
} catch (NumberFormatException ex) {
numberField.requestFocus();
JOptionPane.showMessageDialog(null, "Number is invalid",
"D A T A E R R O R", JOptionPane.ERROR_MESSAGE);
return;
}
if (number < 0 || number > 10) {
numberField.requestFocus();
JOptionPane.showMessageDialog(null,
"Number must be between 0 and 10",
"D A T A E R R O R", JOptionPane.ERROR_MESSAGE);
return;
}
// Determine highest number
Integer [] numberAr = {number};
for(int i = 0; i < numberAr.length; i++)
{
number += numberAr[i];
if (numberAr[i] < lowNumber)
lowNumber = numberAr[i];
else if (numberAr[i] > highNumber)
highNumber = numberAr[i];
}
// Display the results
highNumberOutputLabel.setText("The Highest Number is: "
+ (highNumber));
}
}
You aren't adding the ActionListener to your buttons, and so pushing a button will have no effect. Fix that by calling addActionListener(this) on the relevant Button. Just having your GUI class extend ActionListener (which is also not a good idea in general) does not magically give buttons the action listener code, and pressing a button will have no effect if you don't first give it code to have a behavior.
More importantly, you should be coding with Swing (JApplet, JButton) not AWT. While Swing is admittedly out of date, AWT is prehistoric in comparison.
And most importantly for us, you should not be posting NullPointerExceptions with your question if you code isn't throwing any.