943,910 Members | Top Members by Rank

Ad:
  • Java Discussion Thread
  • Unsolved
  • Views: 18839
  • Java RSS
You are currently viewing page 1 of this multi-page discussion thread
Jun 23rd, 2007
0

SetBounds of Components

Expand Post »
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:
java Syntax (Toggle Plain Text)
  1. //import everything:
  2. import javax.swing.*;
  3. import javax.swing.event.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import java.io.*;
  7. import java.applet.AudioClip;
  8. import java.net.*;
  9.  
  10. //the class with the JFrame and the ActionListner:
  11. public class TicTacToe extends JFrame implements ActionListener
  12. {
  13. //this is an array of the buttons (spots). We use an array, not
  14. //an arrayList because the number of buttons is constant; it does
  15. //not change.
  16. JButton spots[] = new JButton[9];
  17.  
  18. //this will keep track of turns
  19. int turn = 1;
  20.  
  21.  
  22. //this is a JLabel: it will display the text
  23. JLabel lbl = new JLabel(new ImageIcon("title.png"));
  24.  
  25. //this JLabel will display whose turn it is
  26. JLabel turnLbl = new JLabel("X's Turn");
  27.  
  28. ImageIcon red = new ImageIcon("red.png");
  29. ImageIcon blue = new ImageIcon("blue.png");
  30. ImageIcon blank = new ImageIcon("blank.png");
  31. ImageIcon loseImg = new ImageIcon("lose.png");
  32. ImageIcon winImg = new ImageIcon("win.png");
  33. ImageIcon drawImg = new ImageIcon("draw.png");
  34.  
  35. JLabel lose = new JLabel(loseImg);
  36. JLabel win = new JLabel(winImg);
  37. JLabel draw = new JLabel(drawImg);
  38.  
  39. URL hitURL = null, cheerURL = null, booURL = null;
  40. AudioClip hit = null, cheer = null, boo = null;
  41.  
  42. //the constructor
  43. public TicTacToe()
  44. {
  45. super("TicTacToe: Boxing Style");
  46. setSize(450,700);
  47. setVisible(true);
  48. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  49.  
  50. //this will hold the buttons:
  51. Container container = getContentPane();
  52. //this will tell the computer how to display the buttons:
  53. container.setLayout(null);
  54.  
  55.  
  56. //we will add the winning, losing, and draw labels, butt
  57. //move them off the screen.
  58. container.add(lose);
  59. lose.setBounds(-500,-500,331,438);
  60. container.add(win);
  61. lose.setBounds(-500,-500,331,438);
  62. container.add(draw);
  63. lose.setBounds(-500,-500,331,438);
  64.  
  65. //add the lbl:
  66. container.add(lbl);
  67. lbl.setBounds(20,0,400,288);
  68.  
  69. try
  70. {
  71. hitURL = this.getClass().getResource("hit.wav");
  72. booURL = this.getClass().getResource("boo.wav");
  73. cheerURL = this.getClass().getResource("cheer.wav");
  74. hit = JApplet.newAudioClip(hitURL);
  75. boo = JApplet.newAudioClip(booURL);
  76. cheer = JApplet.newAudioClip(cheerURL);
  77. }
  78. catch(Exception e){}
  79.  
  80. //before we can add the buttons to the container, we must
  81. //initialize them. Use a for loop to do it:
  82. int newLine = 0;
  83. int lineCount = 0;
  84. for(int i = 0; i < spots.length; i++)
  85. {
  86. //initialize it with a blank image
  87. spots[i] = new JButton(blank);
  88. //this checks whether to use a new row
  89. if(i==3 || i ==6)
  90. {
  91. newLine++;
  92. lineCount = 0;
  93. }
  94.  
  95. //set the position of the button
  96. spots[i].setBounds(75+(lineCount*100),300+(newLine*100),100,100);
  97.  
  98. //add it to the container
  99. container.add(spots[i]);
  100.  
  101. //and now add the action listener:
  102. spots[i].addActionListener(this);
  103.  
  104. lineCount++;
  105. }
  106.  
  107. //add the JLabel that describes the turn
  108. container.add(turnLbl);
  109. turnLbl.setBounds(200,630,100,30);
  110.  
  111. container.setComponentZOrder(lose,0);
  112. container.setComponentZOrder(win,0);
  113. container.setComponentZOrder(draw,0);
  114. }
  115.  
  116. public void reset()
  117. {
  118. for(int i = 0; i < spots.length; i++)
  119. {
  120. spots[i].setIcon(blank);
  121. spots[i].addActionListener(this);
  122. }
  123. turn = 1;
  124. }
  125.  
  126.  
  127. //the mandatory method:
  128. public void actionPerformed(ActionEvent e)
  129. {
  130. hit.play();
  131. try
  132. {
  133. Thread.sleep(600);
  134. }
  135. catch(Exception excep){}
  136.  
  137. //this will check the button pressed:
  138. for(int i = 0; i < spots.length; i++)
  139. {
  140. if(e.getSource()==spots[i])
  141. {
  142.  
  143. //set the button to X
  144. spots[i].setIcon(red);
  145.  
  146. //now, change the JLabel that describes the player's turn
  147. turnLbl.setText("X's (Red's) Turn");
  148.  
  149. //disable the btn so it can't be re-pressed
  150. spots[i].removeActionListener(this);
  151. }
  152. }
  153.  
  154. turn++;
  155.  
  156. //before letting the other player go, check whether a player won:
  157. checkWin();
  158.  
  159. //this method lets the computer select its turn
  160. ai();
  161. }
  162.  
  163. public void ai()
  164. {
  165.  
  166. boolean movedYet;
  167.  
  168.  
  169. //if this is the computer's first turn, then try to go in the top left
  170. //if already taken, take the middle
  171. if(turn == 2)
  172. {
  173. //if the top left is taken, take the middle
  174. if(spots[0].getIcon().equals(red))
  175. {
  176. spots[4] .setIcon(blue);
  177. spots[4].removeActionListener(this);
  178. movedYet = true;
  179. }
  180. //else, take the top left
  181. else
  182. {
  183. spots[0] .setIcon(blue);
  184. spots[0].removeActionListener(this);
  185. movedYet = true;
  186. }
  187. }
  188. //if this is not the first turn, then check for 2 out of 3 spots
  189. //taken. If there are none, go to a random location
  190. else
  191. {
  192.  
  193. //callin this method checks for two in a row of the first String passed in.
  194. //It then takes the 3rd spot with the 2nd String passed in:
  195. movedYet = twoInARow(blue);
  196.  
  197. //if the computer didn't take an offensive spot, take a defensive
  198. //one.
  199. if(!movedYet)
  200. {
  201. movedYet = twoInARow(red);
  202. //if there is no defensive move, take the next open one.
  203. if(!movedYet)
  204. {
  205. //this loop finds the first untaken spot:
  206. for(int i = 0; i < spots.length; i++)
  207. {
  208. //if empty, take it!
  209. if(spots[i].getIcon().equals(blank))
  210. {
  211. spots[i] .setIcon(blue);
  212. spots[i].removeActionListener(this);
  213. movedYet = true;
  214. break;
  215. }
  216. }
  217. }
  218. }
  219. }
  220.  
  221. turn++;
  222. System.out.println(turn);
  223. checkWin();
  224.  
  225. if(!movedYet)
  226. {
  227. //if no spot was taken, it must be a cat's game:
  228. draw.setBounds(50,50,331,438);
  229. reset();
  230. }
  231. }
  232.  
  233. public boolean twoInARow(Icon a)
  234. {
  235.  
  236. for(int i = 0; i < 3; i++)
  237. {
  238. //this checks for 2 in a row from the top
  239. if(spots[i].getIcon().equals(a) &&
  240. spots[i+3].getIcon().equals(a) &&
  241. spots[i+6].getIcon().equals(blank))
  242. {
  243. spots[i+6].setIcon(blue);
  244. spots[i+6].removeActionListener(this);
  245. return true;
  246. }
  247.  
  248. //this checks (from the top and bottom)
  249. //for a taken spot, then a gap, then a taken one:
  250. if(spots[i].getIcon().equals(a) &&
  251. spots[i+6].getIcon().equals(a) &&
  252. spots[i+3].getIcon().equals(blank))
  253. {
  254. spots[i+3].setIcon(blue);
  255. spots[i+3].removeActionListener(this);
  256. return true;
  257. }
  258.  
  259.  
  260. //this checks for 2 in a row from the bottom
  261. if(spots[i+6].getIcon().equals(a) &&
  262. spots[i+3].getIcon().equals(a) &&
  263. spots[i].getIcon().equals(blank))
  264. {
  265. spots[i] .setIcon(blue);
  266. spots[i].removeActionListener(this);
  267. return true;
  268. }
  269.  
  270. //this checks for 2 in a row from the left
  271. if(spots[i*3].getIcon().equals(a) &&
  272. spots[(i*3)+1].getIcon().equals(a) &&
  273. spots[(i*3)+2].getIcon().equals(blank))
  274. {
  275. spots[(i*3)+2] .setIcon(blue);
  276. spots[(i*3)+2].removeActionListener(this);
  277. return true;
  278. }
  279.  
  280.  
  281. //this checks (from the left and right)
  282. //for a taken spot, then a gap, then a taken one
  283. if(spots[i*3].getIcon().equals(a) &&
  284. spots[(i*3)+2].getIcon().equals(a) &&
  285. spots[(i*3)+1].getIcon().equals(blank))
  286. {
  287. spots[(i*3)+1] .setIcon(blue);
  288. spots[(i*3)+1].removeActionListener(this);
  289. return true;
  290. }
  291.  
  292.  
  293. //this checks for 2 in a row from the right
  294. if(spots[(i*3)+2].getIcon().equals(a) &&
  295. spots[(i*3)+1].getIcon().equals(a) &&
  296. spots[i*3].getIcon().equals(blank))
  297. {
  298. spots[i*3] .setIcon(blue);
  299. spots[i*3].removeActionListener(this);
  300. return true;
  301. }
  302.  
  303. //now we will check for a diagnol 2 in a row:
  304. for(int j = 0; j <= 2; j+=2)
  305. {
  306. //this will check for diagnol X wins
  307. if(spots[j].getIcon()==a &&
  308. spots[4].getIcon()==a &&
  309. spots[8-j].getIcon().equals(blank))
  310. {
  311. spots[8-j] .setIcon(blue);
  312. spots[8-j].removeActionListener(this);
  313. return true;
  314. }
  315.  
  316. //this checks (from a diagnol)
  317. //for a taken spot, then a gap, then a taken one
  318. if(spots[j].getIcon()==a &&
  319. spots[8-j].getIcon()==a &&
  320. spots[4].getIcon().equals(blank))
  321. {
  322. spots[4] .setIcon(blue);
  323. spots[4].removeActionListener(this);
  324. return true;
  325. }
  326.  
  327.  
  328. if(spots[8-j].getIcon()==a &&
  329. spots[4].getIcon()==a &&
  330. spots[j].getIcon().equals(blank))
  331. {
  332. spots[j] .setIcon(blue);
  333. spots[j].removeActionListener(this);
  334. return true;
  335. }
  336. }
  337. }
  338. return false;
  339. }
  340.  
  341. public void checkWin()
  342. {
  343. //first, we will use to go through three iterations. This allows us to
  344. //check for both horizontal and vertical wins without using too
  345. //much code:
  346. for(int i = 0; i < 3; i++)
  347. {
  348. //this checks for a vertical X win
  349. if(spots[i].getIcon().equals(red) &&
  350. spots[i+3].getIcon().equals(red) &&
  351. spots[i+6].getIcon().equals(red))
  352. {
  353. cheer.play();
  354. try
  355. {
  356. Thread.sleep(600);
  357. }
  358. catch(Exception excep){}
  359.  
  360. win.setBounds(50,50,331,438);
  361. reset();
  362. return;
  363. }
  364.  
  365. //this checks for a vertical O win
  366. if(spots[i].getIcon().equals(blue) &&
  367. spots[i+3].getIcon().equals(blue) &&
  368. spots[i+6].getIcon().equals(blue))
  369. {
  370. boo.play();
  371. try
  372. {
  373. Thread.sleep(600);
  374. }
  375. catch(Exception excep){}
  376. lose.setBounds(50,50,331,438);;
  377. reset();
  378. return;
  379. }
  380.  
  381. //this checks for a horizontal X win
  382. if(spots[i*3].getIcon().equals(red) &&
  383. spots[(i*3)+1].getIcon().equals(red) &&
  384. spots[(i*3)+2].getIcon().equals(red))
  385. {
  386. cheer.play();
  387. try
  388. {
  389. Thread.sleep(600);
  390. }
  391. catch(Exception excep){}
  392.  
  393. win.setBounds(50,50,331,438);
  394. reset();
  395. return;
  396. }
  397.  
  398. //this checks for a horizontal O win
  399. if(spots[i*3].getIcon().equals(blue) &&
  400. spots[(i*3)+1].getIcon().equals(blue) &&
  401. spots[(i*3)+2].getIcon().equals(blue))
  402. {
  403. boo.play();
  404. try
  405. {
  406. Thread.sleep(600);
  407. }
  408. catch(Exception excep){}
  409. lose.setBounds(50,50,331,438);;
  410. reset();
  411. return;
  412. }
  413. }
  414.  
  415. //now, this loop will check for diagnol wins
  416. for(int i = 0; i <= 2; i+=2)
  417. {
  418. //this will check for diagnol X wins
  419. if(spots[i].getIcon().equals(red) &&
  420. spots[4].getIcon().equals(red) &&
  421. spots[8-i].getIcon().equals(red))
  422. {
  423. cheer.play();
  424. try
  425. {
  426. Thread.sleep(600);
  427. }
  428. catch(Exception excep){}
  429.  
  430. win.setBounds(50,50,331,438);
  431. reset();
  432. return;
  433. }
  434.  
  435. //this will check for diagnol O wins
  436. if(spots[i].getIcon().equals(blue) &&
  437. spots[4].getIcon().equals(blue) &&
  438. spots[8-i].getIcon().equals(blue))
  439. {
  440. boo.play();
  441. try
  442. {
  443. Thread.sleep(600);
  444. }
  445. catch(Exception excep){}
  446. lose.setBounds(50,50,331,438);;
  447. reset();
  448. return;
  449. }
  450. }
  451. }
  452.  
  453. //starter (main) method:
  454. public static void main(String[] args) {
  455. TicTacToe ttt = new TicTacToe();
  456. }
  457.  
  458. }

