hangman picture isn't changing - java

I'm busy writing an hangman application and I'm currently checking if some of the code works... now i haven't gotten to hiding the word part yet so in the place of that code i used an if statement as supplementary code:
if(original.indexOf(button.getText())!=-1){
JOptionPane.showMessageDialog(null, "Your word does contain" + text );
}
else{
JOptionPane.showMessageDialog(null, "There is no" + text );
error++;
}
}
Anyway when I press the buttons that's not in the word it suppose to add to my errors according to
error++;
and it only finds the first letter in the word. One of my words are Dinosaur when i press D it says "Yes, there is a D" but when I press A it says "No, there is no I" where the clearly is
Can someone please help
here's my full code
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.List;
public final class Hangman extends JFrame implements ActionListener{
String original = readWord();
int error = 0;
String imageName;
JButton btnAddWord = new JButton("Add New Word");
JButton btnRestart = new JButton("Restart");
JButton btnHelp = new JButton("Help");
JButton btnExit = new JButton("Exit");
JLabel word = new JLabel(original);
static JPanel panel1 = new JPanel();
static JPanel panel2 = new JPanel();
static JPanel panel3 = new JPanel();
static JPanel panel4 = new JPanel();
public Hangman(){
Container content =getContentPane();
content.setLayout(new GridLayout(0,1));
if(error >= 0) imageName = "hangman1.jpg";
if(error >= 1) imageName = "hangman2.jpg";
if(error >= 2) imageName = "hangman3.jpg";
if(error == 3) imageName = "hangman4.jpg";
if(error == 4) imageName = "hangman5.jpg";
if(error == 5) imageName = "hangman6.jpg";
if(error == 7) imageName = "hangman7.jpg";
ImageIcon icon = null;
if(imageName != null){
icon = new ImageIcon(imageName);
}
JLabel image = new JLabel();
image.setIcon(icon);
btnAddWord.addActionListener(this);
btnRestart.addActionListener(this);
btnHelp.addActionListener(this);
btnExit.addActionListener(this);
panel2.add(image);
panel3.add(word);
panel4.add(btnAddWord);
panel4.add(btnRestart);
panel4.add(btnHelp);
panel4.add(btnExit);
for(char i = 'A'; i <= 'Z'; i++){
String buttonText = new Character(i).toString();
JButton button = getButton(buttonText);
panel1.add(button);
}
}
public JButton getButton(final String text){
final JButton button = new JButton(text);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(original.indexOf(button.getText())!=-1){
JOptionPane.showMessageDialog(null, "Your word does contain " + text );
}
else{
JOptionPane.showMessageDialog(null, "There is no " + text );
error++;
}
}
});
return button;
}
public String readWord(){
try{
BufferedReader reader = new BufferedReader(new FileReader("Words.txt"));
String line = reader.readLine();
List<String> words = new ArrayList<String>();
while(line != null){
String[] wordsLine = line.split(" ");
boolean addAll = words.addAll(Arrays.asList(wordsLine));
line = reader.readLine();
}
Random rand = new Random(System.currentTimeMillis());
String randomWord = words.get(rand.nextInt(words.size()));
return randomWord;
}catch (Exception e){
return null;
}
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == btnAddWord){
try{
FileWriter fw = new FileWriter("Words.txt", true);
PrintWriter pw = new PrintWriter(fw, true);
String word = JOptionPane.showInputDialog("Please enter a word: ");
pw.println(word);
pw.close();
}
catch(IOException ie){
System.out.println("Error Thrown" + ie.getMessage());
}
}
if(e.getSource() == btnRestart){
}
if(e.getSource() == btnHelp){
String message = "The word to guess is represented by a row of dashes, giving the number of letters and category of the word."
+ "\nIf the guessing player suggests a letter which occurs in the word, the other player writes it in all its correct positions."
+ "\nIf the suggested letter does not occur in the word, the other player draws one element of the hangman diagram as a tally mark."
+ "\n"
+ "\nThe game is over when:"
+ "\nThe guessing player completes the word, or guesses the whole word correctly"
+ "\nThe other player completes the diagram";
JOptionPane.showMessageDialog(null,message, "Help",JOptionPane.INFORMATION_MESSAGE);
}
if(e.getSource() == btnExit){
System.exit(0);
}
}
public static void main (String [] args){
Hangman frame = new Hangman();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 600);
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.add(panel3, BorderLayout.SOUTH);
frame.add(panel4, BorderLayout.SOUTH);
}
}

