JApplet crashing because of a for loop for an Array - java

this is my first post so go easy on me.
I'm doing some uni work and im not asking for any help or advice for the whole project.
Basically the whole thing does work kinda when i comment out a for loop:
for(int i=0;i<words.length;i++)
{
textArea.append(words[i] + "\n");
}
this is designed to work its way through an array but NetBeans keeps telling me to change it into an enhanced for loop but when i do it crashes. The whole program is designed to take an input from a JAplet interface, send it to stringAnalyser in a separate java file, record the length of words and how often words of that length occur, then send them back to the interface and print them onscreen in the centre console.
Here are both files i'm using if it helps:
package Assignment2;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowListener;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.JPanel;
public class GUIAssign extends JApplet
{
private JPanel pnorth,psouth,pcentre,pwest,peast;
private JButton btnEnter,btnReset,btnSave,btnLoad;
private JTextField txtEnter;
private JLabel label1,label2,header;
private JTextArea textArea;
private Container c;
private paintPanel panelpaint;
private String inputString,shape;
private int x,y,size;
private stringAnalyser tim;
#Override
public void init()
{
this.setVisible(true);
this.setSize(800,600);
initComponents();
initPanels();
initButtons();
initText();
initLabels();
tim=new stringAnalyser();
}
public void initComponents()
{
x=0;
y=0;
size=0;
this.panelpaint=new paintPanel();
}
public void initPanels()
{
pnorth= new JPanel();
pnorth.setBackground(Color.CYAN);
this.psouth = new JPanel();
psouth.setBackground(Color.BLUE);
this.peast =new JPanel();
peast.setBackground(Color.CYAN);
this.pwest = new JPanel();
pwest.setBackground(Color.CYAN);
this.pcentre = new JPanel();
pcentre.setBackground(Color.yellow);
}
String words[];
public void initButtons()
{
this.btnEnter=new JButton("Enter");
btnEnter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
inputString=txtEnter.getText();
tim.setText(inputString);
words=tim.sendBack();
for(int i=0;i<words.length;i++)
{
textArea.append(words[i] + "\n");
}
tim.output();
}
});
this.btnReset=new JButton("Reset");
btnReset.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
txtEnter.setText("");
}
});
this.btnSave=new JButton("Save");
this.btnLoad=new JButton("Load");
}
public void initText()
{
txtEnter=new JTextField();
textArea=new JTextArea();
}
public void initLabels()
{
this.label1=new JLabel("");
this.label2=new JLabel("");
}
//structure
#Override
public void start()
{
panelEast();
panelWest();
panelNorth();
panelSouth();
panelCentre();
c=this.getContentPane();
c.setBackground(Color.LIGHT_GRAY);
c.setLayout(new BorderLayout());
c.add(pnorth,BorderLayout.NORTH);
c.add(peast,BorderLayout.EAST);
c.add(psouth,BorderLayout.SOUTH);
c.add(pwest,BorderLayout.WEST);
c.add(pcentre,BorderLayout.CENTER);
}
public void panelNorth()
{
Font f=new Font("Jokerman",Font.BOLD,16);
pnorth.setLayout(new GridLayout(1,3));
pnorth.add(new JLabel(" "));
pnorth.add(new JLabel("Tim's String Lenght Tester"));
pnorth.add(new JLabel(" "));
}
public void panelWest()
{
pwest.add(new JLabel(" "));
//pwest.add(new JLabel(new ImageIcon("src/tim.jpg")));
}
public void panelEast()
{
peast.add(new JLabel(" "));
}
public void panelSouth()
{
psouth.setLayout(new FlowLayout());
JPanel psouth1=new JPanel();
JPanel psouth2=new JPanel();
psouth1.setLayout(new GridLayout(1,3));
psouth1.setBackground(Color.CYAN);
psouth1.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.cyan, Color.black, Color.black, Color.cyan));
psouth1.add(this.txtEnter);
psouth1.add(this.btnEnter);
psouth1.add(this.btnReset);
psouth2.setLayout(new GridLayout(1,2));
psouth2.setBackground(Color.LIGHT_GRAY);
psouth2.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.cyan, Color.black, Color.black, Color.cyan));
psouth2.add(this.btnSave);
psouth2.add(this.btnLoad);
psouth.add(psouth1);
psouth.add(psouth2);
}
public void panelCentre()
{
pcentre.setLayout(new GridLayout(1,2));
JPanel pcentre1=new JPanel();
pcentre.setBackground(Color.GREEN);
pcentre.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.green,Color.green));
pcentre.add(textArea);
textArea.setBackground(Color.LIGHT_GRAY);
textArea.setForeground(Color.YELLOW);
pcentre.add(pcentre1);
}
#Override
public void setName(String n) {
this.inputString=n;
}
public String getNameString() {
return inputString;
}
#Override
public void stop(){}
#Override
public void destroy(){}
#Override
public void paint(Graphics g){
}
}//close project`
file 2, this is the analysing java file:
package Assignment2;
public class stringAnalyser{
//static String inputArray[]= {"Tim","John","Craig", "Andrew", "Bob", "Tom", "Phillipa","Billie-Bob"};
private String inputString = "";
private String removedCharString;//will store the string with removed chars
private String array3="",array4="", array5="", array6="", array7="", array8="", array9="", array10="",array11="",
array12="",array13="",array14="",array15="";
private String[] sendString;
private int count=0;
//will add the words with the appropriate length to a string for printing
public void setText(String input)
{
this.inputString=input;
}
public String showme()
{
return "Think is not difficult believe is the word and look at me I am the great evidence!!!";
}
public void output()
{
int three=0, four=0, five=0, six=0, seven=0, eight=0, nine=0, ten=0,eleven=0,twelve=0,thirt=0,fort=0,fift=0;
// these ints will count how many times the words relevent length have accoured in a string
String w[];
removedCharString = inputString.replaceAll("[^a-zA-Z\\s]", "");//remove chars
w=removedCharString.split(" ");
this.sendString=new String[w.length];
for (String retval: removedCharString.split(" "))//split at any spaces
{
if (retval.length()==3){
three++;
array3 = array3 + retval + ", ";
}//if 3
if (retval.length()==4){
four++;
array4 = array4 + retval + ", ";
}//if 4
if (retval.length()==5){
five++;
array5 = array5 + retval + ", ";
}//if 5
if (retval.length()==6){
six++;
array6 = array6 + retval + ", ";
}//if 6
if (retval.length()==7){
seven++;
array7 = array7 + retval + ", ";
}//if 7
if (retval.length()==8){
eight++;
array8 = array8 + retval + ", ";
}//if 8
if (retval.length()==9){
nine++;
array9 = array9 + retval + ", ";
}//if 9
if (retval.length()==10){
ten++;
array10 = array10 + retval + ", ";
}//if 10
if (retval.length()==11){
eleven++;
array11 = array11 + retval + ", ";
}//if 10
if (retval.length()==12){
twelve++;
array12 = array12 + retval + ", ";
}//if 10
if (retval.length()==13){
thirt++;
array13 = array13 + retval + ", ";
}//if 10
if (retval.length()==14){
fort++;
array14 = array14 + retval + ", ";
}//if 10
if (retval.length()==15){
fift++;
array15 = array15 + retval + ", ";
}//if 10
}//for string retval
// print the results
System.out.println(inputString);
if (three!=0){
count++;
sendString[count]="There are: "+three+" three letter word/s; "+array3;
System.out.println("There are: "+three+" three letter word/s; "+array3);}
if (four!=0){
count++;
sendString[count]="There are: "+four+" four letter word/s; "+array4;
System.out.println("There are: "+four+" four letter word/s; "+array4);}
if (five!=0){
System.out.println("There are: "+five+" five letter word/s; "+array5);}
if (six !=0){
System.out.println("There are: "+six+" six letter word/s; "+array6);}
if (seven !=0){
System.out.println("There are: "+seven+" seven letter word/s; "+array7);}
if (eight!=0){
System.out.println("There are: "+eight+" eigth letter word/s; "+array8);}
if (nine!=0){
System.out.println("There are: "+nine+" nine letter word/s; "+array9);}
if (ten!=0){
System.out.println("There are: "+ten+" ten letter word/s;"+array10);}
if (eleven!=0){
System.out.println("There are: "+eleven+" eleven letter word/s;"+array11);}
if (twelve!=0){
System.out.println("There are: "+twelve+" twelve letter word/s;"+array12);}
if (thirt!=0){
System.out.println("There are: "+thirt+" thirteen letter word/s;"+array13);}
if (fort!=0){
System.out.println("There are: "+fort+" forteen letter word/s;"+array14);}
if (fift!=0){
System.out.println("There are: "+fift+" fifteen letter word/s;"+array15);}
}//output
public String[] sendBack()
{
return this.sendString;
}
public static void main(String []args)
{
stringAnalyser a=new stringAnalyser();
a.output();
}//close main
}//class`
thank you in advance for any and all input.

