Implementing java graphics into bingo card game - java

I started with a class that has all the methods and constructors which are doing all the work for the bingo game. Then had a "tester class" which would print out and update the bingo card through the use of System.out.print. Now I need to add some graphic for the bingo game. I am supposed to use my first to classes to support a new class to draw the card every time there is an update.
I was able to do the first iteration of the bingo card graphics with a separate code from my original 2:
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.Color;
import java.awt.Font;
import java.awt.geom.Ellipse2D;
public class BingoComponent extends JComponent {
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Rectangle box = new Rectangle(28,105,80,80);
for(int j = 0;j<5;j++){
g2.draw(box);
for(int i = 0;i<4;i++){
box.translate(80,0);
g2.draw(box);
}
box.translate(-320,80);
}
g2.setPaint(Color.BLUE);
g2.setFont(new Font("Arial", Font.BOLD,44));
g2.drawString("B",50,100);
g2.drawString("I",140,100);
g2.drawString("N",215,100);
g2.drawString("G",290,100);
g2.drawString("O",370,100);
g2.setPaint(Color.RED);
Ellipse2D.Double ellipse = new Ellipse2D.Double(198,275,60,60);
g2.draw(ellipse);
g2.fill(ellipse);
Bingo_Card test_card = new Bingo_Card();
g2.setPaint(Color.BLACK);
g2.setFont(new Font("Times", Font.PLAIN,24));
int x_location = 60;
int y_location = 150;
int number_value;
for(int j = 0;j<5;j++){
number_value = test_card.get_number(j);
g2.drawString(""+number_value,x_location,y_location);
x_location += 80;
}
x_location = 60;
y_location += 80;
for(int j = 5;j<10;j++){
number_value = test_card.get_number(j);
g2.drawString(""+number_value,x_location,y_location);
x_location += 80;
}
x_location = 60;
y_location += 80;
for(int j = 10;j<15;j++){
number_value = test_card.get_number(j);
if(number_value!=0){
g2.drawString(""+number_value,x_location,y_location);
}
x_location += 80;
}
x_location = 60;
y_location += 80;
for(int j = 15;j<20;j++){
number_value = test_card.get_number(j);
g2.drawString(""+number_value,x_location,y_location);
x_location += 80;
}
x_location = 60;
y_location += 80;
for(int j = 20;j<25;j++){
number_value = test_card.get_number(j);
g2.drawString(""+number_value,x_location,y_location);
x_location += 80;
}
}
}
which I used with this code:
public class makecard {
public static void main(String args[]){
JFrame frame = new JFrame();
frame.setSize(800,800);
frame.setTitle("BINGO Card");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BingoComponent component = new BingoComponent();
frame.add(component);
frame.setVisible(true);
}
}
but what i dont understand is how to implement this into my original two codes.
Which are:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import java.awt.Color;
import java.awt.Font;
import java.awt.geom.Ellipse2D;
public class Bingo_Card {
private ArrayList<Integer> bingo_card;
public boolean bingo = false;
public Bingo_Card(){
/*ArrayList<Integer>*/ bingo_card = new ArrayList<>();
ArrayList<Integer> columnBlist = new ArrayList<>();
for(int i = 1;i<=15;i++){
columnBlist.add(i);
}
Collections.shuffle(columnBlist);
ArrayList<Integer> columnB = new ArrayList<>();
for(int j = 0;j<5;j++){
columnB.add(columnBlist.get(j));
}
ArrayList<Integer> columnIlist = new ArrayList<>();
for(int i = 16;i<=30;i++){
columnIlist.add(i);
}
Collections.shuffle(columnIlist);
ArrayList<Integer> columnI = new ArrayList<>();
for(int j = 0;j<5;j++){
columnI.add(columnIlist.get(j));
}
List<Integer> columnNlist = new ArrayList<>();
for(int i = 31;i<=45;i++){
columnNlist.add(i);
}
Collections.shuffle(columnNlist);
ArrayList<Integer> columnN = new ArrayList<>();
for(int j = 0;j<4;j++){
columnN.add(columnNlist.get(j));
}
columnN.add(2,0);
List<Integer> columnGlist = new ArrayList<>();
for(int i = 46;i<=60;i++){
columnGlist.add(i);
}
Collections.shuffle(columnGlist);
ArrayList<Integer> columnG = new ArrayList<>();
for(int j = 0;j<5;j++){
columnG.add(columnGlist.get(j));
}
List<Integer> columnOlist = new ArrayList<>();
for(int i = 61;i<=75;i++){
columnOlist.add(i);
}
Collections.shuffle(columnOlist);
ArrayList<Integer> columnO = new ArrayList<>();
for(int j = 0;j<5;j++){
columnO.add(columnOlist.get(j));
}
for(int x=0;x<5;x++){
bingo_card.add(columnB.get(x));
bingo_card.add(columnI.get(x));
bingo_card.add(columnN.get(x));
bingo_card.add(columnG.get(x));
bingo_card.add(columnO.get(x));
}
}
public int get_number(int index){
int number = bingo_card.get(index);
return(number);
}
public void print_card(){
System.out.println(" B I N G O ");
System.out.println("----------------");
for(int a = 0;a<5;a++){
if(bingo_card.get(a)<10){
System.out.print("| "+bingo_card.get(a));
}
else{
System.out.print("| "+bingo_card.get(a));
}
}
System.out.println();
System.out.println("----------------");
for(int b = 5;b<10;b++){
if(bingo_card.get(b)<10){
System.out.print("| "+bingo_card.get(b));
}
else{
System.out.print("| "+bingo_card.get(b));
}
}
System.out.println();
System.out.println("----------------");
for(int c = 10;c<15;c++){
if(bingo_card.get(c)<10){
System.out.print("| "+bingo_card.get(c));
}
else{
System.out.print("| "+bingo_card.get(c));
}
}
System.out.println();
System.out.println("----------------");
for(int d = 15;d<20;d++){
if(bingo_card.get(d)<10){
System.out.print("| "+bingo_card.get(d));
}
else{
System.out.print("| "+bingo_card.get(d));
}
}
System.out.println();
System.out.println("----------------");
for(int e = 20;e<25;e++){
if(bingo_card.get(e)<10){
System.out.print("| "+bingo_card.get(e));
}
else{
System.out.print("| "+bingo_card.get(e));
}
}
System.out.println();
System.out.println("----------------");
}
public void check_match(int call_number){
for(int i = 0; i<(bingo_card.size());i++){
if(call_number == bingo_card.get(i)){
bingo_card.set(i,0);
}
}
}
public boolean check_bingo(){
if(bingo_card.get(0)==0&bingo_card.get(1)==0&bingo_card.get(2)==0&bingo_card.get(3)==0&bingo_card.get(4)==0){
bingo = true;
}
else if(bingo_card.get(5)==0&bingo_card.get(6)==0&bingo_card.get(7)==0&bingo_card.get(8)==0&bingo_card.get(9)==0){
bingo = true;
}
else if(bingo_card.get(10)==0&bingo_card.get(11)==0&bingo_card.get(12)==0&bingo_card.get(13)==0&bingo_card.get(14)==0){
bingo = true;
}
else if(bingo_card.get(15)==0&bingo_card.get(16)==0&bingo_card.get(17)==0&bingo_card.get(18)==0&bingo_card.get(19)==0){
bingo = true;
}
else if(bingo_card.get(20)==0&bingo_card.get(21)==0&bingo_card.get(22)==0&bingo_card.get(23)==0&bingo_card.get(24)==0){
bingo = true;
}
else if(bingo_card.get(0)==0&bingo_card.get(5)==0&bingo_card.get(10)==0&bingo_card.get(15)==0&bingo_card.get(20)==0){
bingo = true;
}
else if(bingo_card.get(1)==0&bingo_card.get(6)==0&bingo_card.get(11)==0&bingo_card.get(16)==0&bingo_card.get(21)==0){
bingo = true;
}
else if(bingo_card.get(2)==0&bingo_card.get(7)==0&bingo_card.get(12)==0&bingo_card.get(17)==0&bingo_card.get(22)==0){
bingo = true;
}
else if(bingo_card.get(3)==0&bingo_card.get(8)==0&bingo_card.get(13)==0&bingo_card.get(18)==0&bingo_card.get(23)==0){
bingo = true;
}
else if(bingo_card.get(4)==0&bingo_card.get(9)==0&bingo_card.get(14)==0&bingo_card.get(19)==0&bingo_card.get(24)==0){
bingo = true;
}
else if(bingo_card.get(0)==0&bingo_card.get(6)==0&bingo_card.get(12)==0&bingo_card.get(18)==0&bingo_card.get(24)==0){
bingo = true;
}
else if(bingo_card.get(4)==0&bingo_card.get(8)==0&bingo_card.get(12)==0&bingo_card.get(16)==0&bingo_card.get(20)==0){
bingo = true;
}
else{
bingo = false;
}
return(bingo);
}
and the tester:
public class BINGOFINAL {
public static void main(String args[]){
Bingo_Card test_card = new Bingo_Card();
test_card.print_card();
while(test_card.check_bingo() == false){
System.out.println("Please input the called out number: ");
Scanner input = new Scanner(System.in);
int call_out = input.nextInt();
test_card.check_match(call_out);
test_card.check_bingo();
test_card.print_card();
}
System.out.println("BINGO!");
}
}
i need to implement the BingoComponent into the original two and have the card update each time.

The basic idea remains the same.
You need some kind of model which is maintaining the state of the bingo card, you need some kind of view that displays this model and some kind of control/manager which managers the updates to the model...
In you BingoComponent's paintComponent method, you do this ... Bingo_Card test_card = new Bingo_Card();...
I would say this is a bad idea, as you are restting the state of the card/model each time the component is painted, this isn't what you want. Instead, you want to maintain a single reference to the card, which you then use the paintComponent to render...
Instead, I'd be tempted to do something like this instead...
public class BingoComponent extends JComponent {
private Bingo_Card test_card;
public BingoComponent(Bingo_Card card) {
test_card = card;
}
/*...*/
}
This means that that instance doesn't change, but each time we change it's state, we can re-render it.
The next part will come down to how you want to implement it. If it was me, I would add ChangeListener support to the Bingo_Card, so that the UI could monitor for changes to the card and update itself accordingly, but this might be a little out of your reach just now.
You are going to need some way for the user enter a value into your UI. For this you could use a JTextField. You can either attach an ActionListener directly to the field, so that each time the user presses Enter you will receive notification about it and/or add a JButton, which the user could click (with an attached ActionListener so you know when the user clicks the button).
At this point, you need to take the value and update the model, just like you have in your BINGOFINAL class, but instead, you would to update the UI...
For example...
public void actionPerformed(ActionEvent evt) {
try {
// inputField is a JTextField
// testCard is an instance of Bingo_Card which you
// need to create. It is also the same instance
// you passed to your BingoComponent
int callOut = Integer.parseInt(inputField.getText());
test_card.check_match(call_out);
test_card.check_bingo();
test_card.print_card();
// bingoComponent is an instance of BingoComponent
// which is begin displayed on the screen...
bingoComponent.repaint();
} catch (NumberFormatException exp) {
JOptionPane.showMessageDialog(this, inputField.getText() +
" is not a valid number", "Error", JOptionPane.ERROR_MESSAGE);
}
}
Now, personally, I'd prefer it if the model provided some kind of notification about changes to it's internal state, but lets try and keep it simpler for the time begin...
Check out Creating a GUI with Swing for more details

Related

Processing - Array index out of bounds error

I'm trying to use an array of objects to have barrels fall from the top of the screen to the bottom. (Like that old donkey kong game.) However, I can't seem to find a way to create more instances of the object than whatever the initial length of the array was. Anyone know a way to do this?
Here's the code:
Man Man;
Man background;
Man ladders;
PFont font1;
int time;
boolean run;
boolean newBarrel;
int barrelTotal;
Barrel[] barrel = new Barrel[100];
void setup() {
newBarrel = false;
run = true;
barrelTotal = 1;
time = millis();
size(800, 800);
Man = new Man();
background = new Man();
ladders = new Man();
for (int i = 0; i < barrel.length; i++) {
barrel[i] = new Barrel();
}
}
void draw() {
if (run == true) {
for (int i = 0; i < barrel.length; i++) {
if ((Man.bottom-10 >= barrel[i].top)&&(Man.bottom-10 <= barrel[i].bottom)&&(Man.Ladder == barrel[i].randomLadder)) {
print("GAME OVER!");
run = false;
}
if ((Man.top >= barrel[i].top)&&(Man.top <= barrel[i].bottom)&&(Man.Ladder == barrel[i].randomLadder)) {
print("GAME OVER!");
run = false;
}
}
}
if (run == true) {
background.createBackground();
Man.ladders();
Man.movement();
Man.createMan();
//spawns a barrel every second
if (millis()> time + 10) {
newBarrel = false;
print(" " + barrelTotal + " ");
time = time + 10;
barrelTotal = barrelTotal+1;
newBarrel = true;
}
for (int i = 0; i < barrelTotal; i++) {
if (newBarrel == true) {
}
barrel[i].gravity();
barrel[i].createBarrel();
}
//if(barrelTotal == 100){
//for (int i = 0; i < 50; i++){
// barrel[i] = "???";
//}
//}
}
}
Use an ArrayList instead of a native array. ArrayList will expand capacity as needed, whereas an array is fixed size and cannot be changed (you'd need to create a new larger array each time, which under the covers is what an ArrayList handles for you).
You can use ArrayList for this. You will change
// from
Barrel[] barrel = new Barrel[100]; // i suggest naming it to barrels instead of barrel
// to
ArrayList<Barrel> barrel = new ArrayList<>();
// or better
List<Barrel> barrel = new ArrayList<>();
// from
for (int i = 0; i < barrel.length; i++) {
barrel[i] = new Barrel();
}
// to
for (int i = 0; i < barrel.length; i++) {
barrel.add(new Barrel());
}
// from
barrel[i].<some-method()/attribute>
// to
barrel.get(i).<some-method()/attribute>
// etc
I highly recommend this for getting started with lists
https://docs.oracle.com/javase/tutorial/collections/interfaces/list.html

Memory game does not call compare function correctly

I have coded a simple memory game. Card values are added to two arrays and after that, a compare function is called. But there is a problem with the logic of the compare function.
The specific problem seems related to the fact that the compare function is called on the third button click. So on first click it adds first value to first array , on second click second value to second array. But I must click for yet a third time to call the compare function to compare the match of two arrays.
The main problem is that after all cards are inverted (10 matches in 5x4 memory game), it does not show the result.
I have uploaded full code here : http://uloz.to/xcsJkYUK/memory-game-rar .
public class PEXESO5x4 extends JFrame implements ActionListener {
private JButton[] aHracieTlactika = new JButton[20];
private ArrayList<Integer> aHodnoty = new ArrayList<Integer>();
private int aPocitadlo = 1;
private int[] aTlacitkoIden = new int[2];
private int[] aHodnotaTlac = new int[2];
private JButton aTlacitkoExit;
private JButton aTlacitkoReplay;
private JButton[] aHracieTlacitko = new JButton[20];
private int aPocetTahov = 0;
public void vkladanieHodnot() {
for (int i = 0; i < 2; i++) {
for (int j = 1; j < (this.aHracieTlactika.length / 2) + 1; j++) {
this.aHodnoty.add(j);
}
}
Collections.shuffle(this.aHodnoty);
}
public boolean zhoda() {
if (this.aHodnotaTlac[0] == this.aHodnotaTlac[1]) {
return true;
}
return false;
}
public void zapisCislaDoSuboru() {
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Semestralka.txt", true)))) {
out.println("haha");
//more code
out.println("hahahahha");
//more code
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
}
public void actionPerformed(ActionEvent e) {
int match = 0;
if (this.aTlacitkoExit == e.getSource()) {
System.exit(0);
}
if (this.aTlacitkoReplay == e.getSource()) {
}
for (int i = 0; i < this.aHracieTlactika.length; i++) {
if (this.aHracieTlactika[i] == e.getSource()) {
this.aHracieTlactika[i].setText("" + this.aHodnoty.get(i));
this.aHracieTlactika[i].setEnabled(false);
this.aPocitadlo++;
this.aPocetTahov += 1;
if (this.aPocitadlo == 3) {
if (this.zhoda()) {
match+=1;
if (match==10)
{
System.out.println("You win");
}
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(false);
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(false);
} else {
this.aHracieTlactika[this.aTlacitkoIden[0]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[0]].setText("");
this.aHracieTlactika[this.aTlacitkoIden[1]].setEnabled(true);
this.aHracieTlactika[this.aTlacitkoIden[1]].setText("");
}
this.aPocitadlo = 1;
}
if (this.aPocitadlo == 1) {
this.aTlacitkoIden[0] = i;
this.aHodnotaTlac[0] = this.aHodnoty.get(i);
}
if (this.aPocitadlo == 2) {
this.aTlacitkoIden[1] = i;
this.aHodnotaTlac[1] = this.aHodnoty.get(i);
}
}
}
}
}

How to use JTextArea and Append

Please Help. When I run this GUI the numbers run off the frame. I know I have to use JTextArea and append but where do I put that in my code. can someone explain to me in simple terms and show me? I want to make it scroll vertically and horizontally and when I do add the JTextArea I get this error: error: cannot find symbol panel.setMessage(message);
import java.io.*;
import java.util.*;
import java.lang.*;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class prime extends JFrame
{
public static void main(String[] args)
{
prime frame = new prime();
}
private JTextArea panel;
private JPanel inPanel;
private JTextField inField;
public prime()
{
final int width = 500;
final int height = 500;
setSize(width, height);
setTitle("Find Prime Numbers");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JTextArea(20, 10);
add(new JScrollPane(panel), "Center");
inPanel = new JPanel();
inPanel.add(new JLabel("Enter Your Number", SwingConstants.RIGHT));
inField = new JTextField(20);
ActionListener inListener = new TextListener();
inField.addActionListener(inListener);
inPanel.add(inField);
add(inPanel, "South");
setVisible(true);
}
private class TextListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String message = inField.getText();
inField.setText("");
panel.setMessage(message);
}
}
class TextPanel extends JPanel
{
private String message;
private Color backGroundColor;
public TextPanel()
{
message = "";
backGroundColor = Color.white;
}
public TextPanel(String x, Color background)
{
message = x;
backGroundColor = background;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
int width = getWidth();
int height = getHeight();
setBackground(backGroundColor);
g2.setColor(Color.black);
Font x = new Font("TimesNewRoman", Font.BOLD,20);
g2.setFont(x);
FontMetrics fm = g2.getFontMetrics(x);
g2.drawString(message,50, 50);
if(!(message.equals("")))
g2.drawString(previousPrime(message),50,78);
}
public void setMessage(String message) {
if (isPrime(Integer.parseInt(message))){
this.message = message + " is a prime number.";
}
else
this.message = message + " is not a prime number.";
repaint();
}
public boolean isPrime(int num){
for(int i = 2; i < num; i++){
if (num % i == 0)
return false;
}
if(num < 2)
return false;
return true;
}
public String previousPrime(String message){
String totalPrimeNum = "";
int finalNum = Integer.parseInt(message.substring(0,message.indexOf(" ")));
int count = 0;
for(int i = 2; i < finalNum; i++){
if(isPrime(i)) {
totalPrimeNum += " " + i;
count++;
}
if(count == 10) {
totalPrimeNum += "\n";
count = 0;
}
}
if (isPrime(Integer.parseInt(message.substring(0,message.indexOf(" ")))))
totalPrimeNum += " " + finalNum;
System.out.println(totalPrimeNum);
return totalPrimeNum;
}}}
Look at what you have and what you want to achieve. You have a method which can verify if a value is a prime or not, but it does not produce any output. You have a JTextArea which allows you to add content to it.
You have a square peg and a round hole. One of these things needs to change. You have control over the setMessage method, but you don't have control over the JTextArea, this would suggest that the setMessage needs to change. While you could pass the JTextArea to the setMessage method, a better solution would be to change the setMessage to return some kind of meaningful value or simply get rid of it in favor of using the isPrime method instead
Take your TestPane and move the functionality used to calculate and test for a prime number to a new class, for example...
public class PrimeCalculator {
public boolean isPrime(int num) {
for (int i = 2; i < num; i++) {
if (num % i == 0) {
return false;
}
}
if (num < 2) {
return false;
}
return true;
}
public String previousPrime(String message) {
StringBuilder totalPrimeNum = new StringBuilder(128);
int finalNum = Integer.parseInt(message.substring(0, message.indexOf(" ")));
int count = 0;
for (int i = 2; i < finalNum; i++) {
if (isPrime(i)) {
totalPrimeNum.append(" ").append(i);
count++;
}
if (count == 10) {
totalPrimeNum.append("\n");
count = 0;
}
}
if (isPrime(Integer.parseInt(message.substring(0, message.indexOf(" "))))) {
totalPrimeNum.append(" ").append(finalNum);
}
System.out.println(totalPrimeNum);
return totalPrimeNum.toString();
}
}
This now makes no assumptions over what you want to do and simply produces output. You can now use these methods and make decisions about how to use the output, for example...
private class TextListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
PrimeCalculator calc = new PrimeCalculator();
String message = inField.getText();
inField.setText("");
String text = message + " is not a prime number\n";
try {
if (calc.isPrime(Integer.parseInt(message))) {
text = message + " is a prime number\n";
}
} catch (NumberFormatException exp) {
text = message + " is not a valid integer\n";
}
panel.append(message);
panel.setCaretPosition(panel.getDocument().getLength());
}
}
Sometimes, you need to rethink your design to support what it is you want to achieve.
The process of verifying and calculating the prime numbers should do just that, they should not do anything else (like update the screen), this way you can decouple the code and re-use it in different ways which you didn't original think of (like outputting to a file or the web)
See How to Use Text Areas and How to Use Scroll Panes for more details

