Why double click instead of single? - java

I have one JFrame where I enter parameters of a matrix, after those parameters being entered, the user is supposed to click a button to start a simulation. The problem is, the button is supposed to be clicked twice instead of once in order to open the JOption pane where a message is written. I just can't figure out why this happens. This is the function that is called from the simulation button's action performed function:
private void setMatrixParameters(){
if(tfTouristNumber.getText().equals("") || tfRowNumber.getText().equals("") || tfColumnNumber.getText().equals("") || tfMinimal.getText().equals("")){
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "All fields must be filled", "Error!", JOptionPane.ERROR_MESSAGE);
}
//check the matrix dimensions
else if(min + touristNumber > Integer.parseInt(tfRowNumber.getText()) * Integer.parseInt(tfColumnNumber.getText())){
int dimension= min + touristNumber;
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Matrix dimensions too small. Need to be at least:" + dimension, "Enlarge matrix!", JOptionPane.ERROR_MESSAGE);
}
else{
this.touristNumber = Integer.parseInt(tfTouristNumber.getText());
int row = Integer.parseInt(tfRowNumber.getText());
int column = Integer.parseInt(tfColumnNumber.getText());
this.matrix = new Object[row][column];
this.min = Integer.parseInt(tfMinimal.getText());
}
}

Your problem in this case is that you are not checking the text field values in the second if-condition. The following should do the trick.
private void setMatrixParameters(){
if(tfTouristNumber.getText().equals("") || tfRowNumber.getText().equals("") || tfColumnNumber.getText().equals("") || tfMinimal.getText().equals("")){
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "All fields must be filled", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
// Read values here. (Should probably add a try-catch block around this, in case it can't be parsed as number)
int inTouristNumber = Integer.parseInt(tfTouristNumber.getText());
int inRow = Integer.parseInt(tfRowNumber.getText());
int inColumn = Integer.parseInt(tfColumnNumber.getText());
int inMin = Integer.parseInt(tfMinimal.getText());
//check the matrix dimensions
if(inMin + inTouristNumber > inRow * inColumn){
int dimension= inMin + inTouristNumber;
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, "Matrix dimensions too small. Need to be at least:" + dimension, "Enlarge matrix!", JOptionPane.ERROR_MESSAGE);
}
else{
this.touristNumber = inTouristNumber;
this.matrix = new Object[inRow][inColumn];
this.min = inMin;
}
}

Related

JComboBox doesn't give the Index

I can't understand what's wrong.
I have a JFrame, with JTextFields and JComboBoxes. When I push a button, it has to take the values from the JTextFields and pass them to one of the methods, which is chosen in the JComboBox, but I can't get the index of the items within the JComboBox.
Here is my code:
public class eHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
if (e.getSource() == esc) {
bx.setText(null);
by.setText(null);
bt0.setText(null);
setVisible(false);
window window = new window("Расчет напряжений");
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(600, 650);
}
if (e.getSource() == count) {
double x = Double.parseDouble(bx.getText());
double y = Double.parseDouble(by.getText());
double t0 = Double.parseDouble(bt0.getText());
Integer item = (Integer)ras.getSelectedIndex();
JOptionPane.showMessageDialog(null, item);
if (item == 0) {
double tens = linear(x, y, t0);
ltr.setText("Напряжение на данном периоде: " + tens + " Мпа");
}
if (item == 1) {
double tens = squard(x, y, t0);
ltr.setText("Напряжение на данном периоде: " + tens + " Мпа");
}
}
}//try
catch(Exception ex){
JOptionPane.showMessageDialog(null, "Введите корректные данные");
}
}
}
It's wrong in:
Integer item = (Integer)ras.getSelectedIndex();
JOptionPane.showMessageDialog(null, item);
Thanks for answers. But it is wrong that i try to use {Listener} for {ComboBox} in other {Listener}. I made a special {Listener} for {JComboBox}, and that has work. Best regards))

JTextField won't disappear completely

