Join 300,480 Java Programmers for FREE! Get instant access to thousands of Java experts, tutorials, code snippets, and more! There are 1,769 people online right now. Registration is fast and FREE... Join Now!
I have written a working 3d tic tac toe application that receives user input as an ordered triplet (plane, row, col) to record a move in a 3-dim array board[4][4][4]. I anticipate no problem merging the logic of my application into this applet.
The program plays at three levels. My problem is that I know next to nothing about GUIs and am trying to display a grid of buttons which will be four 4 by 4 grids with some space between each of these 4by4 grids of buttons. I have some code which produces a much too large grid of 64 buttons arranged in 16 rows and 4 columns. I would like an applet that has this grid (much smaller in the left portion of the applet and allows me to add a textfield and a label and a start button.
I will (shamefully) share my first attempt (I am using Eclipse).
CODE
package tic; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ThreeDTic extends JApplet implements ActionListener { JButton pick[][][] = new JButton [4][4][4]; private int i,j,k; public void init() { //Container contentPane = getContentPane(); //contentPane.setLayout(new GridLayout(4,4)); //contentPane.setPreferredSize(new Dimension(40,40)); setLayout( new GridLayout( 16, 4 ) ); setSize(200,200); for (i=0; i < 4; i++) for (j=0; j < 4; j++) for (k=0; k <4; k++){ pick[i][j][k] = new JButton("?"); pick[i][j][k].addActionListener(this); pick[i][j][k].setSize(10, 10); pick[i][j][k].setName("" + i +"" +j +"" +k); pick[i][j][k].setPreferredSize(new Dimension(10,10)); pick[i][j][k].setMaximumSize(new Dimension(10,10)); pick[i][j][k].setMinimumSize(new Dimension(10,10)); //Rectangle r= new Rectangle(i,j*10,10+i,10+j); //pick[i][j][k].setBounds(r); //pick[i][j][k].setBorder(null); //contentPane.add(pick[i][j][k]); add(pick[i][j][k]); }
}
public void actionPerformed(ActionEvent ae) { // what woke me up? JButton thisOne= (JButton)ae.getSource(); System.out.println(thisOne.getName()); } }
This post has been edited by robyn9876: 6 Jan, 2009 - 07:57 AM
Okay, so we are talking an X,Y,Z plane here for the board, are you using all of the available spaces (including the center one: (2,2,2))? Or are you just using the faces that are visible from the outside?
Don't worry about being ashamed of your code, it is always worth an attempt, who knows, you may have had the right idea about it and just made a simple mistake somewhere in implementation.
Okay, so we are talking an X,Y,Z plane here for the board, are you using all of the available spaces (including the center one: (2,2,2))? Or are you just using the faces that are visible from the outside?
Don't worry about being ashamed of your code, it is always worth an attempt, who knows, you may have had the right idea about it and just made a simple mistake somewhere in implementation.
Hope we can help
I am using all the positions (i,j,k) for 0<i,j,k<4. In the version I wrote I ask the user for the plane, row and column and then mark that postion with an X, the computer is O. I displayed a grid of ? as placeholders. Now I would like them to be clickable. That is essentially all.
// I know you did an applet // it's easier to just do a panel, test in a form // then throw it in an applet later public class ThreeTic extends JPanel implements ActionListener { public static final int PANELS = 4;
// want to store some extra data in our button // so we can access it later class BoardButton extends JButton { public int row, col, plane; public BoardButton(int row, int col, int plane) { this.row = row; this.col = col; this.plane = plane; this.setText(" "); } public String toString() { return "(" + row + "," + col + "," + plane + ") = " + this.getText(); } }
// A panel for rows and cols class SingleBoard extends JPanel { public static final int ROWS = 4; public static final int COLS = 4;
// I hate 2d arrays private BoardButton [] items = new BoardButton[ROWS*COLS];
public SingleBoard(int plane, ActionListener listener) { setLayout( new GridLayout( ROWS, COLS ) ); for (int row=0; row<ROWS; row++) { for (int col=0; col<COLS; col++) { BoardButton b = new BoardButton(row, col, plane); b.addActionListener(listener); add(b ); items[row*COLS+col] = b; } } }
// at this level, allow a button value to be changed // given a row and col // see, you never need 2d arrays public char getValue(int row, int col) { String s = items[row*COLS+col].getText(); return (s==null || s.length()==0) ? ' ' : s.charAt(0); }
public void setValue(int row, int col, char val) { items[row*COLS+col].setText(String.valueOf(val)); }
}
public ThreeTic() { // now we just place the boards setLayout( new GridLayout( 2, 2, 10, 10 ) ); for(int panel=0; panel<PANELS; panel++) { SingleBoard sb = new SingleBoard(panel, this); boards[panel] = sb; add(sb); } }
// we can get and set knowing a panel number // the let the panel method do the work public char getValue(int row, int col, int plane) { return boards[plane].getValue(row, col); }
public void setValue(int row, int col, int plane, char val) { boards[plane].setValue(row, col, val); }
public void actionPerformed(ActionEvent evt) { BoardButton b = (BoardButton)evt.getSource(); // we could set this directly // but we want to validate through setValue //b.setText("X"); setValue(b.row, b.col, b.plane, currentPlayer); b.setEnabled(false); currentPlayer = (currentPlayer=='X') ? 'O' : 'X'; System.out.println(b ); }
public static void test() { JFrame frm = new JFrame("Layout Test"); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.getContentPane().setLayout(new BorderLayout()); frm.getContentPane().add(new ThreeTic(), BorderLayout.CENTER); frm.pack(); frm.setVisible(true); }
}
edit: bloody syntax highlight smilies
This post has been edited by baavgai: 7 Jan, 2009 - 06:09 AM
// I know you did an applet // it's easier to just do a panel, test in a form // then throw it in an applet later public class ThreeTic extends JPanel implements ActionListener { public static final int PANELS = 4;
// want to store some extra data in our button // so we can access it later class BoardButton extends JButton { public int row, col, plane; public BoardButton(int row, int col, int plane) { this.row = row; this.col = col; this.plane = plane; this.setText(" "); } public String toString() { return "(" + row + "," + col + "," + plane + ") = " + this.getText(); } }
// A panel for rows and cols class SingleBoard extends JPanel { public static final int ROWS = 4; public static final int COLS = 4;
// I hate 2d arrays private BoardButton [] items = new BoardButton[ROWS*COLS];
public SingleBoard(int plane, ActionListener listener) { setLayout( new GridLayout( ROWS, COLS ) ); for (int row=0; row<ROWS; row++) { for (int col=0; col<COLS; col++) { BoardButton b = new BoardButton(row, col, plane); b.addActionListener(listener); add(b ); items[row*COLS+col] = b; } } }
// at this level, allow a button value to be changed // given a row and col // see, you never need 2d arrays public char getValue(int row, int col) { String s = items[row*COLS+col].getText(); return (s==null || s.length()==0) ? ' ' : s.charAt(0); }
public void setValue(int row, int col, char val) { items[row*COLS+col].setText(String.valueOf(val)); }
}
public ThreeTic() { // now we just place the boards setLayout( new GridLayout( 2, 2, 10, 10 ) ); for(int panel=0; panel<PANELS; panel++) { SingleBoard sb = new SingleBoard(panel, this); boards[panel] = sb; add(sb); } }
// we can get and set knowing a panel number // the let the panel method do the work public char getValue(int row, int col, int plane) { return boards[plane].getValue(row, col); }
public void setValue(int row, int col, int plane, char val) { boards[plane].setValue(row, col, val); }
public void actionPerformed(ActionEvent evt) { BoardButton b = (BoardButton)evt.getSource(); // we could set this directly // but we want to validate through setValue //b.setText("X"); setValue(b.row, b.col, b.plane, currentPlayer); b.setEnabled(false); currentPlayer = (currentPlayer=='X') ? 'O' : 'X'; System.out.println(b ); }
public static void test() { JFrame frm = new JFrame("Layout Test"); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.getContentPane().setLayout(new BorderLayout()); frm.getContentPane().add(new ThreeTic(), BorderLayout.CENTER); frm.pack(); frm.setVisible(true); }
}
edit: bloody syntax highlight smilies
I just got a chance to look over what you did. Wow! I didn't expect that much effort. I really appreciate it. I cut and pasted into Eclipse. It was a bloody mess since it came in as one line. After unravelling with a zillion returns, it compiles clean. However, I can't seem to run it.
I tried something simple to testit using your default constructor for the class but nothing happened. I really haven't had a chance to study your coding but it sure looks impressive. I will need to understand better so as to merge it with my 3D tictactoe program logic. In the interim, could you be so kind as to point in the right direction so that I can view the output of your code. I wrote the following test: (I assume that I need to do more).
Eclipse also has a nice function that will auto stylize your code for you (so you don't have to worry about getting everything broken up correctly). What makes it even better is that you can set how ti does the stylizing!
Here is how to use it: Source -> Format OR: Ctrl+Shift+F