My first guess is that your text comparison is case sensitive.
"Dinosaur".indexOf("A") is not the same as "Dinosaur".indexOf("a")
I'd suggest converting the text to common case when you compare it.
original.toLowerCase().indexOf(button.getText().toLowerCase())!=-1

This is because you're not correctly checking whether the word that you're reading from the file is in the same case as the text in your JButton. There're a couple of ways to fix this:
As #MadProgrammer suggested. Have a couple of checks to cover both lowercase and uppercase characters.
Standardizing your List<String> words i.e. keep everything in one case when you're reading from the file. That way you don't have to worry much in terms of checking whether its in lowercase or uppercase. So in this case you might want to change: String[] wordsLine = line.split(" "); to String[] wordsLine = line.toLowerCase().split(" "); or String[] wordsLine = line.toUpperCase().split(" "); (depending on which one you're comfortable with). Then your check with a single indexOf() operation looks fine.

Related

How to refer to specified button based on certain characteristic effectively

This question is similar to this : How do you reference a button inside of its actionlistener?
I want to create a simple form containing 8 toggle buttons. if i select the toggle button and click save button, it will write into the text file i.e "Button x, On". Next time i open the form, the form will check in the notepad if Button x is already on. If on, the toggle button will already be selected and vice versa.
I know how to write to and read from the notepad, but i am not sure how to check if i.e the user select button 2 then the code will write into second line " Button2, on"
Here is my code so far to write :
Path path = Paths.get(csvFile);
// check if button x is selected, if yes : <- how to refer to button x ?
BufferedWriter bw = new BufferedWriter(New FileWriter(csvFile, true);
writer.write ("button x,on" + "\r\n");
writer.close
and this is my code when the form is opened :
BufferedReader br = null;
String line = "";
String resFilesplitby = ",";
br = new BufferedReader(new FileReader(csvFile));
while((line = br.readLine()) != null){
String[] condition = line.split(csvFilesplitby);
String power = condition[1];
// check if button x is already selected
if (button x power.equals("on")){
button x.isSelected();
}
}
I manage to found a simple way to solve the problem
By adding the button to an array.
JToggleButton[] buttons = new JToggleButton[8];
buttons[0] = seat1; //this is variable name of my button.
buttons[1] = seat2;
buttons[2] = seat3;
buttons[3] = seat4;
buttons[4] = seat5;
buttons[5] = seat6;
buttons[6] = seat7;
buttons[7] = seat8;
// do the work here
for (JToggleButton btn : buttons){
if(btn.isSelected){
}
}
For simplicity I recommend that you write all of the button statuses at the same time, and write them directly as a boolean value:
//Write the state of all the buttons in a single line:
writer.write (
x1.isSelected() + "," +
x2.isSelected() + "," +
x3.isSelected() + "," +
x4.isSelected() + "," +
x5.isSelected() + "," +
x6.isSelected() + "," +
x7.isSelected() + "," +
x8.isSelected());
Then reading it back as a single line and just compare each of the 8 items split by the ",":
String[] condition = line.split(csvFilesplitby);
if (condition[0].equalsIgnoreCase("true")){
x1.setSelected(true);
}else if (condition[1].equalsIgnoreCase("true")){
x2.setSelected(true);
}else if (condition[2].equalsIgnoreCase("true")){
x3.setSelected(true);
}else if (condition[3].equalsIgnoreCase("true")){
x4.setSelected(true);
}else if (condition[4].equalsIgnoreCase("true")){
x5.setSelected(true);
}else if (condition[5].equalsIgnoreCase("true")){
x6.setSelected(true);
}else if (condition[6].equalsIgnoreCase("true")){
x7.setSelected(true);
}else if (condition[7].equalsIgnoreCase("true")){
x8.setSelected(true);
}
Obviously you should add some error checking and make sure all buttons are deselected before you set if they are selected or not. But I am sure you can work that part out.
Alternatively you can try something like below :
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import javax.swing.*;
public class Ques1 extends JFrame implements ActionListener {
private JPanel panel;
private JToggleButton[] buttons;
public Ques1() {
initComponents();
buttonswork();
}
private void initComponents() {
buttons = new JToggleButton[6];
panel = new JPanel();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.LINE_AXIS));
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
for (int i = 0; i < buttons.length; i++) {
JToggleButton tb = buttons[i];
tb = new JToggleButton("tb" + (i + 1));
tb.addActionListener(this);
panel.add(tb);
}
getContentPane().add(panel);
pack();
}
private void buttonswork() {
try {
String line = "";
String buttonString = "tb1-0\n"
+ "tb2-0\n"
+ "tb3-0\n"
+ "tb4-1\n"
+ "tb5-1\n"
+ "tb6-0\n";
BufferedReader br = new BufferedReader(new StringReader(buttonString));
while ((line = br.readLine()) != null) {
Component[] components = panel.getComponents();
for (Component c : components) {
if (c instanceof JToggleButton) {
String ac = ((JToggleButton) c).getActionCommand();
((JToggleButton) c).addActionListener(this);
if (ac.equalsIgnoreCase(line.split("-")[0])) {
((JToggleButton) c).setSelected(Integer.parseInt(line.split("-")[1]) == 1);
}
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new Ques1().setVisible(true);
});
}
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "tb1":
//do your work here ...
break;
case "tb2":
//do your work here ...
break;
}
}
}