I created a dialog box and have the user enter 5 colors in it from memory. That all completely works, there's just a slight aesthetic problem. Upon entering all 5 colors correctly, or getting one incorrect, it's suppose to wipe the contents within the dialog box and print a message "Sorry! Incorrect color" or "Congratulations". It prints the message, but the JTextField can still be seen somewhat behind the message (A left over portion/clipping).
I've tried using the hide() and remove() methods but they didn't seem to work (Or I'm using them incorrectly), I tried re-making a dialog box upon either but I couldn't seem to solve the issue still. What am I doing wrong/how can I make the JTextField disappear upon completion? Thank you in advance for any help!
Here's the portion where if the user enters a color incorrectly or gets them all correct (txtName is the JTextField):
if(count == 6)//User either finished or entered a color incorrectly
{
//Entered color incorrectly
if(incorrect == true)
{
txtName.setEnabled(false); //Doesn't work
homeScreen.remove(txtName); //Doesn't work
labelName.setText("Incorrect! Sorry - Wrong color.");
//txtName.removeActionListener(new MyButtonListener());
}
else//Correctly finished the game.
{
labelName.setText("Congratulations - your memory skills are perfect!");
//txtName.removeActionListener(new MyButtonListener());
homeScreen.remove(txtName);//Doesn't work
}
}
Here's my entire program (I can't get it format properly in the post):
package memorygame;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.FlowLayout;
public class MemoryGame
{
private JFrame homeScreen;
private JLabel labelName;
private JTextField txtName;
private JLabel correct;
Vector<String> name = new Vector();
private int count = 1;
private MyButtonListener listen1 = new MyButtonListener();
//Constructor - Method to be called when MemoryGame object called
public void MemoryGame ()
{
homeScreen = new JFrame();
homeScreen.setSize(400,200);
homeScreen.setTitle("Memory Game");
homeScreen.setDefaultCloseOperation(homeScreen.EXIT_ON_CLOSE);
homeScreen.setLayout(new FlowLayout());
labelName = new JLabel();
txtName = new JTextField(10);
createContents();
homeScreen.setVisible(true);
}//End Constructor
//Create components and add them to the window/dialog box
private void createContents()
{
labelName.setText("Enter the color " + count + ":");
System.out.println("The current count is: " + count);
homeScreen.add(labelName);
homeScreen.add(txtName);
txtName.addActionListener(new MyButtonListener());//Allows you to press enter to invoke action
}
//Upon user hitting enter
private class MyButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)//When event occurs
{
Scanner in = new Scanner (System.in);//For program input
String answer = "";
//Make memColor an array for randomized colors
/*
Random r = new Random();
String[] memColors = new String[5];
String[] colors = {"red", "green", "blue", "yellow", "brown", "purple"};
for(int i =0; i < memColors.length; i++)
{
memColors[i] = colors[r.nextInt(6)];
}
*/
String memColor1 = "red";
String memColor2 = "black";
String memColor3 = "yellow";
String memColor4 = "green";
String memColor5 = "blue";
boolean incorrect = false;
//If answered incorrectly set count to 5(it'll be 6)
//And have a boolean for if count== 6 for congrats and failure
if(e.getSource() == txtName)
{
answer = txtName.getText();
System.out.println(answer);
}
else
{}
//Check if user entered Correct color, 1= Red, 2= Black, etc.
if(count == 1)
{
if(answer.equalsIgnoreCase(memColor1))
{
txtName.setText("");
}
else
{//Needs to be a custom message box
count = 5;
incorrect = true;
}
}
else if(count == 2)
{
if(answer.equalsIgnoreCase(memColor2))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 3)
{
if(answer.equalsIgnoreCase(memColor3))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 4)
{
if(answer.equalsIgnoreCase(memColor4))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 5)
{
if(answer.equalsIgnoreCase(memColor5))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else
{
JOptionPane.showMessageDialog(null, "Something went wrong!");
}
count += 1;
//User has completed the game or entered a color incorrectly
if(count == 6)
{
if(incorrect == true) //Incorrect color
{
txtName.setEnabled(false);
homeScreen.remove(txtName);
labelName.setText("Incorrect! Sorry - Wrong color.");
//txtName.removeActionListener(new MyButtonListener());
}
else //Completed the game correctly
{
labelName.setText("Congratulations - your memory skills are perfect!");
//txtName.removeActionListener(new MyButtonListener());
homeScreen.remove(txtName);
}
}
else
{
labelName.setText("Enter the color " + count + ":");
}
}//End Listener
}//End Button class
public static void main(String[] args) {
//Show message box
//Randomize colors
JOptionPane.showMessageDialog(null, "How good is your memory?\nTry to memorize this color sequence:\n\n red black yellow green blue");
MemoryGame mem = new MemoryGame();
mem.MemoryGame();
}//End Main
}// End Class
Use txtName.setVisible(false); instead of homeScreen.remove(txtName);
Basically, if you want to call remove, you will need to revalidate and repaint container...
You'll also want to ensure that your UI is create within the context of the Event Dispatching Thread, see Initial Threads for more details
Change the code
homeScreen.remove(txtName);
to
homeScreen.remove(txtName);
homeScreen.revalidate();
homeScreen.repaint();
The reason why remove() does not imply revalidate() + repaint() is that remove() is not atomic. The caller might want to perform multiple updates, a sequence of several add() and remove() calls. revalidate() basically "completes" your "UI update transaction", repaint() "pushes it to the screen".
As a side note, your code will be easier to understand and maintain, if you perform a small tiny improvements on variable names. What's homeScreen? And why is it called labelName - what name? And what's txtName - the name of what text? count of what, icecreams?
I suggest the following improvements:
incorrect -> isIncorrect (also change if (incorrect == true) to if (isIncorrect)
homeScreen -> mainFrame or just frame (as you only have one frame)
labelName -> infoLabel or just label (as you only have one label - and remove JLabel correct, it's unused)
txtName -> answerTextField
count -> answerCount
Remove variable listen1, it's not used.
Plus, if you look at the code that does if (count == 1) and the following four if clauses, they are all identical except for the number. A perfect situation for an array. You can convert the variables memColor* to an array String[] memColor. Or maybe that's what the Vector was for. You might instead want to use ArrayList, nobody uses Vector these days in such situations.

InputDialog box showing a random "-1"

Everything runs perfectly but the String am1 = (String)JOptionPane.showInputDialog has a random default "-1" showing.
private void am1ActionPerformed(java.awt.event.ActionEvent evt) {
getinfo();//Set the random question and answer
am1.setEnabled(false);
Object[] options = {"Answer", "Cancel"};
int n = JOptionPane.showOptionDialog(null,
JeopardyGUI.question1_1,//Reference the question set
"",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE,
null, //do not use a custom Icon
options, //the titles of buttons
options[0]); //default button title
if(n == JOptionPane.YES_OPTION){
String am1 = (String)JOptionPane.showInputDialog("",JOptionPane.PLAIN_MESSAGE);
if(am1.equalsIgnoreCase(JeopardyGUI.answer1_1)){
Jscore += 100;
JOptionPane.showMessageDialog(null, JeopardyGUI.answer1_1 );
}
else if(!am1.equalsIgnoreCase(JeopardyGUI.answer1_1)){
Jscore += -100;
JOptionPane.showMessageDialog(null, JeopardyGUI.answer1_1 );
}
// else
// am1.setEnabled(true);
}
if(n == JOptionPane.NO_OPTION){
//am1.setVisible(false);
am1.setEnabled(true);
}
}
You are using:
public static String showInputDialog(Object message, Object initialSelectionValue)
JOptionPane.PLAIN_MESSAGE is your initialSelectionValue in this case. It's an int which is equal to -1 I'm guessing. What you actually want is probably:
JOptionPane.showInputDialog("Actual message", "");
Also, be careful:
String am1 = ...
Is hiding am1 the class member which is some Component it seems.
May I also suggest rewriting the handling logic as:
if(am1 != null && am1.equalsIgnoreCase(JeopardyGUI.answer1_1)){
Jscore += 100;
else Jscore += -100;
JOptionPane.showMessageDialog(null, JeopardyGUI.answer1_1 );
You need use the other static method, it don't receive a default value:
JOptionPane.showInputDialog("")
Check JOptionPane API here.

java dynamic display JLabel

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.

Instance not storing in array. What do I have wrong here?

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.

Categories