aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Buttons not displaying till I mouseover them? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Buttons not displaying till I mouseover them?" Watch "Buttons not displaying till I mouseover them?" New topic
Author

Buttons not displaying till I mouseover them?

Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Hi folks,

I'm new to the forums and to Java. I just finished reading through Head First Java, which was pretty good at giving me a base, as I look into more advanced/in-depth books. I set out to make a Tic-tac-toe (Cross and Noughts) game to test my learning so far. While things have gone pretty well so far, I am absolutely stumped by my current issue. When I compile and run the code, the Grid of buttons that I generate do not appear. However, if I mouse over the window, they seem to then get refreshed/repainted. I cannot for the life of me figure out why this is happening. From Googling the issue, it seems this is either an issue with the layout manager or related to a thread conflict with the GUI? (http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html)

I would really appreciate if someone could help explain why this is happening and what I should do to fix the issue. Also, any other suggestions for my code/best practices would be most appreciated. I'm listing out the code for the game class and the button class.



Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1083
    
  10

Hi Ryan,
Welcome to the Ranch!

Straightaway, when I simply use JButton instead of your CNButton, the buttons are displaying for me.

You are using 2 variables x and y in your class - JButton extends JComponent which extends Container which extends Component - this Component class already has 2 fields declared - x & y - and they are 'int' too. By declaring your own fields with the same name of the super class, you are simply hiding the super class fields. So, whatever purpose the super-class were used goes for a toss.

why do you extend JButton and create a class? what is the purpose of it?


Ranga.
SCJP 1.4, OCMJEA/SCEA 5.0.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Hi Ranga,

thanks for your reply. I wasn't aware that I was conflicting with x,y fields from the Component class. However, I renamed x & y instance variables in the CNButton class to xv, yv , but I am still having the same issue, so it would appear that my issue is perhaps unrelated?

With regards to why I am extending JButton to CNButton, I was hoping to create instance variables with the x,y co-ordinate and value for each button object, so I thought that extending JButton would be the right approach? In retrospect, I can get away with using JButtons and having separate array instance variables in the main game class that record the x-y co-ordinates and values for each button.

Since posting this, I've managed to finish up the program and I can successfully play a game for an NxN board. However, I still have this issue with only a single button being displayed when I run the program, and having to hover over the window to make all the other buttons appear on mouseOver. I'm very puzzled by this, although, admittedly, my knowledge in the area of Swing and GUIs is fairly limited at the moment.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4540
    
    5

1. All Swing components should be constructed on the EDT (also applies to chancing their internal state).
2. Learn to use Layouts and stop worrying about coordinates.


luck, db
There are no new questions, but there may be new answers.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Darryl Burke wrote:1. All Swing components should be constructed on the EDT (also applies to chancing their internal state).
2. Learn to use Layouts and stop worrying about coordinates.

Hi Darryl. Thanks for your reply. Could you help me out a bit further by pointing out what I could do specifically to construct all my Swing components within the EDT? Unfortunately the book (Head First Java) didn't talk about Event Dispatch Threads for GUI applications, and while I can understand why this is creating troubles (due to the single threaded nature of GUI operations in Swing), I am unsure about which part of my code is using the EDT and which part is running in some other thread that is causing conflicts.

I am trying to read through the Swing tutorials on the oracle website, but I'm still confused at the moment. Perhaps I will understand things more clearly once I have read a different reference book and spent some more time on this, but I would really appreciate some specific help/outline for what would fix my current code in the mean time. Thanks a lot!
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18564
    
    8

Following on from what Ranganathan Kaliyur Mannar said, you are overriding the getX() and getY() methods of JButton. The documentation for the getX method says
Returns the current x coordinate of the component's origin.

And like Darryl Burke said, you shouldn't be doing that. Especially since your buttons are already in that GridLayout which is supposed to be controlling the location of the buttons. So call those methods something else.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Hooray! Thanks so much Paul, Darryl and Ranga! :-)

Paul, that helped clarify what Ranga mentioned. I didn't realize that getX() and getY() were defined methods that I was overriding. I renamed the methods and instance variables x & y and it is working perfectly now. Also, to clear up the confusion, I am indeed using the Grid Layout manager for arranging the buttons. My getX() and getY() methods were intended as a means of getting the grid position of the button on my tic-tac-toe grid, not the actual co-ordinates of the button. In any case, I've decided to refine my code and get rid of these methods and instance variables as they are unnecessary.

While I'mglad to have this resolved, I'm curious as to why overriding the getX() and getY() was causing this issue? As I understand method overriding, since I am calling these methods on the CNButton objects, the overriding getX() and getY() method that I defined in CNButton should be the one to be called. It seems that this is indeed the case because the program was working correctly (apart from the buttons needing to be moused over for display) even when I had the getX() and getY() methods in Class CNButton. Why would changing the name of these methods to prevent method overriding from occuring resolve this issue? Is it some subtlety involving which threads are used to call these methods in the two scenarios?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18564
    
    8

Something deep down in the Swing code will have been calling getX() to find out where the x-coordinate of your component is located. You overrode that method to return the wrong information. That would lead to problems in displaying your component. Which is what you observed, no?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18564
    
    8

Ryan Sykes wrote:In any case, I've decided to refine my code and get rid of these methods and instance variables as they are unnecessary.