It seems that in btnEnter.addActionListener you only invoke tim.setText(inputString); which sets the input. But you never call output() or any other required methods on the analyzer that supposed to process the input. As a result, tim.sendBack() returns null. stringAnalyser.sendString is initialized only inside output(). Until then it remains null. So words.length triggers NullPointerException because words array is null.
The indentation and naming of the posted code is bit hard to follow at times. See Java Code Conventions, Naming Conventions section in particular. Most tools can auto indent the code for you, ie ctrl+shift+f in Eclipse.

Related

Previous class gets called when calling the next class

I am not experienced, and only 14 tears old!
I made a little application, that would quiz me. Basically I would put in questions and answers in a notepad like this:
H
Hydrogen
O
Oxygen
K
Potassium
The program would sort the words like so↓, and display them in a TextArea with a ScrollPane
H = Hydrogen
O = Oxygen
K = Potassium
On the bottom theres, a JButton("Start Test"), and it would ask you the questions in order. E.g. ``H means? O Means? K Means? and then it would give you feedback E.g. Wrong! H means Hydrogen, or Correct!
here are the two classes! GUI is just simply the GUI. and the test is the class responsible for the testing
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class GUI extends JFrame
{
//JFrame components
public static JButton btn = new JButton("Start Test");
public static JPanel panelBtn = new JPanel();
public static JPanel panelTxt = new JPanel();
public static JTextArea txt = new JTextArea();
public static JScrollPane scroll = new JScrollPane(txt);
static String[] words;
static String link = "words.txt";
//constructor
public GUI()
{
//title
setTitle("Test");
//size
setSize(400,400);
//layout
setLayout(new BorderLayout());
//on close
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//OTHER
txt.setLineWrap(true);
txt.setWrapStyleWord(true);
txt.setEditable(false);
txt.setBackground(Color.white);
btn.setEnabled(false);
//border for panelTxt
LineBorder b1 = new LineBorder(Color.BLACK);
LineBorder b2 = new LineBorder(panelBtn.getBackground() ,5);
txt.setBorder(BorderFactory.createCompoundBorder(b2,b1));
//actionListnere
btn.addActionListener(new lst());
//add
add(scroll, BorderLayout.CENTER);
panelBtn.add(btn);
add(panelBtn, BorderLayout.SOUTH);
//visible
setVisible(true);
}
//action listener for btn
private class lst implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
new test(words);
GUI g = new GUI() ;
g.setVisible(false);
}
}
//main
public static void main(String[] args) throws IOException
{
new GUI();
final int ARRAY_LEN = getArrayLength();
words = makeArray(ARRAY_LEN);
displayArray(words);
btn.setEnabled(true);
}
//get the length of the array, using hasNext from Scanner class
private static int getArrayLength() throws IOException
{
File file = new File(link);
Scanner scanner = new Scanner(file);
int len = 0;
while(scanner.hasNext())
{
scanner.nextLine();
len++;
}
final int ARRAY_LEN = len +1;
return ARRAY_LEN;
}
//declares and initializes String array, with length of ARRAY_LEN
private static String[] makeArray(final int ARRAY_LEN) throws FileNotFoundException
{
String[] words = new String[ARRAY_LEN];
int value = 0;
int count = ARRAY_LEN;
words[value] = null;
count--;
value++;
File file = new File(link);
Scanner scanner = new Scanner(file);
do
{
words[value] = scanner.nextLine();
count--;
value++;
}while(count != 0);
return words;
}
//displays the array in text area
private static void displayArray(String[] words)
{
int len = words.length - 1;
int i = 0;
i++;
txt.setText(words[i]);
i++;
txt.setText(txt.getText() + "\t=");
txt.setText(txt.getText() + "\t" + words[i]);
do
{
i ++;
txt.setText(txt.getText() + "\n\n" + words[i]);
i++;
txt.setText(txt.getText() + "\t=");
txt.setText(txt.getText() + "\t" + words[i]);
}while(i != len);
}
}
Class 2
import javax.swing.*;
import java.util.Random;
public class test extends GUI
{
public static String[] words;
//constructor
public test(String[] word)
{
words = word;
main(word);
}
public static void main(String[] args)
{
int len = words.length;
boolean first = true;
for(int i = 0; i != len; i++)
{
if(first == true) //to skip null
{
i++;
first = false;
}
String question = words[i];
i++;
String answer = JOptionPane.showInputDialog(question+ " is?");
String rightAnswer = words[i];
if(answer.equals(rightAnswer))
JOptionPane.showMessageDialog(null, "Correct!");
else
{
JOptionPane.showMessageDialog(null, "Wrong! " + question +" means " + rightAnswer);
}
}
}
}
So here is the problem
Whenever I press the Button, it starts the test, but a new window from GUI class is created, and setVisible(false) doesn't actually do anything.
So there are 2 problmes;
1 setVisible(false) doesn't work.
2 a new window gets created at ButtonClikced(), so there are 2 identical windows, and closing one, closes the other too.
Please help because I don't know what to do
Remove the new GUI (); from the main method.
In your code, button was invisibled when action performe. But inthis time GUI object also was created. When the GUI object is created, it main method will be executed. There you are going to visible the button.
So change the
btn.setEnabled(true); to required another method.
Try this following code,
//main
public static void main(String[] args) throws IOException
{
final int ARRAY_LEN = getArrayLength();
words = makeArray(ARRAY_LEN);
displayArray(words);
// btn.setEnabled(true);
}

Event driven input vs turn based

I am trying to recreate console game with JTextArea as console/output and JTextField as user input. Since the GUI is event driven I do not understand how could I stop the code from executing, to wait for user input before proceeding with opponents turn. The only solution I can think of is While(userTurn) and userTurn would be changed to false upon actionlistener is there a better way?
My console solution
String getInput(String prompt){
String inputLine = null;
console.setTextConsole(prompt + " ");
try{
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
inputLine = is.readLine();
if(inputLine.length() == 0) return null;
}catch(IOException e){
console.setTextConsole("IOException "+e);
}
return inputLine;
}
I just called this getInput method and I proceeded with opponents turn.
What I want to accomplish is:
Opponents turn
Game waits for user
User types text into JtextField and presses enter
Game executes players command
Opponents turn again ..
I've written an example game so you can observe the difference. The computer and the user try to guess a random number between 0-2 inclusive. Who ever gets it right wins. If both get it right or both get it wrong its a draw.
EDIT: Updated GUI version
Here's the console program:
import java.util.Random;
import java.util.Scanner;
public class ConsoleGame {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
Random rand = new Random();
boolean playAgain = false;
int wins = 0, losses = 0, draw = 0;
do {
int num = rand.nextInt(3); // 0-2 inclusive
System.out.println("Guess the number [0-2]: ");
int guess = Integer.parseInt(console.nextLine());
int computerGuess = rand.nextInt(3);
System.out.println("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num);
if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
draw++;
System.out.println("Draw!");
} else if (guess == num) {
wins++;
System.out.println("You win!");
} else if (computerGuess == num) {
losses++;
System.out.println("Computer wins :(");
}
System.out.println("Play again [y/n]? ");
playAgain = console.nextLine().startsWith("y");
} while (playAgain);
System.out.println("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw);
console.close();
}
}
Here's the GUI program:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class GUIGame extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextArea textArea;
private boolean textReceived;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
GUIGame frame = new GUIGame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GUIGame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
setContentPane(contentPane);
textField = new JTextField();
textField.addActionListener(new ActionListener() {
#Override
// user pressed 'enter' key,
public void actionPerformed(ActionEvent e) {
textReceived = true;
synchronized (textField) {
// notify game loop thread which is waiting on this event
textField.notifyAll();
}
}
});
contentPane.add(textField, BorderLayout.SOUTH);
JScrollPane scrollPane = new JScrollPane();
contentPane.add(scrollPane, BorderLayout.CENTER);
textArea = new JTextArea();
textArea.setFont(new Font("Consolas", Font.PLAIN, 12));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setForeground(Color.LIGHT_GRAY);
textArea.setBackground(Color.BLACK);
textArea.setEditable(false);
scrollPane.setViewportView(textArea);
// Start game loop in new thread since we block the thread when
// waiting for input and we don't want to block the UI thread
new Thread(new Runnable() {
#Override
public void run() {
playGame();
}
}).start();
}
private void playGame() {
Random rand = new Random();
boolean playAgain = false;
int wins = 0, losses = 0, draw = 0;
do {
int num = rand.nextInt(3); // 0-2 inclusive
textArea.append("Guess the number [0-2]: \n");
int guess = Integer.parseInt(requestInput());
int computerGuess = rand.nextInt(3);
textArea.append("You: " + guess + "\tComputer: " + computerGuess + "\tNumber: " + num + "\n");
if (guess == num && computerGuess == num || guess != num && computerGuess != num) {
draw++;
textArea.append("Draw!\n");
} else if (guess == num) {
wins++;
textArea.append("You win!\n");
} else if (computerGuess == num) {
losses++;
textArea.append("Computer wins :(\n");
}
textArea.append("Play again [y/n]? \n");
playAgain = requestInput().startsWith("y");
} while (playAgain);
textArea.append("Wins: " + wins + "\nLosses: " + losses + "\nDraw: " + draw + "\n");
}
private String requestInput() {
textField.setEnabled(true);
textField.requestFocus();
// wait on text field till UI thread signals a user input event
synchronized (textField) {
while (!textReceived) {
try {
textField.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
String input = textField.getText();
textField.setText("");
textField.setEnabled(false);
textReceived = false;
return input;
}
}
Well, I think this:
The ruler of the game is that who owns the turn. As long as the ruler make its move, the other must wait. How to implement this?
If the user owns the turn, he/she may enter text in the JTextField.
When he/she presses ENTER, the command must be validated. If it is OK, the turn must be transferred to the program, and meanwhile, the user shall not even be able to enter text in the JTextField. For example, disabling it:
private void switchTurnToTheProgram()
{
jTextField.setEnabled(false);
}
When the program finalizes its move, the turn must be transferred to the user again, and so, the jTextField must be enabled:
private void switchTurnToTheUser()
{
jTextField.setEnabled(true);
}
Last, you must determine in each case whose's first turn (to make the jTextField appear enabled or disabled).
The complete algorithm:
public void startGame(boolean userOwnsTheFirstTurn)
{
if (userOwnsTheFirstTurn)
{
switchTurnToTheUser();
}
else
{
switchTurnToTheProgram();
calculateNextMove();
switchTurnToTheUser();
}
}
public void userHasEnteredSomeCommand(String command)
{
// This must be called from the correspondant actionListener.
if (validateCommand())
{
switchTurnToTheProgram();
calculateNextMove();
switchTurnToTheUser();
}
else
{
... log an error to the user ...
}
}
To enhance the user's experience, maybe it will be useful to enable/disable the button along with the textField. In that case, you'll have to modify just the two methods switchTurnToTheProgram and switchTurnToTheUser.

arithmetic expression Math.random in java

the purpose of this program is to let the user try to guess a number up to 20 randomly chosen by the computer. The user inputs their guess. The computer then tells the user if their guess is too high or too low. The user keeps inputting their guess until theu guess correctly. Then they are told how many guesses it took them. The problem is that I am not understanding whether the arithmetic expression in the program generates random numbers from 1 to 20 because when I am inputting numbers from 1 to 20, the pop-up says 'number is too big'.
package pkTopic6Exercise13;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Font;
public class Topic6Exercise13
{
private GuessingGame MyGuessingGame = new GuessingGame();
private Topic6Exercise13()
{//constructor
}
public static void main(String[] args)
{
Topic6Exercise13 myTopic6Exercise13 = new Topic6Exercise13();
myTopic6Exercise13.go();
}
private void go()
{
T6Ex13GUIin myT6Ex13GUIin = new T6Ex13GUIin();
}
private class GuessingGame
{
private int NumToGuess=0;
private int Guess=0;
private int NumGuesses=0;
private GuessingGame()
{//constructor
}
private void GenerateNum()
{
NumToGuess = 1+(int)(20*Math.random());
}
private String CheckNum()
{
NumGuesses = NumGuesses + 1;
if (Guess > NumToGuess)
{
JOptionPane.showMessageDialog(null, Guess + " is too BIG!");
return "NotGuessed";
}
else if (Guess < NumToGuess)
{
JOptionPane.showMessageDialog(null, Guess + " is too SMALL!");
return "NotGuessed";
}
else
{
JOptionPane.showMessageDialog(null, "Well done! " + Guess +" is correct, it took " + NumGuesses + " goes.");
return "Guessed";
}
}
}
private class T6Ex13GUIin extends JFrame
{
private JLabel lblGuess;
private JTextField txfGuess;
private JButton btnPickNumber;
private JButton btnQuit;
private T6Ex13GUIin()
{//constructor
Font fontDialog = new Font("Dialog", Font.BOLD,24);
this.setSize(1000,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(100,0);
this.setTitle("Guessing Game");
this.setLayout(null);
lblGuess = new JLabel("Type Guess:");
lblGuess.setFont(fontDialog);
lblGuess.setBounds(100,200,200,50);
lblGuess.setVisible(false);
this.add(lblGuess);
txfGuess = new JTextField("");
txfGuess.setBounds(300,200,100,50);
txfGuess.setFont(fontDialog);
txfGuess.setVisible(false);
ReturnListener MyReturnListener = new ReturnListener();
txfGuess.addKeyListener(MyReturnListener);
this.add(txfGuess);
ClickListener MyClickListener = new ClickListener();
btnPickNumber = new JButton("Pick Number");
btnPickNumber.setBounds(100,100,750,50);
btnPickNumber.setFont(fontDialog);
btnPickNumber.addActionListener(MyClickListener);
this.add(btnPickNumber);
btnQuit = new JButton("Quit");
btnQuit.setBounds(750,300,100,50);
btnQuit.setFont(fontDialog);
btnQuit.addActionListener(MyClickListener);
this.add(btnQuit);
this.setVisible(true);
}
private class ClickListener implements ActionListener
{
private ClickListener()
{//constructor
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == btnPickNumber)
{
MyGuessingGame.GenerateNum();
MyGuessingGame.NumGuesses=0;
btnPickNumber.setVisible(false);
lblGuess.setVisible(true);
txfGuess.setVisible(true);
txfGuess.setText("");
}
if (e.getSource() == btnQuit)
{
System.exit(0);
}
}
}
private class ReturnListener implements KeyListener
{
private ReturnListener()
{//constructor
}
public void keyPressed(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
if (e.getKeyChar() == '\n')
{
MyGuessingGame.Guess =
Integer.parseInt(txfGuess.getText());
if (MyGuessingGame.CheckNum().equals("Guessed"))
{
lblGuess.setVisible(false);
txfGuess.setVisible(false);
btnPickNumber.setVisible(true);
}
else
{
txfGuess.setText("");
}
}
}
}
}
}
Have you tried any testing? Like, debugging and seeing what value is getting set for NumToGuess? Or perhaps simply displaying the value being set? Then if you know what the random number is, you can test out your logic.
Based on your core logic, I ran this simple code below and didn't experience any problems.
public static void main(String[] args) {
int NumToGuess = 1+(int)(20*Math.random());
int myGuess = Integer.parseInt("10");
System.out.println("Value is: " + NumToGuess);
System.out.println("My Guess: " + myGuess);
if (myGuess > NumToGuess) {
System.out.println("Too Big");
}
else if (myGuess < NumToGuess) {
System.out.println("Too Small");
}
}
Math.rand() generates a random number between 0 and 1 exclusive. So by multiplying by 20 you get a value between 0 and 20 exclusive. By rounding down with the (int) cast it becomes between 0-19 inclusive and by adding one it becomes between 1-20 inclusive. So yes, your number is being generated correctly. However, you do add 1 again at the beginning of the checkNum() method so that could be a problem. Hope this helps.

Java parse strings stored in an arraylist into a calculation [duplicate]

This question already has answers here:
How does the Java 'for each' loop work?
(29 answers)
Closed 8 years ago.
So, I have an ArrayList that stores information like: {"2.0", "+", "2.0", "-", "1.0"} and I need to parse that into 2 + 2 - 1, however the method I made to do that doesnt work.
Method Code:
public static void ans()
{
Double cV = Double.parseDouble(calculate.get(0));
for(int i = 1; i < calculate.size(); i += 2)
{
switch(calculate.get(i))
{
case "+":
cV += Double.parseDouble(calculate.get(i + 1));
break;
case "-":
cV -= Double.parseDouble(calculate.get(i + 1));
break;
}
}
calc.setText("= " + cV);
}
"calculate" here is my arrayList.
What it is doing wrong is just returning the first number rather than the answer to the calculation. Any help would be appreciated!
EDIT: I added System.out.print(calculate.get(i) + ", " + calculate.get(i + 1) + ", "); into the for loop and nothing is happening... For some reason the loop isn't getting run.
EDIT: Full Code: http://pastebin.com/cP3hGgA3
EDIT: So I just added: System.out.println(calculate.size()); into the method, and it is returning 1... What is going on?
EDIT: I think the problem is here:
public static void addTo(String toAdd)
{
try{
if(!isNumeric(toAdd))
{
if(!isNumeric(calc.get(calc.size() - 1)))
{
calc.set(calc.size() - 1, toAdd);
}
}else{
calc.add(toAdd);
}
}catch(Exception e){ }
}
public static boolean isNumeric(String str)
{
try{
Double.parseDouble(str);
}catch(NumberFormatException nfe){
return false;
}
return true;
}
EDIT: Short Code:
package net.discfiresoftworks.shortcalc;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Short extends JFrame
{
private static final long serialVersionUID = 1L;
public static ArrayList<String> calc = new ArrayList<String>();
public static JLabel ans = new JLabel("");
public static void main(String[] args)
{
new Short();
}
public Short()
{
this.setSize(300, 300);
this.setDefaultCloseOperation(3);
this.setLayout(new FlowLayout());
JButton b1 = new JButton("Click me");
JButton b2 = new JButton("then me");
JButton b3 = new JButton("then me.");
b1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0)
{
addTo("1");
}
});
b2.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0)
{
addTo("+");
}
});
b3.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0)
{
addTo("1");
ans();
}
});
this.add(b1);
this.add(b2);
this.add(b3);
this.add(ans);
this.setVisible(true);
}
public static void addTo(String toAdd)
{
try{
if(!isNumeric(toAdd))
{
if(!isNumeric(calc.get(calc.size() - 1)))
{
calc.set(calc.size() - 1, toAdd);
}
}else{
calc.add(toAdd);
}
}catch(Exception e){ }
}
public static boolean isNumeric(String str)
{
try{
Double.parseDouble(str);
}catch(NumberFormatException nfe){
return false;
}
return true;
}
public static void ans()
{
Double cV = Double.parseDouble(calc.get(0));
System.out.println(calc.size());
for(int i = 1; i < calc.size(); i += 2)
{
switch(calc.get(i))
{
case "+":
cV += Double.parseDouble(calc.get(i + 1));
break;
}
}
ans.setText("= " + cV);
}
}
This should do the trick (I suupose that calculate is the array in the form {"2.0", "+", "2.0", "-", "1.0"}:
public static void ans() {
Double total = 0.0;
boolean isSum = true;
for (String input : calculate) {
switch (input) {
case "+":
isSum = true;
break;
case "-":
isSum = false;
break;
default:
if (isSum)
total += Double.parseDouble(input);
else
total -= Double.parseDouble(input);
break;
}
}
/*
* Now you have the total variable which stores the sum.
* You can do whatever you want with it, like printing
* it along with the result.
*/
for (String input : calculate) {
System.out.print(input+" ");
}
System.out.print(" = "+total);
}
However, this will not work (as expected) if you have an array like this:
{"2.0", "+", "5.0", "7.0"}
As it will sum the 5 and the 7 because it stores the last sign you used, you may want to implement some sort of vallidation method that requires symbols between numbers. But if you're sure your input will always be number, symbol, number then it'll no problem with this code.

how to insert characters at particular index in JFormattedTextField of MaskFormatter in Java?

I have a string which is say "AAAABB". I have a JFormattedField of MaskFormatter. so I have ? ? ? ? ? ? in my Frame. I have two buttons A and B. when the user presses A button, the JFormattedField of the MaskFormatter should replace ? with Letter A for all occurrences of A. i.e, index 0,1,2,3 in this example.
I have my code that gets the list of indices to be replaced with A. But I am having difficulty in implementing setLetter(String Letter, int Position) method, that takes letter and indices to be replaced in the JformattedField. example if I pass setLetter("A",2), I should get ? ? A ? ? ? in the above example. Please try this code to see the frame.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.MaskFormatter;
public class TestMain extends JPanel{
JFormattedTextField input;
private MaskFormatter formatter;
public final String WORD = "ABBAABBA";
public TestMain() {
try {
JLabel label = new JLabel("Guesss");
String s="";
for (int i =0;i<WORD.length();i++){
s+="? ";
}
formatter = new MaskFormatter(s);
formatter.setPlaceholderCharacter('?');
input = new JFormattedTextField(formatter);
input.setColumns(20);
add(label);
add(input);
} catch (java.text.ParseException exc) {
System.err.println("formatter is bad: " + exc.getMessage());
System.exit(-1);
}
JButton buttonA = new JButton("A");
JButton buttonB = new JButton("B");
buttonA.addActionListener(clickedbutton());
buttonB.addActionListener(clickedbutton());
add(buttonA);
add(buttonB);
}
private ActionListener clickedbutton() {
return new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton pressedButton = (JButton) e.getSource();
String letter = e.getActionCommand();
try {
//System.out.println("actionCommand is: ---" + letter);
//Get the list of indices
int index = WORD.indexOf(letter);
ArrayList<Integer> indices = new ArrayList<Integer>();
if (index>=0){
for(int j=0;j<WORD.length();j++){
if (WORD.charAt(j)==letter.charAt(0)){
indices.add(j);
}
}
//System.out.println(indices);
}
for (int k =0 ; k < indices.size(); k++){
setLetter(letter, k);
}
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
};
}
public void setLetter(String letter, int position) throws ParseException {
String word="Hello";
input.setValue(letter);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
TestMain tm = new TestMain();
frame.add(tm);
frame.pack();
frame.setTitle("formatter");
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I don't think a mask formatter is what you want for this because you aren't really formatting a string here. If you just want to take a string and set characters at certain positions you should formulate the string yourself.
String text = "";
for (int i = 0; i < WORD.length(); i++) {
if (String.valueOf(word.charAt(i)).equals(letter)) {
text += letter + " ";
} else {
text += "? ";
}
}
input.setText(text);
Also a style note: all caps is for identifiers of static variables.

Categories