Thanks!
Last edited by Ghost; Jun 23rd, 2007 at 9:37 pm.
Reputation Points: 12
Solved Threads: 2
Posting Whiz
Ghost is offline Offline
352 posts
since Aug 2004
Jun 24th, 2007
0

Re: SetBounds of Components

Quote ...
Right now, I am not using a layout.
Bad! And wrong too! You're implicitly using a NullLayout, which you should never, ever use.
Team Colleague
Reputation Points: 1658
Solved Threads: 331
duckman
jwenting is offline Offline
7,719 posts
since Nov 2004
Jun 24th, 2007
0

Re: SetBounds of Components

I want to use setBounds, ao what layout should I use? SetBounds doesn't seem to work with a FlowLayout.

Thanks!
Reputation Points: 12
Solved Threads: 2
Posting Whiz
Ghost is offline Offline
352 posts
since Aug 2004
Jun 25th, 2007
0

Re: SetBounds of Components

And why not use a NullLayout? It's an official Java class, so what is wrong with it? Is it just personal preference?

Also, I have seen many, many, many projects/games use this style.

What should I do instead?

Thanks
Reputation Points: 12
Solved Threads: 2
Posting Whiz
Ghost is offline Offline
352 posts
since Aug 2004
Jun 25th, 2007
0