In fact, as far as I can see your action listener doesn't care much about which button was clicked. What I mean to say is, it doesn't care whether it's the button in row 1, column 3 or the button in row 2, column 2 -- it does the same regardless. So you don't need a separate action listener for each button, you can get away with a single action listener which you attach to all of the buttons.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Paul, forgive me if I sound dense. I just want to make sure I truly understand why this is happening so I can avoid similar mistakes in the future.

If I understand what you wrote correctly, you're saying that even though my code itself is not explicitly calling getX() or getY(), the Swing code is probably calling those methods deep down somewhere when initializing the main JFrame for displaying all the GUI elements and that is what is causing the conflict and issue? That makes sense to me now. I was not considering what Swing methods are being called in the background unbeknownst to me.

That must still imply that the Swing code was calling getX() and getY() on the CNButton object and not a parent object, as the latter case would result in a call to the original JComponent getX() and getY() methods? Does that sound correct? (I'm just trying to make sure I have understood method overriding and inheritance correctly)

Thanks a ton! I'm definitely going to be scouring the Java docs for any naming conflicts when writing any future code.

Edit -

Paul Clapham wrote:
Ryan Sykes wrote:In any case, I've decided to refine my code and get rid of these methods and instance variables as they are unnecessary.


In fact, as far as I can see your action listener doesn't care much about which button was clicked. What I mean to say is, it doesn't care whether it's the button in row 1, column 3 or the button in row 2, column 2 -- it does the same regardless. So you don't need a separate action listener for each button, you can get away with a single action listener which you attach to all of the buttons.


That is an excellent point Paul. Thanks for pointing that out. I will try to change that so I have a single listener for all buttons.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18564
    
    8

Ryan Sykes wrote:That must still imply that the Swing code was calling getX() and getY() on the CNButton object and not a parent object, as the latter case would result in a call to the original JComponent getX() and getY() methods? Does that sound correct? (I'm just trying to make sure I have understood method overriding and inheritance correctly)


Well, yeah. That's how inheritance and polymorphism work. There's no such thing as a "parent object" anyway -- your CNButton is a JButton, there isn't some separate hidden JButton when you create a CNButton. There's only one object, which is a CNButton and is a JButton and is a JComponent and is whatever other classes are in the inheritance chain.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Perfect. Yes, that was silly of me, and now that I think about it, it all makes sense :-). Thanks a ton for all your help!
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4540
    
    5

Ryan Sykes wrote:Hi Darryl. Thanks for your reply. Could you help me out a bit further by pointing out what I could do specifically to construct all my Swing components within the EDT?

You're welcome.

Search this forum for SwingUtilities.invokeLater and you'll find plenty of examples. To further your understanding, go through the tutorial on Concurrency in Swing.
Ryan Sykes
Ranch Hand

Joined: Jan 18, 2012
Posts: 58
Darryl Burke wrote:
Ryan Sykes wrote:Hi Darryl. Thanks for your reply. Could you help me out a bit further by pointing out what I could do specifically to construct all my Swing components within the EDT?

You're welcome.

Search this forum for SwingUtilities.invokeLater and you'll find plenty of examples. To further your understanding, go through the tutorial on Concurrency in Swing.

Thanks Darryl. I already have that page bookmarked and will try to go through it over the weekend :-).
Nick Christensen
Greenhorn

Joined: Nov 09, 2013
Posts: 1
Not meaning to resurrect a dead thread, but I just wanted to post my thanks to Paul, Ranganathan and Ryan. I was doing some googling around to find this annoying bug and this eventually came up. This was EXACTLY my problem. I extended JButton, added int variable x and y members, added getX() and getY() member functions. Once I changed these, the problem vanished I did this because the location of the button in respect to the grid/array was all the information I needed. I decided it was worth creating an account just to post my thanks and I too should read through some of this material.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38765
    
  23
Welcome to the Ranch
It shows that old posts are still useful.
harinath kanchu
Greenhorn

Joined: Jun 06, 2014
Posts: 2
hi everyone ,
i got the same problem today, I searched in web and i got this question here , but i didn't get answer to my question
actually i am working with netbeans ide and this is my code snippet i added for generating a new button and text filed in my gui

private void addActionPerformed(java.awt.event.ActionEvent evt) {

javax.swing.JTextField jt;
javax.swing.JButton bs;
jt = new javax.swing.JTextField("text field");

bs = new javax.swing.JButton("new button");
bs.setLocation(100,200);
bs.setSize(150,50);

jt.setLocation(100, 120);
jt.setSize(60,60);
panel.add(jt);
panel.add(bs);
panel.revalidate();
validate();
panel.setVisible(true);
}


but i my new button is not visible until mouse is moved on it.......

according to the previous answers given by someone i tried to check whether i am overridding anything but i am not but why this is happening in my code
please help
thanks in advance
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38765
    
  23
Welcome to the Ranch

Don't use set size or set position methods except on top‑level containers. Use a layout manager.
Don't use a listener to add or remove components. Add them in the constructor, initGUI method or similar.
You probably don't need validate or revalidate then.
harinath kanchu
Greenhorn

Joined: Jun 06, 2014
Posts: 2
THANkS Campbell Ritchie FOR YOUR REPLY,

but according to one of my friends sugussetion I just added one more statement that is "repaint();" at the end of the method and now it is working fine.

I am working with java very recently so i need to improve my conceptual knowledge in java.

anyhow i will consider your sugesstion and will try to improve my code.

this site is helping me well.....
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Buttons not displaying till I mouseover them?