Troubleshooting Vignere Cipher using JFileChooser and JPasswordField

I'm attempting to make a code that will use JFileChooser and JPassword for getting input of encrypted code or code to be encrypted.
Here is the code to be encrypted "Be sure to drink your Ovaltine!" to be saved in a .rtf or a .txt file. The key is "annie". The output should be
"Fv '$zi (# pzm"| (wy& `%ip(zzm%".
I have two different class files under the project "Password". One class is called "File Opener". It calls the class "Password1".
Here is Password1.java.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
/* PasswordDemo.java requires no other files. */
public class Password1 extends JPanel
implements ActionListener {
private String key;
private static String OK = "ok";
private JFrame controllingFrame; //needed for dialogs
private JPasswordField passwordField;
public Password1(JFrame f) {
//Use the default FlowLayout.
controllingFrame = f;
//Create everything.
passwordField = new JPasswordField(10);
passwordField.setActionCommand(OK);
passwordField.addActionListener(this);
JLabel label = new JLabel("Enter the key: ");
label.setLabelFor(passwordField);
JComponent buttonPane = createButtonPanel();
//Lay out everything.
JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
textPane.add(label);
textPane.add(passwordField);
add(textPane);
add(buttonPane);
}
protected JComponent createButtonPanel() {
JPanel p = new JPanel(new GridLayout(0,1));
JButton okButton = new JButton("OK");
okButton.setActionCommand(OK);
okButton.addActionListener(this);
p.add(okButton);
return p;
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
controllingFrame.dispose();
if (OK.equals(cmd)) { //Process the password.
char[] input = passwordField.getPassword();
key = new String(input);
//Zero out the possible password, for security.
Arrays.fill(input,'0');
passwordField.selectAll();
resetFocus();
} else {
System.out.println("Please enter a key.");
}
}
public String getKey(){
return key;
}
//Must be called from the event dispatch thread.
protected void resetFocus() {
passwordField.requestFocusInWindow();
}
public static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Key");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
final Password1 newContentPane = new Password1(frame);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Make sure the focus goes to the right component
//whenever the frame is initially given the focus.
frame.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
newContentPane.resetFocus();
}
});
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
And here is the FileOpener.java.
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.*;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class FileOpener extends JPanel implements ActionListener {
static private final String newline = "\n";
private Password1 p1;
JButton decodeButton, encodeButton;
JFileChooser fc;
JTextArea log;
Scanner in = new Scanner(System.in);
JFrame frame;
File file;
int count;
public FileOpener(){
// create and set up the window.
frame = new JFrame("Open Your File");
// make the program close when the window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create the box layout
frame.getContentPane( ).setLayout(new BoxLayout(frame.getContentPane( ), BoxLayout.Y_AXIS));
//label prompting user for input
JLabel label1 = new JLabel ("Would you like to encode or decode your file?", JLabel.CENTER);
frame.getContentPane().add(label1);
//create a filer chooser
fc = new JFileChooser();
// add a button object
decodeButton = new JButton("Decode");
decodeButton.addActionListener(this);
frame.getContentPane( ).add(decodeButton);
encodeButton = new JButton("Encode");
encodeButton.addActionListener(this);
frame.getContentPane( ).add(encodeButton);
// display the window.
frame.pack( );
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
//Handle open button action.
if (e.getSource() == encodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION ) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
FileInputStream file2= new FileInputStream(file);
//create a scanner for it
in = new Scanner(file2);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii += keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii>126){
ascii-= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.println(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
//Handle save button action.
} else if (e.getSource() == decodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//open the file
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//create a scanner for it
in = new Scanner(file);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii -= keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii<33){
ascii+= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.print(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
in.close();
log.append("Opening: " + file.getName() + "." + newline);
}
}
public static void main(String args[]) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
FileOpener f = new FileOpener();
}
}
It was working fine before I added the JFileChooser and the Password stuff aka there shouldn't be anything wrong with the actual ciphering part of the code.
It's giving me a java.lang.NullPointerException at line at line 70 in FileOpener.
int length3 = key.length();
Thanks!
In the createAndShowGUI() method, you show your Password1 instance in a JFrame, not a modal JDialog. Therefore, this display instruction is non-blocking, i.e. it does not stop code execution, nor does it wait until you click a button that closes the window.
As a result, you retrieve the Password1 instance key before its actionPerformed() method can execute and initialize the key attribute, hence the key is still null and you get a NullPointerException when you invoke any method on it.
My suggestion is using a modal JDialog in createAndShowGUI() to manage your Password1 interface (initialization using a JPanel is much like what you are already doing with a JFrame). This way, when you invoke createAndShowGUI(), the FileOpener.actionPerformed() method execution will block until you are done with the Password1 dialog, hence you will make sure key is properly initialized before you retrieve and use it in FileOpener.actionPerformed().
One last thing: be careful with frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);! Using it on your main window is OK but using it on any secondary window will make the whole program shut down completely as soon as you close it. But anyway, the JDialog version of setDefaultCloseOperation() doesn't accept EXIT_ON_CLOSE as a valid argument, so you will remain using it only on your main FileOpener window, which is fine.

How do I make my count variable increment correctly?

I am trying to create a java applet that uses text fields to add strings to a linked list. I can not get the search button to work. I am trying to get the string specified by the user in the text field and then search the list and print how many times the word has been found if any.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* Created by joshuaogunnote on 31/10/2015.
*/
public class Applet2 extends JApplet {
private String text;
private int text1;
JTextField value1, value2;
LinkedList<String> list = new LinkedList<String>();
public JLabel jLabel;
public int count = 0;
I have created this search_count variable to count up how many times the word has been found.
public int search_count = 0;
public void init() {
JLabel prompt = new JLabel("Please enter a word");
JLabel prompt1 = new JLabel("Please enter a certain letter");
value1 = new JTextField(10);
value2 = new JTextField(10);
JPanel textPanel = new JPanel();
textPanel.add(prompt);
textPanel.add(value1);
add(textPanel, BorderLayout.NORTH);
textPanel.add(prompt1);
textPanel.add(value2);
JPanel centrePanel = new JPanel();
text = "";
jLabel = new JLabel(text);
centrePanel.add(jLabel);
add(centrePanel, BorderLayout.CENTER);
JButton but = new JButton("Add word");
JButton but1 = new JButton("Clear");
JButton but2 = new JButton("Remove first occurrence");
JButton but3 = new JButton("Remove all occurrences");
JButton but4 = new JButton("Display all words begging with certain letter");
JButton but5 = new JButton("Search");
JPanel butPanel = new JPanel();
butPanel.add(but);
butPanel.add(but1);
butPanel.add(but5);
butPanel.add(but2);
butPanel.add(but3);
butPanel.add(but4);
add(butPanel, BorderLayout.SOUTH);
but.addActionListener(new ButtonHandler(this));
but1.addActionListener(new ButtonHandler1(this));
but5.addActionListener(new ButtonHandler2(this));
}
class ButtonHandler implements ActionListener {
private Applet2 theApplet;
public ButtonHandler(Applet2 app) {
theApplet = app;
}
public void actionPerformed(ActionEvent e) {
text = theApplet.value1.getText();
try {
text1 = Integer.parseInt(text);
jLabel.setText("ERROR - The string " + "'" + text1 + "'" + " is not a valid word");
} catch (NumberFormatException e1) {
if (text.length() != 0) {
jLabel.setText("Word " + "'" + text + "'" + " has been added to the list");
count = count + 1;
} else {
jLabel.setText("ERROR - Please enter a word");
}
}
}
}
class ButtonHandler1 implements ActionListener {
private Applet2 theApplet;
public ButtonHandler1(Applet2 app) {
theApplet = app;
}
public void actionPerformed(ActionEvent e) {
list.clear();
jLabel.setText("List has been cleared");
count = 0;
}
}
class ButtonHandler2 implements ActionListener {
private Applet2 theApplet;
public ButtonHandler2(Applet2 app) {
theApplet = app;
}
public void actionPerformed(ActionEvent e) {
String text = theApplet.value1.getText();
Here I am trying to use a for loop to iterate through all the strings in the list and increment search_count if a match has been found. It does not however produce the correct answer. I am also trying to produce an ERROR message when the user tries to search for a word that is not in the list. How do I get the search_count variable and how do I get the ERROR message to show at the correct time?
for (int i = 0; i < list.size(); i++) {
if(text.equals(list.get(i))){
search_count = search_count + 1;
} else {
jLabel.setText("ERROR - word is not in the list")
}
jLabel.setText("Word " + "'" + text + "'" + " was found " + search_count + " time(s) in the list");
if (text.length() == 0) {
jLabel.setText("Please enter a word - The total number of words in the list are: " + count);
}
}
}
}
It seems you did not declare count as a variable before you used it in the loop. If the output is not what you want / expect, the condition of the loop gives you something else then what you think it does.
int count = 0;

Searching for specific text in a text file. Returning it to a textbox

I am very new to java. I am working on project for class that would look up books in a text file and display information about them. Primarily if the book is in stock or not. The text file is set up like this: {ISBN, Author, Type, Stock}
I have coded a user interface that allows the user to type in ISBN, Author, and Type. Ideally, I would like for the user to just search one of these and return the needed information. However, just searching via ISBN would be acceptable for now. My code right now only takes what is typed into the textboxes and displays it in a large textbox. I am somewhat familiar with reading a text file in but have no idea how I would take the text from a textbox and use it to search the file. Any help would be greatly appreciated.
Here is my code:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.sql.*;
public class InventoryInterface extends JFrame
{
private static final int FRAME_WIDTH = 600;
private static final int FRAME_HEIGHT = 350;
private JButton btnSearch;
private JButton btnDatabase;
private JButton btnRefresh;
private JLabel lblISBN, lblAuthor, lblType;
private JTextField txtISBN, txtAuthor, txtType;
private JTextArea txtOutput;
public InventoryInterfaceSimple()
{
createComponents();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
}
public void createComponents()
{
btnSearch = new JButton("Search");
lblISBN = new JLabel("ISBN");
lblAuthor = new JLabel("Author");
lblType = new JLabel("Type");
txtISBN = new JTextField(10);
txtAuthor = new JTextField(10);
txtType = new JTextField(10);
txtOutput = new JTextArea(30,30);
txtOutput.setText("");
txtOutput.setEditable(false);
ActionListener action = new InventoryOutput();
btnSearch.addActionListener(action);
JPanel panel = new JPanel();
panel.setLayout(null);
lblISBN.setBounds(10,10,50,25);
txtISBN.setBounds(55,10,125,25);
lblAuthor.setBounds(10,40,50,25);
txtAuthor.setBounds(55,40,125,25);
lblType.setBounds(10,70,50,25);
txtType.setBounds(55,70,125,25);
btnSearch.setBounds(30,130,150,25);
JScrollPane scrollArea = new JScrollPane(txtOutput);
scrollArea.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollArea.setBounds(200,10,350,200);
panel.add(scrollArea);
panel.add(lblISBN);
panel.add(txtISBN);
panel.add(lblAuthor);
panel.add(txtAuthor);
panel.add(lblType);
panel.add(txtType);
panel.add(btnSearch);
panel.add(scrollArea);
add(panel);
}
class InventoryOutput implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String inventoryString = "";
inventoryString += txtISBN.getText() + " - ";
inventoryString += "Author: " + txtAuthor.getText() + " - ";
inventoryString += "Type: " + txtType.getText() + " - ";
txtOutput.append(inventoryString + "\n");
txtISBN.setText("");
txtAuthor.setText("");
txtType.setText("");
}
}
}
​
you can replace your code with this.. this is a starting point, you can do many improvements to this code, but this will work. change REPOSITORY_FILE_PATH to your data file
class InventoryOutput implements ActionListener {
private final String REPOSITORY_FILE_PATH = "C:\\temp\\book-repo.txt";
private final File REPOSITORY_FILE = new File(REPOSITORY_FILE_PATH);
public void actionPerformed(ActionEvent event) {
String inventoryString = "";
String requestedISBN = txtISBN.getText().trim().toLowerCase();
String requestedAuthor = txtAuthor.getText().trim();
String requestedType = txtType.getText().trim();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(REPOSITORY_FILE));
String line;
while ((line = reader.readLine()) != null) {
String lineLtrim = line.toLowerCase().replaceAll("^\\{", ""); //{
String lineRtrim = lineLtrim.replaceAll("\\}$", ""); //}
String[] data = lineRtrim.split(","); //ISBN, Author, Type, Stock
if (data.length < 4) {
throw new IllegalArgumentException("bad datafile: All fields must be entered: " + line);
}
if (data[0].equals(requestedISBN)) {
inventoryString += txtISBN.getText() + " - Author: " + data[1] + " - Type: " + data[2] + " - Stock:" + data[3];
txtOutput.append(inventoryString + "\n");
return;
}
}
reader.close();
inventoryString += txtISBN.getText() + " - Not Found";
txtOutput.append(inventoryString + "\n");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
you can just add this main() code to test, ideally you should write unit test-- to cover all cases.
public static void main(String[] args) {
JFrame f = new InventoryInterface();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(600, 600));
f.pack();
f.setVisible(true);
}
data file
{ISBN1234,me,drama,5}
{ISBN1235,me,Tech,0}
{ISBN1236,me,Fiction,2}
{ISBN1237,me,Audio/Kids,4}
Not sure which part you did not get,,
on the listener-- we read the ISBN entered by user String
requestedISBN = txtISBN.getText().trim().toLowerCase(); and convert
it in lower case so, we can compare with lower-cased-data
then we read your data file (line by line)
we then from each line we remove character "{" and "}" // comment
says that
then we get "isbn,author, type, stock" , so we split by ","
split gives us array of string putting each element in array in
order i.e data[0] has isbn, data[1] has author ...etc
we check if the data file is correct by making sure we have all
elements in there i.e if (data.length < 4) {
we throw exception if the size of array is not <4 i.e. we found that
the data file has incorrect data.
then we compare if the input isbn (data[0]) is same as one of the
line element from your data file
if we find a match we display it in the textArea and exit the loop,
if we dont find we display "not Found"
If you wrote the code (listener) yourself, this should be trivial to you.
You could create a private String chosenISBN and set the value of it in the actionPerformed method. Then you can access the value everywhere in the class.
You could even create a getter for the chosenISBN as well, if you need it.

Displaying an array of Strings in a JTextArea

i've been stuck on getting one of my JTextArea's to display an array of Strings that represent letters in a word in a hangman game. Once the user guesses a letter, (assuming it's right), it should reflect into the array. Instead, it seems to be only adding the letter that was guessed, and not the blanks or the rest of the array. I want to set the guessed letter equal to the correct index in the array and then have it shown on the screen. Here is my code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
#SuppressWarnings("serial")
public class GuiClass extends JFrame {
char guess = ' ';
int numGuesses = 0;
char[] letterGuessedAgainst = null;
String wordInPlay = " ";
String[] hangmanScores = null;
ArrayList<Character> wrongGuesses = null;
boolean isGuessSuccessfull = false;
private Container contents;
JRadioButton rbEasy;
JRadioButton rbHard;
ButtonGroup difficultyGroup;
JTextField txtfldWord;
JTextArea txtareaWord;
JLabel difficultyPrompt;
JLabel userDifficulty;
JButton btnStartGame;
JButton btnGuessSubmit;
JButton btnWordGuessSubmit;
JPanel topPanel;
JPanel midPanel;
JLabel topLabel;
JPanel guessPanel;
JPanel letterPanel;
JLabel word;
JTextArea txtareaNumGuesses;
JTextField txtfldGuess;
JTextField txtfldWordGuess;
JTextArea txtareaguessedLetters;
JTextArea txtareaLettersLeft;
public GuiClass(){
super("Hangman GUI");
contents = getContentPane();
//create a new panel & set layout
midPanel = new JPanel();
midPanel.setLayout(new GridLayout(3,3));
//layout manager
topLabel = new JLabel("Welcome to Hangman!");
contents.setLayout(new FlowLayout());
//create new ButtonHandlers
ButtonHandler buttonHandler = new ButtonHandler();
ButtonHandler2 btnHndlrNewGame = new ButtonHandler2();
//create difficulty buttons/labels & add ActionListeners
difficultyPrompt = new JLabel("First, Choose A Difficulty:");
rbEasy = new JRadioButton("Easy");
rbHard = new JRadioButton("Hard");
userDifficulty = new JLabel("Game Difficulty: ");
difficultyGroup = new ButtonGroup();
difficultyGroup.add(rbEasy);
difficultyGroup.add(rbHard);
rbEasy.addItemListener(buttonHandler);
rbHard.addItemListener(buttonHandler);
midPanel.add(topLabel);
midPanel.add(difficultyPrompt);
midPanel.add(rbEasy);
midPanel.add(rbHard);
midPanel.add(userDifficulty);
topPanel = new JPanel();
JLabel btnStartNewGame = new JLabel("Next, Start a new game!");
btnStartGame = new JButton("Start A New Game");
btnStartGame.addActionListener(btnHndlrNewGame);
topPanel.add(btnStartNewGame);
topPanel.add(btnStartGame);
guessPanel = new JPanel();
JLabel lblGuess = new JLabel("Guess: ");
JLabel lblWordGuess = new JLabel("Word Guess: ");
btnGuessSubmit = new JButton("Submit");
btnGuessSubmit.addActionListener(btnHndlrNewGame);
btnWordGuessSubmit = new JButton("Submit");
btnGuessSubmit.addActionListener(btnHndlrNewGame);
txtfldGuess = new JTextField(10);
txtfldWordGuess = new JTextField(10);
guessPanel.add(lblGuess);
guessPanel.add(txtfldGuess);
guessPanel.add(btnGuessSubmit);
guessPanel.add(lblWordGuess);
guessPanel.add(txtfldWordGuess);
guessPanel.add(btnWordGuessSubmit);
letterPanel = new JPanel();
JLabel lblGuessedLetters = new JLabel("Guessed Letters:");
JLabel lblLettersInWord = new JLabel("Letters Left:");
JLabel lblNumGuesses = new JLabel("Guess Number: ");
txtareaNumGuesses = new JTextArea(5,5);
txtareaNumGuesses.setEditable(false);
txtareaguessedLetters = new JTextArea(5,15);
txtareaguessedLetters.setEditable(false);
txtareaLettersLeft = new JTextArea(5,15);
txtareaLettersLeft.setEditable(false);
letterPanel.add(lblGuessedLetters);
letterPanel.add(txtareaguessedLetters);
letterPanel.add(lblLettersInWord);
letterPanel.add(txtareaLettersLeft);
letterPanel.add(lblNumGuesses);
letterPanel.add(txtareaNumGuesses);
JPanel wordPanel = new JPanel();
word = new JLabel("Word is: ");
//txtfldWord = new JTextField(10);
txtareaWord = new JTextArea(20,20);
//txtfldWord.setEditable(false);
txtareaWord.setEditable(false);
wordPanel.add(word);
//wordPanel.add(txtfldWord);
wordPanel.add(txtareaWord);
//add contents of panels to the container
contents.add(midPanel);
contents.add(topPanel);
contents.add(guessPanel);
contents.add(letterPanel);
contents.add(wordPanel);
setSize(800,600);
setVisible(true);
}//end constructor
private class ButtonHandler implements ItemListener{
public void itemStateChanged(ItemEvent ie){
if (ie.getSource()==rbEasy){
userDifficulty.setText("Game Difficulty: Easy");
}//end if
if (ie.getSource()==rbHard){
userDifficulty.setText("Game Difficulty: Hard");
}//end if
}//end method
}//end ButtonHandler inner class
private class ButtonHandler2 implements ActionListener{
public void actionPerformed(ActionEvent ae){
if (ae.getSource()==btnStartGame){
if (rbEasy.isSelected()){
ArrayList<String> easyHmWords = new ArrayList<String>();
String filename = "easyhangmanwords.txt";
BufferedReader infile = null;
try {
infile = new BufferedReader(new FileReader(filename));
}//end try
catch (FileNotFoundException e) {
e.getMessage();
}//end catch
String re = "";
try {
while ((re=infile.readLine())!=null){ // reading one line
easyHmWords.add(re);
}//end while
System.out.println("words in file: "+easyHmWords);
}//end try
catch (IOException e) {
e.getMessage();
}//end while
try {
infile.close();
}//end try
catch (IOException e) {
e.getMessage();
}//end catch
wordInPlay = "";
int randomNumber = 0;
Random rand = new Random();
int maxRandomNumber = 0;
word.setText("Word is: Set");
//System.out.println("Okay, the word is set!");
maxRandomNumber = easyHmWords.size();
System.out.println("Size of arraylist: "+easyHmWords.size());
randomNumber = rand.nextInt(maxRandomNumber);
System.out.println("random num: "+randomNumber);
wordInPlay = easyHmWords.get(randomNumber);
System.out.println("word in play: "+wordInPlay);
//figures out how many letters the word has
int lettersInWord = wordInPlay.length();
System.out.println("Letters in word: "+lettersInWord);
//creates an array of hangman scores which is the size of the letters in the word
hangmanScores = new String[lettersInWord];
//for loop to iterate through the array and assign "_" to the spaces
for (int i = 0; i < hangmanScores.length; i++) {
hangmanScores[i] = " _ ";
}//end for
for (int i = 0; i < hangmanScores.length; i++){
//txtareaWord.setText(hangmanScores[i]);
//txtfldWord.append(hangmanScores[i]);
txtareaWord.append((hangmanScores[i]));
}//end for
}//end if
}//end if
if(btnGuessSubmit == ae.getSource()){ //getting problems in this if statement
guess = txtfldGuess.getText().charAt(0);
letterGuessedAgainst = wordInPlay.toCharArray();
for (int i = 0; i < letterGuessedAgainst.length; i++) {//goes through the letters of the word in play
***if(letterGuessedAgainst[i]==guess){//if a letter matches up,
hangmanScores[i] = Character.toString(guess);
isGuessSuccessfull = true;
}//end if
}//end for
for (int k =0; k < hangmanScores.length; k++){//displays the ______ in the text area
txtareaWord.setText((hangmanScores[k]));***
System.out.print(hangmanScores[k]);//testing purposes
}//end for
numGuesses++;
txtareaNumGuesses.setText(" "+numGuesses);
}//end for
if(isGuessSuccessfull = false){
wrongGuesses.add(guess);
txtareaguessedLetters.append(wrongGuesses+"");
}//end if
}//end method
}//end private inner class
public static void main (String[] args){
GuiClass estGUI = new GuiClass();
estGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}//end main method
}//end class
this is the part of the code that doesn't display the correct parts of the array:
***if(letterGuessedAgainst[i]==guess){//if a letter matches up,
hangmanScores[i] = Character.toString(guess);
isGuessSuccessfull = true;
}//end if
}//end for
for (int k =0; k < hangmanScores.length; k++){
txtareaWord.setText((hangmanScores[k]));***
Basically, you are calling setText every time you want to add a new character to the JTextArea in question, this is, first, clearing any existing text and then adding the new String, which, in this case, is the last thing you entered.
There are a few ways you could fix this, but because you want to remove the existing text first and then replace it, it's probably better to build a buffer of what you want and apply it all in a single step...
StringBuilder sb = new StringBuilder(hangmanScores.length);
for (int k = 0; k < hangmanScores.length; k++) {//displays the ______ in the text area
sb.append(hangmanScores[k]);
System.out.print(hangmanScores[k]);//testing purposes
}//end for
txtareaWord.setText(sb.toString());
You also seem to have attached multiple ActionListeners to your button, as each time I clicked it, it counted for two guesses...

Categories