| | |
SetBounds of Components
![]() |
Hi,
I am making tic tac toe, and I basically have it all working, except the GUI has a few bugs. Right now, I am not using a layout. I am using "setBounds" instead.
When a player wins, an image saying "you win" should be displayed over the title image and the game board. That works, except when you move the mouse over the buttons, the "you win" image is covered by those buttons.
Also, when the program first runs, the buttons are not visible unless you roll over them with a mouse...
Here is the code:
Thanks!
I am making tic tac toe, and I basically have it all working, except the GUI has a few bugs. Right now, I am not using a layout. I am using "setBounds" instead.
When a player wins, an image saying "you win" should be displayed over the title image and the game board. That works, except when you move the mouse over the buttons, the "you win" image is covered by those buttons.
Also, when the program first runs, the buttons are not visible unless you roll over them with a mouse...
Here is the code:
java Syntax (Toggle Plain Text)
//import everything: import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.applet.AudioClip; import java.net.*; //the class with the JFrame and the ActionListner: public class TicTacToe extends JFrame implements ActionListener { //this is an array of the buttons (spots). We use an array, not //an arrayList because the number of buttons is constant; it does //not change. JButton spots[] = new JButton[9]; //this will keep track of turns int turn = 1; //this is a JLabel: it will display the text JLabel lbl = new JLabel(new ImageIcon("title.png")); //this JLabel will display whose turn it is JLabel turnLbl = new JLabel("X's Turn"); ImageIcon red = new ImageIcon("red.png"); ImageIcon blue = new ImageIcon("blue.png"); ImageIcon blank = new ImageIcon("blank.png"); ImageIcon loseImg = new ImageIcon("lose.png"); ImageIcon winImg = new ImageIcon("win.png"); ImageIcon drawImg = new ImageIcon("draw.png"); JLabel lose = new JLabel(loseImg); JLabel win = new JLabel(winImg); JLabel draw = new JLabel(drawImg); URL hitURL = null, cheerURL = null, booURL = null; AudioClip hit = null, cheer = null, boo = null; //the constructor public TicTacToe() { super("TicTacToe: Boxing Style"); setSize(450,700); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //this will hold the buttons: Container container = getContentPane(); //this will tell the computer how to display the buttons: container.setLayout(null); //we will add the winning, losing, and draw labels, butt //move them off the screen. container.add(lose); lose.setBounds(-500,-500,331,438); container.add(win); lose.setBounds(-500,-500,331,438); container.add(draw); lose.setBounds(-500,-500,331,438); //add the lbl: container.add(lbl); lbl.setBounds(20,0,400,288); try { hitURL = this.getClass().getResource("hit.wav"); booURL = this.getClass().getResource("boo.wav"); cheerURL = this.getClass().getResource("cheer.wav"); hit = JApplet.newAudioClip(hitURL); boo = JApplet.newAudioClip(booURL); cheer = JApplet.newAudioClip(cheerURL); } catch(Exception e){} //before we can add the buttons to the container, we must //initialize them. Use a for loop to do it: int newLine = 0; int lineCount = 0; for(int i = 0; i < spots.length; i++) { //initialize it with a blank image spots[i] = new JButton(blank); //this checks whether to use a new row if(i==3 || i ==6) { newLine++; lineCount = 0; } //set the position of the button spots[i].setBounds(75+(lineCount*100),300+(newLine*100),100,100); //add it to the container container.add(spots[i]); //and now add the action listener: spots[i].addActionListener(this); lineCount++; } //add the JLabel that describes the turn container.add(turnLbl); turnLbl.setBounds(200,630,100,30); container.setComponentZOrder(lose,0); container.setComponentZOrder(win,0); container.setComponentZOrder(draw,0); } public void reset() { for(int i = 0; i < spots.length; i++) { spots[i].setIcon(blank); spots[i].addActionListener(this); } turn = 1; } //the mandatory method: public void actionPerformed(ActionEvent e) { hit.play(); try { Thread.sleep(600); } catch(Exception excep){} //this will check the button pressed: for(int i = 0; i < spots.length; i++) { if(e.getSource()==spots[i]) { //set the button to X spots[i].setIcon(red); //now, change the JLabel that describes the player's turn turnLbl.setText("X's (Red's) Turn"); //disable the btn so it can't be re-pressed spots[i].removeActionListener(this); } } turn++; //before letting the other player go, check whether a player won: checkWin(); //this method lets the computer select its turn ai(); } public void ai() { boolean movedYet; //if this is the computer's first turn, then try to go in the top left //if already taken, take the middle if(turn == 2) { //if the top left is taken, take the middle if(spots[0].getIcon().equals(red)) { spots[4] .setIcon(blue); spots[4].removeActionListener(this); movedYet = true; } //else, take the top left else { spots[0] .setIcon(blue); spots[0].removeActionListener(this); movedYet = true; } } //if this is not the first turn, then check for 2 out of 3 spots //taken. If there are none, go to a random location else { //callin this method checks for two in a row of the first String passed in. //It then takes the 3rd spot with the 2nd String passed in: movedYet = twoInARow(blue); //if the computer didn't take an offensive spot, take a defensive //one. if(!movedYet) { movedYet = twoInARow(red); //if there is no defensive move, take the next open one. if(!movedYet) { //this loop finds the first untaken spot: for(int i = 0; i < spots.length; i++) { //if empty, take it! if(spots[i].getIcon().equals(blank)) { spots[i] .setIcon(blue); spots[i].removeActionListener(this); movedYet = true; break; } } } } } turn++; System.out.println(turn); checkWin(); if(!movedYet) { //if no spot was taken, it must be a cat's game: draw.setBounds(50,50,331,438); reset(); } } public boolean twoInARow(Icon a) { for(int i = 0; i < 3; i++) { //this checks for 2 in a row from the top if(spots[i].getIcon().equals(a) && spots[i+3].getIcon().equals(a) && spots[i+6].getIcon().equals(blank)) { spots[i+6].setIcon(blue); spots[i+6].removeActionListener(this); return true; } //this checks (from the top and bottom) //for a taken spot, then a gap, then a taken one: if(spots[i].getIcon().equals(a) && spots[i+6].getIcon().equals(a) && spots[i+3].getIcon().equals(blank)) { spots[i+3].setIcon(blue); spots[i+3].removeActionListener(this); return true; } //this checks for 2 in a row from the bottom if(spots[i+6].getIcon().equals(a) && spots[i+3].getIcon().equals(a) && spots[i].getIcon().equals(blank)) { spots[i] .setIcon(blue); spots[i].removeActionListener(this); return true; } //this checks for 2 in a row from the left if(spots[i*3].getIcon().equals(a) && spots[(i*3)+1].getIcon().equals(a) && spots[(i*3)+2].getIcon().equals(blank)) { spots[(i*3)+2] .setIcon(blue); spots[(i*3)+2].removeActionListener(this); return true; } //this checks (from the left and right) //for a taken spot, then a gap, then a taken one if(spots[i*3].getIcon().equals(a) && spots[(i*3)+2].getIcon().equals(a) && spots[(i*3)+1].getIcon().equals(blank)) { spots[(i*3)+1] .setIcon(blue); spots[(i*3)+1].removeActionListener(this); return true; } //this checks for 2 in a row from the right if(spots[(i*3)+2].getIcon().equals(a) && spots[(i*3)+1].getIcon().equals(a) && spots[i*3].getIcon().equals(blank)) { spots[i*3] .setIcon(blue); spots[i*3].removeActionListener(this); return true; } //now we will check for a diagnol 2 in a row: for(int j = 0; j <= 2; j+=2) { //this will check for diagnol X wins if(spots[j].getIcon()==a && spots[4].getIcon()==a && spots[8-j].getIcon().equals(blank)) { spots[8-j] .setIcon(blue); spots[8-j].removeActionListener(this); return true; } //this checks (from a diagnol) //for a taken spot, then a gap, then a taken one if(spots[j].getIcon()==a && spots[8-j].getIcon()==a && spots[4].getIcon().equals(blank)) { spots[4] .setIcon(blue); spots[4].removeActionListener(this); return true; } if(spots[8-j].getIcon()==a && spots[4].getIcon()==a && spots[j].getIcon().equals(blank)) { spots[j] .setIcon(blue); spots[j].removeActionListener(this); return true; } } } return false; } public void checkWin() { //first, we will use to go through three iterations. This allows us to //check for both horizontal and vertical wins without using too //much code: for(int i = 0; i < 3; i++) { //this checks for a vertical X win if(spots[i].getIcon().equals(red) && spots[i+3].getIcon().equals(red) && spots[i+6].getIcon().equals(red)) { cheer.play(); try { Thread.sleep(600); } catch(Exception excep){} win.setBounds(50,50,331,438); reset(); return; } //this checks for a vertical O win if(spots[i].getIcon().equals(blue) && spots[i+3].getIcon().equals(blue) && spots[i+6].getIcon().equals(blue)) { boo.play(); try { Thread.sleep(600); } catch(Exception excep){} lose.setBounds(50,50,331,438);; reset(); return; } //this checks for a horizontal X win if(spots[i*3].getIcon().equals(red) && spots[(i*3)+1].getIcon().equals(red) && spots[(i*3)+2].getIcon().equals(red)) { cheer.play(); try { Thread.sleep(600); } catch(Exception excep){} win.setBounds(50,50,331,438); reset(); return; } //this checks for a horizontal O win if(spots[i*3].getIcon().equals(blue) && spots[(i*3)+1].getIcon().equals(blue) && spots[(i*3)+2].getIcon().equals(blue)) { boo.play(); try { Thread.sleep(600); } catch(Exception excep){} lose.setBounds(50,50,331,438);; reset(); return; } } //now, this loop will check for diagnol wins for(int i = 0; i <= 2; i+=2) { //this will check for diagnol X wins if(spots[i].getIcon().equals(red) && spots[4].getIcon().equals(red) && spots[8-i].getIcon().equals(red)) { cheer.play(); try { Thread.sleep(600); } catch(Exception excep){} win.setBounds(50,50,331,438); reset(); return; } //this will check for diagnol O wins if(spots[i].getIcon().equals(blue) && spots[4].getIcon().equals(blue) && spots[8-i].getIcon().equals(blue)) { boo.play(); try { Thread.sleep(600); } catch(Exception excep){} lose.setBounds(50,50,331,438);; reset(); return; } } } //starter (main) method: public static void main(String[] args) { TicTacToe ttt = new TicTacToe(); } }
Thanks!
Last edited by Ghost; Jun 23rd, 2007 at 9:37 pm.
Using a NullLayout is not Platform independent as the varying underlying graphics systems display things differently, so the bounds are not always (and usually are not) the same and so your layout will not always work.
As far as the buttons showing up under the image, remove everything from the panel before displaying the image, then after displaying the image, remove it and redisplay/redraw the original item.
You may wish to create one JPanel with everything needed for the game/whatever and one Panel for the Image, then you can swap the JPanels.
If you do not wish to do this (or find it to hard), Google Java SplashScreen to find out how make on of those, and use that to display the image.
And, BTW, you do not have to use "pixel" locations. The GridBagLayout, once you understand it, is a very powerful layout manager where you can lay things out exactly how you want them with creative use of anchors, widths, heights, fills, and weights that is completely platform independent, without having to try and fiddle with pixel sizes and bounds.
As far as the buttons not immediately displaying, try moving the setVisible(true) to the end of the constructor and adding a validate() and/or pack() right before it.
As far as the buttons showing up under the image, remove everything from the panel before displaying the image, then after displaying the image, remove it and redisplay/redraw the original item.
You may wish to create one JPanel with everything needed for the game/whatever and one Panel for the Image, then you can swap the JPanels.
If you do not wish to do this (or find it to hard), Google Java SplashScreen to find out how make on of those, and use that to display the image.
And, BTW, you do not have to use "pixel" locations. The GridBagLayout, once you understand it, is a very powerful layout manager where you can lay things out exactly how you want them with creative use of anchors, widths, heights, fills, and weights that is completely platform independent, without having to try and fiddle with pixel sizes and bounds.
As far as the buttons not immediately displaying, try moving the setVisible(true) to the end of the constructor and adding a validate() and/or pack() right before it.
Java Programmer and Sun Systems Administrator
----------------------------------------------
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
--Brian Kernighan
----------------------------------------------
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
--Brian Kernighan
Ahh... now this makes sense
Thank you.
I want to use pixel locations because my next project is a game where I draw images and they get moved by the keyboard. Therefore, I think it is easier to use a NullLayout and use pixels.
I still have one more question, however. When I run the game, the buttons do not appear. They do not appear unless my mouse moves over them. Why?
Thank you.I want to use pixel locations because my next project is a game where I draw images and they get moved by the keyboard. Therefore, I think it is easier to use a NullLayout and use pixels.
I still have one more question, however. When I run the game, the buttons do not appear. They do not appear unless my mouse moves over them. Why?
•
•
•
•
Using a NullLayout is not Platform independent as the varying underlying graphics systems display things differently, so the bounds are not always (and usually are not) the same and so your layout will not always work.
As far as the buttons showing up under the image, remove everything from the panel before displaying the image, then after displaying the image, remove it and redisplay/redraw the original item.
You may wish to create one JPanel with everything needed for the game/whatever and one Panel for the Image, then you can swap the JPanels.
If you do not wish to do this (or find it to hard), Google Java SplashScreen to find out how make on of those, and use that to display the image.
And, BTW, you do not have to use "pixel" locations. The GridBagLayout, once you understand it, is a very powerful layout manager where you can lay things out exactly how you want them with creative use of anchors, widths, heights, fills, and weights that is completely platform independent, without having to try and fiddle with pixel sizes and bounds.
As far as the buttons not immediately displaying, try moving the setVisible(true) to the end of the constructor and adding a validate() and/or pack() right before it.
Last edited by Ghost; Jun 25th, 2007 at 4:47 pm.
•
•
•
•
Ahh... now this makes senseThank you.
I want to use pixel locations because my next project is a game where I draw images and they get moved by the keyboard. Therefore, I think it is easier to use a NullLayout and use pixels.
I still have one more question, however. When I run the game, the buttons do not appear. They do not appear unless my mouse moves over them. Why?
•
•
•
•
Try adding a call to validate() or repaint() after you have added all components. Since you are using Null Layout, the mechanisms for notifying the container to redraw itself may not behave in an expected manner. When you mouse over something, the window redraws the portion behind the mouse cursor, so this is probably what is causing the buttons to become visible.
Java Programmer and Sun Systems Administrator
----------------------------------------------
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
--Brian Kernighan
----------------------------------------------
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
--Brian Kernighan
![]() |
Other Threads in the Java Forum
- Previous Thread: JTable & MS Access
- Next Thread: Jboss
| Thread Tools | Search this Thread |
android api applet application apps array arrays automation awt bidirectional binary birt bluetooth businessintelligence busy_handler(null) card chat class classes client code collision columns component constructor database designadrawingapplicationusingjavajslider draw eclipse editor error errors eventlistener exception expand fractal game givemetehcodez graphics gui guidancer html ide image inetaddress input integer intellij j2me java javafx javamicroeditionuseofmotionsensor javaprojects jme jni jpanel jtree julia linux list loop machine map method methods mobile mobiledevelopmentcreatejar myaggfun netbeans newbie oracle parsing plazmic print problem program programming project recursion scanner server set sharepoint size smart sms smsspam sort sortedmaps sql string subclass support swing threads tree unlimited utility webservices windows