can't set text to Jbutton on a grid for a game

i am creating a game based on a grid and a parser from english to java. i am having trouble making the command draw on a grid. right now im trying to simply write a letter onto the grid so i can see it and then later i will add graphics. basically, the game accepts commands in english, then parses them to java and should draw it to a grid. i have done most of the code, but its not working. im not too good with swing and GUI in java. below is the code for the parser which has been reduced, and the grid its self. i have some methods that should draw but they dont, im not sure why.
ServerPlayerParsing class:
public class ServerPlayerParsing {
ServerGridGenerator serverGrid = new ServerGridGenerator (10, 10);
public String validate(String command){
serverGrid.frameGen();
if (wordCount(command)== 3) {
String[] commandArray = command.split(" ");
commandParsing(commandArray);
} else {
System.out.println("Error! Format incorrect!");
System.out.println("Correct format = [COMMAND 1] [COMMAND 2] [COMMAND 3]");
}
return "";
}
public int wordCount(String command){
String[] commandCount = command.split("\\s");
return commandCount.length;
}
public String commandParsing(String[] commandArray) {
switch (commandArray[0]) {
case "move":
secondCommand (commandArray);
break;
default: System.out.println("Error in first command!");
}
return " ";
}
public String secondCommand (String commandArray[]) {
switch (commandArray[1]) {
case "forward":
forwardMovement(commandArray);
break;
case "backward":
backwardMovement (commandArray);
break;
case "left":
leftMovement (commandArray);
break;
case "right":
rightMovement (commandArray);
break;
default: System.out.println("Error in second command!");
}
return " ";
}
public String forwardMovement (String commandArray[]) {
switch (commandArray[2]) {
case "1":
serverGrid.serverPlayerMoveForward(1);
break;
case "2":
serverGrid.serverPlayerMoveForward(2);
break;
default: System.out.println("Error in third command!");
}
return " ";
}
public String backwardMovement (String commandArray[]) {
switch (commandArray[2]) {
case "1":
serverGrid.serverPlayerMoveBackward(1);
break;
case "2":
serverGrid.serverPlayerMoveBackward(2);
break;
default: System.out.println("Error in third command!");
}
return " ";
}
public String leftMovement (String commandArray[]) {
switch (commandArray[2]) {
case "1":
serverGrid.serverPlayerMoveLeft(1);
break;
case "2":
serverGrid.serverPlayerMoveLeft(2);
break;
default: System.out.println("Error in third command!");
}
return " ";
}
public String rightMovement (String commandArray[]) {
switch (commandArray[2]) {
case "1":
serverGrid.serverPlayerMoveRight(1);
break;
case "2":
serverGrid.serverPlayerMoveRight(2);
break;
default: System.out.println("Error in third command!");
}
return " ";
}
}
ServerGridGenerator:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ServerGridGenerator extends JFrame {
public int serverPlayerXPos = 0;
public int serverPlayerYPos = 0;
int row;
int column;
public void frameGen(){
row = 10;
column = 10;
int sizeGrid = 700;
ServerGridGenerator frame = new ServerGridGenerator(row, column);
frame.setPreferredSize(new Dimension(sizeGrid, sizeGrid));
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public ServerGridGenerator(int row, int column) {
JButton[][] squareButtons = new JButton [row][column];
Container pane = getContentPane();
pane.setLayout(new GridLayout(row, column));
for(int y=0; y<column; y++){
for (int x=0; x<row; x++) {
squareButtons[y][x] = new JButton("");
squareButtons[y][x].setOpaque(true);
squareButtons[y][x].setBackground(Color.white);
squareButtons[y][x].setEnabled(false);
pane.add(squareButtons[y][x]);
}
}
}
public void serverPlayerMoveRight (int moveBy){
JButton[][] squareButtons = new JButton [row][column];
for (int i=0; i<moveBy; i++) {
serverPlayerXPos = serverPlayerXPos + 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveLeft (int moveBy){
JButton[][] squareButtons = new JButton [row][column];
for (int i=0; i<moveBy; i++) {
serverPlayerXPos = serverPlayerXPos - 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveForward (int moveBy){
JButton[][] squareButtons = new JButton [row][column];
for (int i=0; i<moveBy; i++) {
serverPlayerYPos = serverPlayerYPos + 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveBackward (int moveBy){
JButton[][] squareButtons = new JButton [row][column];
for (int i=0; i<moveBy; i++) {
serverPlayerYPos = serverPlayerYPos - 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
}
logically im pretty sure this works, but im not too familiar with java and if im allowed to modify text on the JButton after the program is running, either way could you please help me, it would be greatly appreciated!
Thanks
your frame and your code for the grid are seperate, it shouldnt be like that. create one method for the grid, and other for the left, right, forward and backward movements. therefore your constructor will be called and nothing else.
Your update event just has to call the setText method on whatever button you want the text on.
public void updateWhatever(String str, int buttonX, int buttonY){
squareButton[buttonX][buttonY].setText(str);
}
As for your code. You also probably need to fix your JButton 2D Array.
JButton[][] squareButtons = new JButton [width][height];
That array should probably be a global variable instead of a local. The Data is dumped every time your method finishes and none of the data is saved anywhere in memory. Also, when constructing an array of objects you need to you need to instantiate each object in the array to access any of the methods.
int height = 9;
int width = 9;
for(int i = 0; i <height; i++)
for(int j = 0; j < width; j++)
squareButtons[i][j] = new JButton();
// Grid size 10x10
Try that out let me know how it goes.
Update
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ServerGridGenerator extends JFrame {
public int serverPlayerXPos = 0;
public int serverPlayerYPos = 0;
int row = 10;
int column = 10;
int sizeGrid = 700;
JButton[][] squareButtons = new JButton [row][column];
public void frameGen(){
ServerGridGenerator frame = new ServerGridGenerator(row, column);
frame.setPreferredSize(new Dimension(sizeGrid, sizeGrid));
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public ServerGridGenerator(int r, int c) {
squareButtons = new JButton [r][c];
Container pane = getContentPane();
pane.setLayout(new GridLayout(r, c));
for(int y=0; y<c; y++){
for (int x=0; x<r; x++) {
squareButtons[y][x] = new JButton("");
squareButtons[y][x].setOpaque(true);
squareButtons[y][x].setBackground(Color.white);
squareButtons[y][x].setEnabled(false);
pane.add(squareButtons[y][x]);
}
}
}
public void serverPlayerMoveRight (int moveBy){
for (int i=0; i<moveBy; i++) {
serverPlayerXPos = serverPlayerXPos + 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveLeft (int moveBy){
for (int i=0; i<moveBy; i++) {
serverPlayerXPos = serverPlayerXPos - 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveForward (int moveBy){
for (int i=0; i<moveBy; i++) {
serverPlayerYPos = serverPlayerYPos + 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
public void serverPlayerMoveBackward (int moveBy){
for (int i=0; i<moveBy; i++) {
serverPlayerYPos = serverPlayerYPos - 1;
squareButtons[serverPlayerYPos][serverPlayerXPos].setText(" P1");
}
}
}
Here's what that class should look like. I have a similar project where I made the battle ship board game.

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