Creating arrays using Joptionpane input - java

Create a program that will count the number of times an input name appeared in a list from an input array of 10 names. Using JOptionPne.
(After input of 10 names and for a name to count from the list, and assuming Maria is the name entered to count)
Expected sample output
My code so far:
import javax.swing.JOptionPane;
public class Chapter4Act_Array {
public static void main(String[] args) {
String ArrayOf_Names[] = new String[10];
for (int i = 0; i < ArrayOf_Names.length; i++) {
ArrayOf_Names[i] = JOptionPane.showInputDialog("Enter name" + (i + 1) + ":");
}
System.out.println("Your friends are: ");
for (int i = 0; i < ArrayOf_Names.length; i++) {
System.out.println(ArrayOf_Names[i]);
}
}
}

Little short on information but I think i know what you are trying to accomplish. In the demo code below, a JOptionPane is used to acquire the names from a User. Do do this a custom panel is created and passed to the JOptionPane#showOptionPane() method:
Yes...that's a JOptionPane. This is most likely more than you require but then again there isn't enough info to clarify either way. In any case, here is the code and be sure to read all the comments in code (comments always make the code look more than it really is):
/* Create a JPanel object to display within the JOptionPane
and fill it with the components we want. */
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
JLabel msg = new JLabel("<html><center><font size='4'>Please enter <font "
+ "color=blue>User</font> names into the list below:"
+ "</font></html>");
msg.setVerticalAlignment(JLabel.TOP);
msg.setPreferredSize(new Dimension(135, 60));
jp.add(msg, BorderLayout.NORTH);
// Add a JTextfield and JLabel
JPanel textPanel = new JPanel();
textPanel.setLayout(new BorderLayout());
JLabel name = new JLabel("Enter Name:");
JTextField textField = new JTextField(0);
textPanel.add(name, BorderLayout.NORTH);
textPanel.add(textField, BorderLayout.SOUTH);
jp.add(textPanel, BorderLayout.CENTER);
// Add a JList (in a JScrollPane) and Add/Remove buttons
JPanel listPanel = new JPanel();
DefaultListModel<String> listModel = new DefaultListModel<>();
JList<String> list = new JList<>(listModel);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(120, 150));
scrollPane.setViewportView(list);
listPanel.add(scrollPane, BorderLayout.WEST);
// Add/Remove Buttons
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BorderLayout());
JButton addButton = new JButton("Add");
addButton.addActionListener(new ActionListener() {
int listItemCount = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (textField.getText() != null) {
listModel.addElement(textField.getText());
if (listModel.getSize() == 10) {
addButton.setEnabled(false);
return;
}
}
textField.requestFocus();
textField.setSelectionStart(0);
textField.setSelectionEnd(textField.getText().length());
}
});
buttonPanel.add(addButton, BorderLayout.NORTH);
JButton removeButton = new JButton("Remove");
removeButton.addActionListener(new ActionListener() {
int listItemCount = 0;
#Override
public void actionPerformed(ActionEvent e) {
int selectedIndex = list.getSelectedIndex();
if (list.getSelectedIndex() >= 0) {
listModel.remove(selectedIndex);
}
if (listModel.getSize() < 10) {
addButton.setEnabled(true);
}
if (selectedIndex > 0) {
list.setSelectedIndex(selectedIndex - 1);
}
}
});
buttonPanel.add(removeButton, BorderLayout.CENTER);
listPanel.add(buttonPanel, BorderLayout.EAST);
jp.add(listPanel, BorderLayout.SOUTH);
// Supply what we want the dialog button captions are to be.
Object[] buttons = {"Process", "Cancel"};
// Display the JOptionPane using the Option Dialog.
int res = JOptionPane.showOptionDialog(this, jp, "User Names", 0,
JOptionPane.PLAIN_MESSAGE, null, buttons, 1);
// The following code will no run until the JOptionPane is closed.
/* If the list does not contain 10 names then inform
the User and make him/her do it over again. */
if (listModel.getSize() < 10) {
System.out.println("Not Enough Names! Do it again!");
return;
}
/* Fill a String[] Array with the names in List but,
at the same time keep track of how many times a
specific name was in that list. We use a Map/HashMap
to hold the occurrences information. You really don't
need a String[] Array since the Map can take care of
everything but I thought you might want them separate. */
String[] names = new String[listModel.size()]; // Declare a String[] Array
Map<String, Integer> nameMap = new HashMap<>(); // Declare a Map
// Iterate through the List that was in the dialog using the List Model
for (int i = 0; i < listModel.size(); i++) {
// Get name from list at current index
names[i] = listModel.get(i);
// Is the name already in the Map?
if (nameMap.containsKey(names[i])) {
// Yes, it is ...
// Get the current number of times Count Value for that specific name
int value = nameMap.get(names[i]);
value++; // Increment that value by 1
nameMap.put(names[i], value); // Update the count value for that specific name.
}
else {
/* No, it isn't so add the Name as key and
a count value of 1 for the value. */
nameMap.put(names[i], 1);
}
}
/* Processing the name information is now complete,
we just need to diplay the acquired data now held
within the names[] Array and the nameMap Map. */
/* Display the oringinal list which is now
contained within the names[] String Array. */
for (int i = 0; i < names.length; i++) {
System.out.printf("%-12s%-15s%n", "Name #" + (i+1), names[i]);
}
System.out.println();
/* Now, display the occurrences for all those
names held within nameMap. */
String n;
int o;
for (Map.Entry<String,Integer> entry : nameMap.entrySet()) {
n = entry.getKey();
o = entry.getValue();
System.out.println(n + " appeared " + o
+ (o > 1 ? " times" : " time") + " in the List.");
}
System.out.println();
System.out.println("Process Completed.");
// DONE
If you run this code, your Console Window should display something like this:
Name #1 Bill
Name #2 Jane
Name #3 Marie
Name #4 Tracey
Name #5 Fred
Name #6 Bill
Name #7 Marie
Name #8 Doug
Name #9 Marie
Name #10 Tracey
Marie appeared 3 times in the List.
Bill appeared 2 times in the List.
Fred appeared 1 time in the List.
Jane appeared 1 time in the List.
Doug appeared 1 time in the List.
Tracey appeared 2 times in the List.
Process Completed.
EDIT: Based on comments!
Now that you have provided more info, here is one way it can be achieved. Again, read the comments in code:
public class Chapter4Act_Array {
public static void main(String[] args) {
String arrayOfNames[] = new String[10];
for (int i = 0; i < arrayOfNames.length; i++) {
// Letter case will be ignored during the occurrences processing.
arrayOfNames[i] = JOptionPane.showInputDialog(null, "Please Enter name #" + (i + 1) + ":", "Name",JOptionPane.QUESTION_MESSAGE);
}
System.out.println("Your friends are: ");
for (int i = 0; i < arrayOfNames.length; i++) {
System.out.println(arrayOfNames[i]);
}
System.out.println();
/* List to keep track of the names we've already processed.
This will help to prevent printing the same Name more
than once. */
java.util.List<String> namesAlreadyProcessed = new java.util.ArrayList<>();
int counter;
for (int i = 0; i < arrayOfNames.length; i++) {
counter = 1;
for (int j = 0; j < arrayOfNames.length; j++) {
if (j == i) { continue; } // If we fall onto the same index then skip past it.
if (arrayOfNames[i].equalsIgnoreCase(arrayOfNames[j])) {
counter++;
}
}
/* If counter is greater than 1 then there has been
a name we've encountered more than once. Let's
display the number of times it was encountered
and add that name to namesAlreadyProcessed List. */
if (counter > 1) {
// Have we already processed this name?
boolean processed = false;
for (String name : namesAlreadyProcessed) {
if (name.equalsIgnoreCase(arrayOfNames[i])) {
// Yes, so skip printing the result again for this name.
processed = true;
break;
}
}
/* If No, then let's print the name and count result to
Console Window and add the name to our List. */
if (!processed) {
System.out.println(arrayOfNames[i] + " is in the List " + counter + " times.");
namesAlreadyProcessed.add(arrayOfNames[i]);
}
}
}
}
}