Re: SetBounds of Components

Use GridLayout or GridBagLayout.
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 839
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Jun 25th, 2007
0

Re: SetBounds of Components

Click to Expand / Collapse  Quote originally posted by Ezzaral ...
Use GridLayout or GridBagLayout.
Those do not use pixel locations. They simply use a grid that the user defines. I need to use pixel locations.
Reputation Points: 12
Solved Threads: 2
Posting Whiz
Ghost is offline Offline
352 posts
since Aug 2004
Jun 25th, 2007
0

Re: SetBounds of Components

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.
Moderator
Reputation Points: 1471
Solved Threads: 490
Industrious Poster
masijade is offline Offline
4,043 posts
since Feb 2006
Jun 25th, 2007
0

Re: SetBounds of Components

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?

Click to Expand / Collapse  Quote originally posted by masijade ...
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.
Reputation Points: 12
Solved Threads: 2
Posting Whiz
Ghost is offline Offline
352 posts
since Aug 2004
Jun 25th, 2007
0

Re: SetBounds of Components

Click to Expand / Collapse  Quote originally posted by Ghost ...
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?
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.
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 839
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Jun 26th, 2007
0

Re: SetBounds of Components

Click to Expand / Collapse  Quote originally posted by Ezzaral ...
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.
As I mentioned in the last sentence of my post (as well). ;-)
Moderator
Reputation Points: 1471
Solved Threads: 490
Industrious Poster
masijade is offline Offline
4,043 posts
since Feb 2006

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Java Forum Timeline: JTable & MS Access
Next Thread in Java Forum Timeline: Jboss





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC