we are working on a project trying to make a message in a JOptionPane show up when a button is pressed and certain conditions are met. However whenever the code is activated and a button is pressed, the JOptionPane shows up with no message. Here is the code that creates the GUI
package BlackJack;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class BlckJckUI {
public static void main(String[] args) {
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(1000,900);
GUI.setVisible(true);
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(two);
This is the code that works out the logic.
package BlackJack;
public class Math {
public int cardvalue;
public Math()
{
Arrays array = new Arrays();
if (array.clicktracker == 1)
{
array.dealer = cardvalue;
array.result = "Please select the first card you have :)";
}
else if (array.clicktracker == 2)
{
array.playerhand.add(cardvalue);
array.result = "Please select the second card you have :)";
}
else if (array.clicktracker >= 3)
{
array.playerhand.add(cardvalue);
if (array.playerhandtotal <= 8)
{
// array.result = result statement
array.result = "You should just hit until you're safe. If the dealer 6 or below,\n"
+ " the chances are that he'll bust and if not, remain low above 17.\n"
+ " As long as you can pull a 17 or higher, you should be safe. Pick \n"
+ "another card or reset.";
This is the code that creates the Array and variables associated with it.
package BlackJack;
import java.util.ArrayList;
public class Arrays{
public String result = null;
ArrayList<Integer> playerhand = new ArrayList<Integer>();
public int dealer = 0;
public int clicktracker = 0;
public int playerhandtotal = 0;
{
for (int element: playerhand)
{
playerhandtotal = element + playerhandtotal;
}
System.out.println(result);
System.out.println(dealer);
System.out.println(clicktracker);
}
}
In your Math constructor, you are changing the result of a different type of array.result than the one you are trying to display.
I would consider passing the Arrays instance into the Math constructor so that you can modify the result from there. Be sure to not reassign the instance though.
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math(array);
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
...
public Math(Arrays array)
{
if (array.clicktracker == 1)
{
// And so on ...
The problem is that you are creating two separate instances of your Arrays class. Once in the actionPerformed method and also within the constructor of your Math class.
This code you currently have:
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
will display the result of the Arrays object you created in the actionPerformed method - which is null as the result of this object is initialised to null and never set.
This has been mentioned in other answers and comments and will solve it from producing null but this approach will now always yield the same result as you are still always creating a new instance of your Arrays class in your actionPerformed method.
A better approach would be to separate the logic of the result from the constructor of your Math class into another method and create this instance of your Math class outside of the actionPerformed method. Then within your actionPerformed method call your method which will do the logic for your result.
In UI:
Math math = new Math();
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
math.cardvalue = 2;
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
In Math:
public class Math {
public int cardvalue;
public Arrays array;
public Math()
{
array = new Arrays();
}
public void calcResult(){
if (array.clicktracker == 1)
{
//...rest of your logic
}
}
Related
I'm writing a simple Java program.
First, the program asks user to input some info like name and id of the student and uses radio button for asking whether the student is present or absent. After finishing the inputs, then program validate whether predefined student names and inputs are match or not. And check id number again and spit out if input is over 4. Lastly check radio button is true or false. If one of the above two rules get error then program will quit without executing next method.
I have three .java files. One for UI. One for validation and one for storing data.
UI.java
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class UI extends JFrame {
JTextField name = new JTextField("Name", 10);
JTextField id = new JTextField("Id", 10);
JRadioButton attendance = new JRadioButton("Present");
JButton JB = new JButton("Check");
public UI() {
super("Test");
JPanel JP = new JPanel();
JP.add(name);
JP.add(id);
JP.add(attendance);
JP.add(JB);
add(JP);
pack();
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void buttonAction(){
UI UIbutton = new UI();
UIbutton.JB.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == UIbutton.JB) {
String nameInput = UIbutton.name.getText();
int idInt = Integer.parseInt(UIbutton.id.getText());
boolean attInput = UIbutton.attendance.isSelected();
Validate.nameChk(nameInput);
Validate.idChk(idInt);
Validate.attChk(attInput);
Student studentObj = new Student(UIbutton.name.getText(), idInt, UIbutton.attendance.isSelected());
System.out.println(studentObj.name + "'s ID number is : " + studentObj.id + ".");
System.out.println(studentObj.name + " is present: " + studentObj.attendance);
System.exit(0);
}}});
}
public static void main(String[] args) {
buttonAction();
}
}
Validate.java
public class Validate {
public static void nameChk (String nameInput) {
String n1 = "Matthew";
String n2 = "John";
String n3 = "Mark";
String n4 = "Luke";
if ((nameInput.equalsIgnoreCase(n1))||
(nameInput.equalsIgnoreCase(n2))||
(nameInput.equalsIgnoreCase(n3))||
(nameInput.equalsIgnoreCase(n4))){
System.out.println("Your data is okay.");
}
else {
System.out.println("Error, wrong student name.");
System.exit(0);
}
}
public static void idChk (int idInt) {
if (idInt > 4) {
System.out.println("Your id is not correct.");
System.exit(0);
}
else {
System.out.println("Your id is correct.");
}
}
public static void attChk (boolean attInput) {
if (attInput) {
System.out.println("The student is present.");
} else {
System.out.println("The student is absent.");
}
}
}
Student.java
public class Student {
String name;
int id;
boolean attendance;
Student(String name, int id, boolean attendance) {
this.name = name;
this.id = id;
this.attendance = attendance;
}
}
What I want to know is how can I reuse output of that actionlister method somewhere else. Let say I would create foo.java class and use that studentObj variable to give grades like
System.out.println(studentObj.name+"has B+.");
Sort of.
How can I do that? How to turn that variable into global?
This can be achieved in different ways.
Quite simple, but not a good practice would be to create a Singleton. It would contain Students objects and you'll be able to access them from anywhere. Here is example with eager singleton, but you can implement much better versions (check about singleton implementations i.e. here https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples)
public class StudentsSingleton {
private Map<Integer, Student> students = new HashMap<>();
public Student getStudent(int id) { return students.get(id);}
public void addStudent(Student s) { students.put(s.id, s);}
private static final StudentsSingleton instance = new StudentsSingleton();
//private constructor to avoid client applications to use constructor
private StudentsSingleton(){}
public static StudentsSingleton getInstance(){
return instance;
}
}
In that case, you can access it from anywhere by getting the instance :
StudentsSingleton.getInstance().getStudent(id);
A much better solution and a good practice would be to use some Dependency Injection framework i.e. Spring. In that case, you would create a Bean and inject it whenever it is needed to use.
public class QuestionBank {
public static void main(String[] args) {
int k = 0;
String Bank[][] = {{"The sun is hot.","A. True","B. Flase","A"},
{"Cats can fly.","A. True","B. False","B"}};
}
}
Above is my QuestionBank class that creates a 2X4 string array. First column being the question, 2nd and 3rd being the answer choices, and 4th being the correct answer.
Below is my RealDeal class.
import javax.swing.JOptionPane;
import java.util.Scanner;
public class RealDeal {
public static void main(String[] args) {
input = JOptionPane.showInputDialog(Bank[0][0]\nBank[0][1]\nBank[0][2]);
if (input == Bank[0][3]) {
input = 10;
} else {
input = 0;
}
total = input/1;
JOptionPane.showMessageDialog(null,"You scored a " + total + " out of 10. Great job!");
System.exit(0);
}
}
What I'm trying to do is to get Bank[0][0], Bank[0][1], and Bank[0][2] to output on my RealDeal class and then to check whether Bank[0][3] matches with the users input. Can anyone please help me with this. Im really new to java so if anyone could actually draw out the answer and explain it to me that would be great.
I think the best way is reading a good Java book and become familiar with the language itself and then try to solve this by your own. If you then have a real question there is no problem asking it here again. But your code is... not really working at all.
I don't think this portal is a "please do my work for me" portal.
To call anything from another class you will need to either setup a method for a return or make the variables public.
So:
public class Class1
{
// for method 1
public String s1 = "This is a string"
// for method 2
public Class1 {}
public returnString()
{
return s1;
}
}
public class CLASS2
{
public static void main(String args[])
{
// get the class
cls1 = new Class1();
// retrieving - method 1
String str = cls1.s1;
// retrieving - method2
str = cls1.returnString();
}
}
I've been trying to create a scenario where when a button is clicked, a new JFrame is generated with x amount of JLabels and JButtons (x is dependent on user inputs in another part of the program). However, whenever I try to do this, I get the "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException" error
I cannot figure out what the error is. My code's syntax is fine and compiles with no errors. Code that is bolded (not really but has ...) are lines that the error points to. There are also other lines that are pointed to but those are the lines generated by java.
**public class MainUI extends javax.swing.JFrame {**
public MainUI() {
initComponents();
}
private void ViewList(java.awt.event.ActionEvent evt) {
this.dispose();
ListFrame list = new ListFrame();
ArrayList<Type1> miniList1 = DataStorage.getMiniList1();
ArrayList<Type2> miniList2 = DataStorage.getMiniList2();
int counter = 0;
java.awt.Label[] rLabels;
rLabels = new java.awt.Label[miniList1.size() + miniList2.size()];
javax.swing.JButton[] rButtons;
rButtons = new javax.swing.JButton[rLabels.length];
for (int g=0;g<rLabels.length;g++)
{
**rLabels[g].setPreferredSize(new Dimension(150,35));**
rLabels[g].setAlignment(Label.CENTER);
rLabels[g].setLocation(30,30*g);
}
for (int h=0;h<rButtons.length;h++)
{
rButtons[h].setText("Show");
}
for (int i=counter;i<miniList1.size();i++)
{
String name1 = miniList1.get(i).getName();
rLabels[i].setText(name1);
Type1 item1 = miniList1.get(i);
rButtons[i].addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
ItemScreen iScreen = new ItemScreen();
String item1Display = DataStorage.type1ToString(item1);
iScreen.iTitleLabel.setText(name1);
iScreen.iTextLabel.setText(item1Display);
iScreen.setVisible(true);
}
});
counter++;
}
for (int j=counter;j<miniList2.size() + counter;j++)
{
String name2 = miniList2.get(j-counter).getName();
rLabels[j].setText(name2);
Type2 item2 = miniList2.get(j);
rButtons[i].addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
ItemScreen iScreen = new ItemScreen();
String item2Display = DataStorage.type2ToString(item2);
iScreen.iTitleLabel.setText(name2);
iScreen.iTextLabel.setText(item2Display);
iScreen.setVisible(true);
}
});
}
for (int m=0;m<rLabels.length;m++)
{
list.add(rLabels[m]);
}
for (int n=0;n<rLabels.length;n++)
{
list.add(rButtons[n]);
}
list.setVisible(true);
}
ListFrame and ItemScreen are JFrames in my project and DataStorage is another class in my project. Type1 and Type2 are objects. I'm using NetBeans.
When you create an array, it creates n number of empty/uninitialised slots
So when you do something like...
rLabels = new java.awt.Label[miniList1.size() + miniList2.size()];
All you have is an array of null elements...
Before you can modify an object at a given position, you need to initialise the value at the given slot...
for (int g=0;g<rLabels.length;g++)
{
rLabels[g] = new JLabel();
//...
}
This goes for all arrays. Take a look at the Arrays tutorial for more details
I'm doing the Guessing Game for Java homework and I am having a logic problem with the nested if else. I am trying to determine two things: is the number to high/low, and if the user is getting hotter/colder. I have a variables intGuess and intOldGuess. I am trying to compare the two for the hotter/colder but I either end up with intOldGuess being 0, or the same as intGuess when it comes time for comparison. Neither are correct of course. Here is what I have so far:
Here is the section I think is giving me trouble:
public void actionPerformed(ActionEvent e)
{
int intGuess = 0, intOldGuess;
intOldGuess = intGuess;
try
{
intGuess = Integer.parseInt(txaUserGuess.getText().trim());
if (intGuess < intRandomNum)
{
lblHighLow.setText("Too Low");
if (intGuess > intOldGuess)
{
lblHotCold.setText("Getting Colder");
System.out.println(intOldGuess);
System.out.println(intGuess);
}
Here is the entire code if you need it:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class GuessNumber extends JFrame
{
private JTextField txaUserGuess;
private JLabel lblStart, lblPrompt, lblHighLow, lblHotCold;
private JButton btnGuess, btnQuit, btnAgain;
private int intRandomNum;
Container c = getContentPane();
public static void main(String args[])
{
GuessNumber app = new GuessNumber();
}
public GuessNumber()
{
super("Guessing Game");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Creates components
btnGuess = new JButton("Guess");
btnQuit = new JButton("Quit");
btnAgain = new JButton("Play Again?");
lblStart = new JLabel("I have a number between 1 and 1000.");
lblPrompt = new JLabel(
"Can you guess my number? Please enter your guess:");
lblHighLow = new JLabel("");
lblHotCold = new JLabel("");
txaUserGuess = new JTextField(5);
setLayout(new FlowLayout());
c.add(lblStart);
c.add(lblPrompt);
c.add(txaUserGuess);
c.add(btnGuess);
c.add(btnQuit);
c.add(btnAgain);
c.add(lblHighLow);
c.add(lblHotCold);
setSize(350, 200);
setVisible(true);
btnAgain.setVisible(false);
RandomNumber();
FirstGuessButtonHandler ghandler = new FirstGuessButtonHandler();
btnGuess.addActionListener(ghandler);
QuitButtonHandler qhandler = new QuitButtonHandler();
btnQuit.addActionListener(qhandler);
AgainButtonHandler ahandler = new AgainButtonHandler();
btnAgain.addActionListener(ahandler);
}
private void RandomNumber()
{
intRandomNum = new Random().nextInt(1000) + 1;
System.out.println(intRandomNum);
}
class QuitButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
class AgainButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
}
}
class FirstGuessButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
int intGuess = 0, intOldGuess;
intOldGuess = intGuess;
try
{
intGuess = Integer.parseInt(txaUserGuess.getText().trim());
if (intGuess < intRandomNum)
{
lblHighLow.setText("Too Low");
if (intGuess > intOldGuess)
{
lblHotCold.setText("Getting Colder");
System.out.println(intOldGuess);
System.out.println(intGuess);
} else if (intGuess < intOldGuess)
{
lblHotCold.setText("Getting Hotter");
}
} else if (intGuess > intRandomNum)
{
lblHighLow.setText("Too High");
} else
{
c.setBackground(Color.GREEN);
lblHighLow.setText("\n\tCorrect!");
txaUserGuess.setEditable(false);
btnAgain.setVisible(true);
btnGuess.setEnabled(false);
}
} catch (NumberFormatException e1)
{
lblHighLow.setText("\n\tEnter a VALID number!");
}
}
}
}
int intGuess = 0, intOldGuess;
is currently contained in the method actionPerformed() these need to be declared as fields (outside methods but in the class body).
Also you may consider writing those as
int intGuess = 0;
int intOldGuess;
for clarity sake (it looks cleaner and will make your code more easily readable)
intOldGuess is local variable to the method. So every time the method gets called, it gets initialized to 0 (default value).
To preserve the value, you might want to create the variable as class field
class FirstGuessButtonHandler implements ActionListener
{
int intOldGuess;
public void actionPerformed(ActionEvent e)
{
int intGuess = 0;
But remember, in above case, you need to maintain the same instance of FirstGuessButtonHandler class, since the class fields are maintained per instance of the class.
Other approach could be to create intOldGuess as static class field too
In this place here:
int intGuess = 0, intOldGuess;
intOldGuess = intGuess;
You are defining intOldGuess, but in second line you assign value 0 to it. You probably should keep this variable in class scope and don't assign 0 to it.
Use of local variables should be avoided, if you want to use them without re-initialization.
To retain the value of variables make those variables Reference variable.
You can do this-
class ClassName{
int oldguess;
public void yourMethod(){
int newGuess = 0;
if (intGuess < intRandomNum)
{
lblHighLow.setText("Too Low");
if (intGuess > intOldGuess)
{
lblHotCold.setText("Getting Colder");
System.out.println(intOldGuess);
System.out.println(intGuess);
}
The problem is, that you have the second if nested in the first. The second only ever gets checked, if the first is valid. The second condition can therefore never be true. (It only checks if intGuess is greater than inOldGuess, if intGuess is less than intOldGuess, which can never be.
You need to take the second if out of the first.
Also, you seem to want to store data in intOldGuess, but you declared it as a local variable. You need to set it is a field if you want it to store data between method calls.
The problem lies with how you are keeping state
int intGuess = 0, intOldGuess;
intOldGuess = intGuess;
Here you are declaring local variables, which are recreated each time your function is called.
When I'm trying to create a new object from a class I previously defined, I keep getting a "cannot find symbol" error, and there's an arrow pointing towards the "S" in the first "SnowFallReport" in my constructor. I've had this problem when trying to create other objects in other programs and I just wanna throw my laptop! I feel like it's a simple solution, I just don't know what it is.
The code follows:
import java.util.Random;
public class SnowfallReport
{
// Random amount of snow
private double snowAmount;
// Default constructor creates random amount and assigns to snowAmount
public void SnowFallReport()
{
Random snowFall = new Random();
snowAmount = (snowFall.nextDouble()) * 20;
}
public double getSnow()
{
return snowAmount;
}
public void getStars()
{
for (int starAmount = 0; starAmount == snowAmount; starAmount++)
{
System.out.print("*");
}
}
public static void main(String[] args)
{
**SnowFallReport day1 = new SnowFallReport();**
}
}
java is case sensitive language SnowfallReport != SnowFallReport
your class name is SnowfallReport thus you create your object like:
SnowfallReport ref = new SnowfallReport ();
also, constructor name should be the same as class name and they don't have return type not even void.
// Default constructor creates random amount and assigns to snowAmount
public void SnowFallReport()
{
should be
public SnowfallReport()
{