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.
Related
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;
}
}
I am trying to make a game and in said game, there are 21 sticks and each person takes turns taking 1-4 sticks until there are no sticks left, if you cant take anymore sticks you lose. I have successfully made this program in eclipse but now I want to add GUI to it so I have to change the code. This code isn't complete but it crashes whenever I press the Go button which is my actionListener. I would type in a number to the text field, press go and it will just crash. How can I fix this?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Sticks extends JFrame {
JButton Go;
JTextField tf1, tf2;
static JTextField sttf;
JLabel startTake;
static JLabel errorTake;
JLabel uTake;
JLabel compTake;
public Sticks() {
setLayout(new GridLayout(5, 2, 5, 5));
startTake = new JLabel("How many sticks do you want to take? (1-4)");
add(startTake);
sttf = new JTextField();
add(sttf);
errorTake = new JLabel("Hello");
add(errorTake);
Go = new JButton("Go");
add(Go);
uTake = new JLabel("");
add(uTake);
compTake = new JLabel("");
add(compTake);
// tf1 = new JTextField();
// add(tf1);
// TakeP = new JLabel("One stick taken");
// add(TakeP);
event e = new event();
Go.addActionListener(e);
}
public static class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
int numSticks = 21;
int numToTake = 0;
int randomNum = 0;
while (numSticks > 0) {
try {
int num = (int) (Double.parseDouble(sttf.getText()));
int NumSticks = numSticks - num;
errorTake.setText("There are: " + numSticks + " left");
Robot Rob = new Robot();
numToTake = (int)Math.random() * 4 + 1;
errorTake.setText("There are: " + numSticks + " left");
}
catch (Exception ex) {
ex.printStackTrace();;errorTake.setText("There is a problem");
}
}
}
}
public static void main(String[] args) {
Sticks gui = new Sticks();
gui.setDefaultCloseOperation(EXIT_ON_CLOSE);
gui.setVisible(true);
gui.setSize(600, 200);
gui.setTitle("Nice Game");
}
}
Everytime you click the "Go" button, your actionPerformed fires, and it doesn't wait for user input at all. This is your problem line.
public static class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
//...
int num = (int) (Double.parseDouble(sttf.getText()));
//...
}
}
sttf.getText() always returns "" because sttf is empty, the program doesn't wait for user input unlike Scanner(System.in).
Makes sense that you don't get any Exceptions because it just runs and finishes the game without giving the user enough time to input anything. Are you sure the console doesn't print "Numbers only!", though? Because I've never tried to parse an empty String before.
Okay I've been reading this all wrong, sorry.
Your actionListener generates a new game everytime you click it, because you set your numSticks to 21 at each click. Looking forward, I don't think that's a good idea unless you want to take the same amount of sticks the whole way until the game ends. Same thing stands. If you input a value in sttf, the program won't wait for you to change it because it'd keep using that value until your while loop ends.
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.
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 need to make the following exceptions: NoSuchRowException if the row is not between 1 and 3, IllegalSticksException if the number of sticks taken is not between 1 and 3, and NotEnoughSticksException if the number of sticks taken is between 1 and 3, but more than the number of sticks remaining in that row. My issue is I really don't understand the syntax. If someone could help me get started with one exception, I think I can figure the others out.
So far I have the main class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nimapp;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* #author jrsullins
*/
public class NimApp extends JFrame implements ActionListener {
private static final int ROWS = 3;
private JTextField[] gameFields; // Where sticks for each row shown
private JTextField rowField; // Where player enters row to select
private JTextField sticksField; // Where player enters sticks to take
private JButton playButton; // Pressed to take sticks
private JButton AIButton; // Pressed to make AI's move
private NimGame nim;
public NimApp() {
// Build the fields for the game play
rowField = new JTextField(5);
sticksField = new JTextField(5);
playButton = new JButton("PLAYER");
AIButton = new JButton("COMPUTER");
playButton.addActionListener(this);
AIButton.addActionListener(this);
AIButton.setEnabled(false);
// Create the layout
JPanel mainPanel = new JPanel(new BorderLayout());
getContentPane().add(mainPanel);
JPanel sticksPanel = new JPanel(new GridLayout(3, 1));
mainPanel.add(sticksPanel, BorderLayout.EAST);
JPanel playPanel = new JPanel(new GridLayout(3, 2));
mainPanel.add(playPanel, BorderLayout.CENTER);
// Add the fields to the play panel
playPanel.add(new JLabel("Row: ", JLabel.RIGHT));
playPanel.add(rowField);
playPanel.add(new JLabel("Sticks: ", JLabel.RIGHT));
playPanel.add(sticksField);
playPanel.add(playButton);
playPanel.add(AIButton);
// Build the array of textfields to display the sticks
gameFields = new JTextField[ROWS];
for (int i = 0; i < ROWS; i++) {
gameFields[i] = new JTextField(10);
gameFields[i].setEditable(false);
sticksPanel.add(gameFields[i]);
}
setSize(350, 150);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
nim = new NimGame(new int[]{3, 5, 7});
draw();
}
// Utility function to redraw game
private void draw() {
for (int row = 0; row < ROWS; row++) {
String sticks = "";
for (int j = 0; j < nim.getRow(row); j++) {
sticks += "| ";
}
gameFields[row].setText(sticks);
}
rowField.setText("");
sticksField.setText("");
}
public void actionPerformed(ActionEvent e) {
// Player move
if (e.getSource() == playButton) {
// Get the row and number of sticks to take
int row = Integer.parseInt(rowField.getText())-1;
int sticks = Integer.parseInt(sticksField.getText());
// Play that move
nim.play(row, sticks);
// Redisplay the board and enable the AI button
draw();
playButton.setEnabled(false);
AIButton.setEnabled(true);
// Determine whether the game is over
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
// Computer move
if (e.getSource() == AIButton) {
// Determine computer move
nim.AIMove();
// Redraw board
draw();
AIButton.setEnabled(false);
playButton.setEnabled(true);
// Is the game over?
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
NimApp a = new NimApp();
}
}
The support class:
package nimapp;
import java.util.Random;
import javax.swing.JOptionPane;
import java.io.*;
import java.lang.*;
public class NimGame {
int x = 1;
int[] Sticks; //creating an array of sticks
int totalSticks = 0;
public NimGame(int[] initialSticks){
Sticks = initialSticks;}
public int getRow(int r){
return Sticks[r];}
public void play(int r, int s) throws IllegalSticksException {
try {
Sticks[r]=Sticks[r]-s;
if(s < 0 || s > 3)
throw new IllegalSticksException();
} catch (IllegalSticksException ex){
JOptionPane.showMessageDialog(null, "Not a valid row!");
} catch (IndexOutOfBoundsException e){
JOptionPane.showMessageDialog(null, "Too Many Sticks!");
}
}
public boolean isOver(){
int theTotal = 0;
for (int i = 0; i< Sticks.length; i++){
theTotal = Sticks[i];
System.out.println(Sticks[i]);
System.out.println(theTotal);
}
totalSticks = theTotal;
if (totalSticks <= 0){
return true;
}
else return false;
}
public void AIMove(){
Random randomInt = new Random ();
boolean tryRemove = true;
while(tryRemove && totalSticks >= 1){
int RandomRow = randomInt.nextInt(3);
if(Sticks[RandomRow] <= 0)//the computer can't remove from this row
continue;
//the max number to remove from row
int size = 3;
if( Sticks[RandomRow] < 3)//this row have least that 3 cards
size = Sticks[RandomRow];//make the max number to remove from the row be the number of cards on the row
int RandomDiscard = randomInt.nextInt(size) + 1;
Sticks[RandomRow] = Sticks[RandomRow] - RandomDiscard;
//I don't know if this is needed, but since we remove a RandomDiscard amount lest decrease the totalSticks
totalSticks = totalSticks - RandomDiscard;
//exit loop
tryRemove = false;
}
if(totalSticks <= 1){
int RandomRow = 0;
Sticks[RandomRow] = Sticks[RandomRow]-1;
isOver();
}
}
}
My issue is I really don't understand the syntax.
There is nothing wrong with the syntax as you have written it.
The problem is that you are catching the exception at the wrong place. You are (apparently) intending play to propagate the IllegalSticksException to its caller. But that won't happen because you are catching it within the play method.
There are two possible fixes depending on what you actually intent to happen.
You could remove the throws IllegalSticksException from the play signature.
You could remove the catch (IllegalSticksException ex){ ... } in play and catch/handle the exception at an outer level.