Related

How to set properties of a JButton ArrayList?

I have a JButton ArrayList. The code below does not work. How can I access a specific button from the array list and set the size, location and other properties and also add it to the applet?
ArrayList<String> cdTitles = new ArrayList<String>();
ArrayList<JButton> btnCDS = new ArrayList<JButton>();
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("Initialize")) {
cdTitles.add("Original Order");
cdTitles.add("Metric - Fantasies");
cdTitles.add("Beatles - Abby Road");
cdTitles.add("Pearl Jam - Ten");
cdTitles.add("Doors - Alive");
cdTitles.add("The Rolling Stones - Gimme Shelter");
for(int i = 0; i < cdTitles.size(); i++) {
String buttonName = "btn" + i;
System.out.println(buttonName);
btnCDS.add(new JButton(buttonName));
break;
}
btnCDS.get(0).setText(cdTitles.get(0));
btnCDS.get(0).setLocation(100, 145);
btnCDS.get(0).setSize(520, 25);
add(btnCDS.get(0));
}
}
provided that this is executing in a Applet sub-class,
this works for me:
#Override
public void init()
{
// all your code between:
// cdTitles.add("Original Order");
// AND
// add(btnCDS.get(0));
// Watch out for dead code in the for loop.
}

Generate JFrames in a loop, naming issue

Beginner Java programmer here. I'm trying to create a card game to learn more about Java. I have an array of names I pulled out a database. For each String in the array I want to create a JPanel and inside JLabels where I will set the name, power, health, etc.
The problem is when I create these in a loop they all have the same name and overwrite each other. Since I read Java doesn't have dynamic Variable names, how do I solve this?
public void loadDatabaseCardElements(ArrayList cards) {
ArrayList<String> buildCards = cards;
int i;
for(i = 0; i != buildCards.size();) {
String var = buildCards.get(0);
//create the Panel etc
JPanel mainHolder = new JPanel();
mainHolder.setLayout(new BoxLayout(mainHolder, BoxLayout.PAGE_AXIS));
JLabel name = new JLabel("Name: " + var);
JLabel powerLabel = new JLabel("Power: ");
JLabel healthLabel = new JLabel("Health: ");
JLabel armorLabel = new JLabel("Armor: ");
JLabel type1Label = new JLabel("Type1");
JLabel type2Label = new JLabel("Type2: ");
JLabel ability1Label = new JLabel("Ability1: ");
JLabel ability2Label = new JLabel("Ability2: ");
JLabel ability3Label = new JLabel("Ability3: ");
JButton card1 = new JButton("Add to deck");
mainHolder.add(name);
mainHolder.add(powerLabel);
mainHolder.add(healthLabel);
mainHolder.add(armorLabel);
mainHolder.add(type1Label);
mainHolder.add(type2Label);
mainHolder.add(ability1Label);
mainHolder.add(ability2Label);
mainHolder.add(ability3Label);
mainHolder.add(card1);
mainHolder.setBorder(BorderFactory.createLineBorder(Color.black));
mainHolder.setPreferredSize( new Dimension( 130, 200 ) );
frame1.add(mainHolder, BorderLayout.WEST);
SwingUtilities.updateComponentTreeUI(frame1);
card1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
preDeck.add(var); //add to another array when clicked
}
});
if (buildCards.size() != 0) {
buildCards.remove(0);
} else {
}
}
}
The reason for overwriting all the panels with same name is due to this part of your code:
int i;
for(i = 0; i != buildCards.size();) {
String var = buildCards.get(0);
You are assigning the first element of your list to each JLabel. This could help you achieve what you need:
for(int i = 0; i < buildCards.size(); i++){
String var = buildCards.get(i);
// Followed by your code
}
set a growable layout for a standard jpanel in the frame and then add a new jpanel to the standard jpanel every time. this should solve the naming problem. if u need access to each panel, you can store them in an array

NullPointerException when attempting to insert items into array from JDialog box

As it states, when I attempt to insert an item into an object array via my JDialog popup, I get a NullPointerException. I reworked an existing app to create the JDialog, which opens from another application class currently named Project6(). The JDialog class, called ProcessRec(), worked fine when it ran as a standalone GUI(before I made it a JDialog).
My stacktrace is rather unhelpful in this case, as it only points to the method that is attempting to insert data into the array(which, like I said, worked fine before) and the GUI buttons that correspond to them.
The constructor for ProcessRec() accepts a ToolWarehouse() object, which matches the class that creates my object array(which is an array of objects from another class I have defined, ToolItem() ).
public ProcessRec(ToolWarehouse tools)
When it ran on it's own, ProcessRec() constructor params were empty(default).
When ProcessRec() ran as a standalone GUI for inputting data into the array, I would create an object using the default constructor like so:
ToolWareHouse tools = new ToolWarehouse();
and I would then use it's method insert() to enter data into the array.
Now that it is a JDialog, though, I was instructed to change to:
ToolWarehouse tools;
However this causes the NullPointerException because, and i'm guessing, the compiler is pointing to an object that doesn't exist. When I create a new object in ProcessRec(), as I did when it was a standalone, I no longer get this exception. However, when I attempt to store data into the array using insert(), it does not work and the data cannot be found(although I receive a prompt saying the insert was successful).
I know very little about instances of classes, but i'm assuming that the reason my data isn't showing is because it is using a whole different instance of the ToolWarehouse() class? Is the format:
public ProcessRec(ToolWarehouse tools)
accepting the same instance of the class used before? I may be way off base here, so I was hoping someone could help me understand what may be happening and why.
If more info is needed I apologize, i'll add whatever is necessary. The code is somewhat lengthy and I didn't want to take up space. Thanks a ton.
EDIT: Here is the ProcessRec() class, which creates the JDialog box, along with some of the methods corresponding to it's use.
public class ProcessRec extends JDialog
{
//global declarations
private JButton insertBtn;
private JButton deleteBtn;
private JButton displayBtn;
private JButton hideBtn;
private JButton clearBtn;
private JTextField toolFld;
private JTextField idFld;
private JTextField priceFld;
private JTextField qualityFld;
private JTextField numInStockFld;
private JTextField messageFld;
private JLabel messageLbl;
private Font f1 = new Font("serif", Font.BOLD, 24);
private Font f2 = new Font("serif", Font.PLAIN, 18);
private Container c = getContentPane();
private String input = "";
private String toolInput = "";
private int responseCode = 0;
private int idInput = 0;
private int qualityInput = 0;
private int numInStockInput = 0;
private double priceInput = 0.0;
private ToolWarehouse tools = new ToolWarehouse();
//constructor for GUI elements and event listeners
public ProcessRec(ToolWarehouse tools)
{
setTitle("Project1");
setSize(520,450);
c.setLayout(new FlowLayout());
JLabel title = new JLabel("Tiny Tim's Tool Warehouse, Inc.");
title.setFont(f1);
c.add(title);
JTextField toolLbl = new JTextField("Enter tool name:", 15);
toolLbl.setEditable(false);
c.add(toolLbl);
toolFld = new JTextField(25);
c.add(toolFld);
JTextField idLbl = new JTextField("Enter ID:", 15);
idLbl.setEditable(false);
c.add(idLbl);
idFld = new JTextField(25);
c.add(idFld);
JTextField priceLbl = new JTextField("Base Price:", 15);
priceLbl.setEditable(false);
c.add(priceLbl);
priceFld = new JTextField(25);
c.add(priceFld);
JTextField qualityLbl = new JTextField("Enter Quality:", 15);
qualityLbl.setEditable(false);
c.add(qualityLbl);
qualityFld = new JTextField(25);
c.add(qualityFld);
JTextField numInStockLbl = new JTextField("Enter Number in Stock:", 15);
numInStockLbl.setEditable(false);
c.add(numInStockLbl);
numInStockFld = new JTextField(25);
c.add(numInStockFld);
insertBtn = new JButton("Insert");
c.add(insertBtn);
deleteBtn = new JButton("Delete");
c.add(deleteBtn);
displayBtn = new JButton("Display");
c.add(displayBtn);
hideBtn = new JButton("Hide");
c.add(hideBtn);
clearBtn = new JButton("Clear");
c.add(clearBtn);
JLabel messageLbl = new JLabel("Messages:");
messageLbl.setFont(f2);
c.add(messageLbl);
messageFld = new JTextField(30);
c.add(messageFld);
//button listeners
insertBtn.addActionListener(new EventListener());
deleteBtn.addActionListener(new EventListener());
displayBtn.addActionListener(new EventListener());
hideBtn.addActionListener(new EventListener());
clearBtn.addActionListener(new EventListener());
} //end constructor
public String getToolRecords(int index)
{
return tools.getRecord(index);
}
public int getNumberOfItems()
{
return tools.getNumberOfItems();
}
//Action Listener
private class EventListener implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
if (ev.getSource() == insertBtn)
{
toolInput = toolFld.getText();
input = idFld.getText();
idInput = Integer.parseInt(input);
input = priceFld.getText();
priceInput = Double.parseDouble(input);
input = qualityFld.getText();
qualityInput = Integer.parseInt(input);
input = numInStockFld.getText();
numInStockInput = Integer.parseInt(input);
responseCode = tools.insert(qualityInput, toolInput, idInput, numInStockInput,
priceInput);
if (responseCode == 1)
{
messageFld.setText(idInput + " - Successful insertion");
}
else if (responseCode == 0)
{
messageFld.setText(idInput + " - Array is full");
}
else if (responseCode == -1)
{
messageFld.setText(idInput + " - Duplicate/Invalid ID");
}
if (tools.getNumberOfItems() < 10)
{
JOptionPane.showMessageDialog(null, "Tool Name: " + toolInput
+ "\nTool ID: " + idInput + "\nTool Base Price: " + "$" + priceInput
+ "\nQuality: " + qualityInput + "\nNumber In Stock: "
+ numInStockInput, "Insert Review", JOptionPane.INFORMATION_MESSAGE);
}
else if (tools.getNumberOfItems() == 10)
{
JOptionPane.showMessageDialog(null, "The array is full, please delete an entry",
"Insert Review", JOptionPane.INFORMATION_MESSAGE);
}
}//end insert button
else if (ev.getSource() == deleteBtn)
{
input = idFld.getText();
idInput = Integer.parseInt(input);
responseCode = tools.delete(idInput);
if (responseCode == 1)
{
messageFld.setText(idInput + " - Successful deletion");
}
else if (responseCode == -1)
{
messageFld.setText(idInput + " - ID not found");
}
}//end delete button
else if (ev.getSource() == displayBtn)
{
tools.display();
}
else if (ev.getSource() == hideBtn)
{
//setState(JFrame.ICONIFIED);
}
else if (ev.getSource() == clearBtn)
{
qualityFld.setText(null);
toolFld.setText(null);
idFld.setText(null);
numInStockFld.setText(null);
priceFld.setText(null);
messageFld.setText(null);
repaint();
}//end clear button
}//end actionPerformed
}//end ActionListener
}//end Project1
ToolWarehouse class that creates the array:
public class ToolWarehouse
{
//Global declarations
private int numberOfItems = 0;
private int index = 0;
private int returnCode = 0;
protected ToolItem[] toolArray = new ToolItem[10];
public ToolWarehouse()
{
numberOfItems = 0;
//creating the array of ToolItems
for (int i = 0; i < toolArray.length; i++)
{
toolArray[i] = new ToolItem();
System.out.println(toolArray[i]);
}
}//end constructor
public int searchArray(int id)
{
for (index = 0; index < toolArray.length; index++)
{
if (toolArray[index].getToolID() == id)
{
System.out.println("ID found at location " + index);
return index;
}
}
return -1;
}//end searchArray
public int insert(int quality, String name, int id, int numInStock, double price)
{
returnCode = searchArray(id);
if (numberOfItems == 10)
{
System.out.println("Array is full");
return 0;
}
else if (returnCode == -1)
{
boolean oK = toolArray[numberOfItems].assign(quality, name, id, numInStock,
price);
if (oK == true)
{
System.out.println("Successful insertion");
numberOfItems++;
return 1;
}
}
return -1;
}//end insert
public int delete(int ID)
{
returnCode = searchArray(ID);
if (returnCode != -1)
{
toolArray[returnCode] = new ToolItem();
for (index = returnCode; index < numberOfItems; index++)
{
toolArray[index] = toolArray[index + 1];
}
numberOfItems--;
System.out.println("Successful deletion");
return 1;
}
else
System.out.println("ID not found");
return -1;
}//end delete
public void display()
{
for (index = 0; index < numberOfItems; index++)
{
toolArray[index].calcAdjustedPrice();
toolArray[index].display();
}
}//end display
public String getRecord(int index)
{
return "Tool Name: " + toolArray[index].getName()
+ "| Tool ID: " + toolArray[index].getToolID()
+ "| Tool Quality: " + toolArray[index].getQuality()
+ "| Number in Stock: " + toolArray[index].getNumberInStock()
+ "| Tool Price: " + toolArray[index].getPrice();
}//end getRecord
public int getNumberOfItems()
{
return numberOfItems;
}
}//end ToolWarehouse
And the current portion i'm working on now, which calls insert() from the ToolWarehouse() class, but does not properly insert into the array i'm working on when creating an object of the ToolWarehouse() class using default constructor(even though my println debugging statements indicate it does):
public void readBSAFile() throws IOException,
FileNotFoundException
{
FileInputStream fstream2 = new FileInputStream(filename);
DataInputStream dstream2 = new DataInputStream(fstream2);
while (dstream2.available() > 0)
{
try
{
toolName = dstream2.readUTF();
id = dstream2.readInt();
quality = dstream2.readInt();
numInStock = dstream2.readInt();
price = dstream2.readDouble();
dstream2.close();
System.out.println(toolName);
System.out.println(id);
System.out.println(quality);
System.out.println(numInStock);
System.out.println(price);
//tools.insert(quality, toolName, id, numInStock, price);
}
catch (EOFException e)
{
System.out.println("End of file reached");
}
}
tools.insert(quality, toolName, id, numInStock, price);
}//end readBSAFile
Indeed, you have to make sure the object is initialized before attempting to use it. You put
ToolWarehouse tools;
as a class variable, and in the dialog method you could say
tools = new ToolWareHouse();
to create the object and start using it. But maybe a better way is to just initialize it as a class variable straight way. e.g write
ToolWarehouse tools = new ToolWareHouse();
at the top of the class. (So it's a class variable, and known throughout the whole class)
You didn't show us too much code, so it's hard to tell what the exact problem is. But as you said, you don't initialize your object, so you're bound to get a nullPointerException when trying to pass it on to another method & use it.

Could someone tell me why my actionListener for-loop is not working?

I have a program that takes an input file, pulls a color word + hexadecimal value from it (for exaple Red 0xFF0000). I had my code working perfectly except I tried to replace my 2 arrayLists with a HashMap... That is where things took a wrong turn. I have my code back to what I believe it was before except now it is NOT changing colors when the radio buttons are pushed. Anyone want to take a peek?
public HashMapTests() {
JPanel p1 = new JPanel();
this.getContentPane().setLayout(new GridLayout(5,4));
ButtonGroup group = new ButtonGroup();
for (int i = 0; i < colorCollection.size(); i++) {
jrbColor[i] = new JRadioButton(colorCollection.get(i));
jrbColor[i].setText(colorCollection.get(i));
group.add(jrbColor[i]);
p1.add(jrbColor[i]);
}
for(int i = 0; i < colorCollection.size(); i++){
jrbColor[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
for (int j = 0; j < colorCollection.size(); j++){
String hexColor = hexCollection.get(j);
if(hexCollection.get(j).equals(((JRadioButton)e.getSource()).getText())){
getContentPane().setBackground(Color.decode(hexColor));
repaint();
}
}
}
});
}
add(p1);
}
First investigation:
while (colorCollection.size() < 10)
shall be replaced with
if (colorCollection.size() < 10)
Second observation:
jrbColor[i] = new JRadioButton(colorCollection.get(i));
jrbColor[i].setText(colorCollection.get(i));
The second line is useless, see constructor's javadoc.
Third:
The second loop where you attach the listener is useless, you can put this code to the first loop where you create a button.
Finally:
if (hexCollection.get(j).equals(((JRadioButton) e.getSource()).getText())) {
You compare here content of hexCollection with radio button text, but the button has label from colorCollection. I cannot look to your file but I think that this will be the problem.
Map Solution:
Initialization
String name = fileInput.next();
String hexValue = fileInput.next();
colors.put(name, hexValue);
Buttons
int i = 0;
for (String s : colors.keySet()) {
jrbColor[i] = new JRadioButton(s);
group.add(jrbColor[i]);
p1.add(jrbColor[i]);
jrbColor[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String hexColor = colors.get(((JRadioButton) e.getSource()).getText());
getContentPane().setBackground(Color.decode(hexColor));
}
});
}

Java exception handling with multiple classes

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.

Categories