JButtons not responding

My program extends Canvas (for buffering purposes), I put this into the JFrame’s contentPane and draw everything myself (using the NullRepaintManager from David Brackeen’s book) . I have made several JButtons in a JPanel which I put into the contentPane and then to draw them I call paintContents(g) on the JPanel because for some reason if I call contentPane.paintContents(g) I get a gray screen even though I’ve set setOpaque(false). Everything seems great until I try to use the thing because the buttons don’t respond at all, they don’t even register that the cursor os over them i.e. neither the image icon nor the cursor image change and clicking them doesn’t do anything either.

I’m a bit of a noob so I’m sure it’s something really simple, can anyone help?

Hi,

Well I’m not a specialist of the NullRepaintManager stuff but what I understand is that you draw your buttons yourself and not put them into a component hierarchy.
Since they are not in such a hierarchy you have to write a MouseMotion listener (and a MouseListener), add them to your canvas and perform all the logic and redraw stuff to make your buttons respond tho the events. At least that is what I guess.

I think torquoise is right.
There are more ways to paint swing components manually, check out Commander Keith and mine discussion over this. Unfortunatly there is no universal good solution.

Thing is, the buttons were working perfectly before (drawn by calling paintComponents(g) on my JFrame ) but my program was a JPanel so I had all sorts of issues with things being drawn underneath the JFrame’s title bar and such. The thing is if I try to call the paintComponents() method woth my canvas I get a huge gray block although I can still see my background image around the edges (because the block is slightly smaller than the drawing surface) I don’t know if this bcause of some shortcomings in the canvas class or my coding.

Here’s some code if it helps:



public class MyGame extends Canvas implements Stage
{
	private JFrame gameWindow;
	private JPanel contentPane;
	private JPanel activeLayer;
	private BufferStrategy strategy;


	public MyGame() 
	{
		quitGame = false;
		spriteCache = new SpriteCache();
		gameWindow = new JFrame("Soccer");
		contentPane = (JPanel)gameWindow.getContentPane();
		activeLayer = new JPanel();
		activeLayer.setBounds(0,30,Stage.WIDTH,Stage.HEIGHT);
		activeLayer.setLayout(new FlowLayout(FlowLayout.LEFT));
		setBounds(0,0,Stage.WIDTH,Stage.HEIGHT);
		//Configure the contentPane
		contentPane.setOpaque(false);
		contentPane.setLayout(null);
		contentPane.add(this);
		contentPane.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT));
		//Configure the main Window
		gameWindow.setBounds(0,0,Stage.WIDTH,Stage.HEIGHT);
		gameWindow.setVisible(true);
		gameWindow.addWindowListener( new WindowAdapter() 
		{
			public void windowClosing(WindowEvent e) 
			{
				System.exit(0);
			}
		});
		gameWindow.setResizable(false);
		createBufferStrategy(2);
		strategy = this.getBufferStrategy();
		requestFocus();
		NullRepaintManager.install();
	}


	public void menuSystem()
	{
		Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
	
		MenuManager menuManager = new MenuManager(match, resources.getMenuGraphics());
		activeLayer.setOpaque(false);
		//This returns the JPanel containing the buttons
		activeLayer.add(menuManager.getMenu(0));
		contentPane.setOpaque(false);
		contentPane.add(activeLayer);
		gameWindow.validate();
		boolean doDraw = true;
		while(doDraw)
		{
			g.drawImage((BufferedImage)resources.getMenuGraphics().get(0),0,-29,null);
			menuManager.paintMenu(g);
			activeLayer.paintComponents(g);
			strategy.show();
		}
	
	}


I cut a few methods out of the code because they’re irrelevant and I doubt many people would appreciate reading through 400+ lines.

I thought of something, you maybe didn’t set sizes right. Set size and position to all that matter, container, jbutton and such. Normally when you see that JButton was drawn you know that you put it right in container and that layout manager will process events on it, but this might not be the case since you’re drawing it yourself. I think I had the same problem, read the thread I gave you in my post above, think it’s there.

Woah that was quick, I’m pretty sure that’s not the problem but I’ll try it anyway. I’m really desperate right now. Thanks for the help so far guys.

create a small runnable example of your problem, I’ll look into it then. Don’t forget to include nullrepaintmanager class

You could be starving the AWT event thread (so it doesn’t get a chance to reply) since your rendering loop is very tight. Add a sleep in there to give the AWT thread to respond. This only happens on certain systems (Windows mostly)

Alternatively, what calls menuSystem() - is it called as a response to a button press from somewhere else or something? If so then you’ll be locking the AWT event thread by not returning from menuSystem().

Just guesses, probably way off :frowning:

Thanks for not posting the huge file in a code block, maybe you could attach the java file instead so we could see the whole code.

Kev

I can now add things directly to the contentPane and call contentPane.paintComponents(), it turns out setOpaque(false) didn’t work as I’d expected it to but setBackground(new Color(0f,0f,0f,0f)) (transparent background colour) did the trick, weird (can anyone explain this). No change on the main problem with the buttons though.

KEV
1)I already have a sleep() thingy, I tried different (larger) values but no change.

2)menuSystem() is called by my main method because it simply provides a way of setting a few options before the main game is started i.e. it returns a few objects for game().

KOVA
I’ll make one and upload it for you guys to check but I’ll have to do a bit of editing (there’s a lot of fluff that needs to be cut out).

In fact just out of interest how do you guys make your menus? By this I mean how do you arrange everything and what sort of objects do you use, because I’m starting to think that I’m going about this the wrong way or at least the long way.

you don’t need to cut out anything, it is much simpler just to start new project, create a JFrame with Canvas and then put your rendering code in it. I hope that is what you meant anyway.

About menus… I suck big time on this, not using OO approach at all, I just have a flag in rendering code to see if menu is shown and then draw it. Somewhere (thik on newless clubies) was a discussion about how to handle various game statuses and as I remember many gurus from here agreed on having an object to represent statuses (such as game menu). Read it.

I read somewhere that mixing AWT and Swing is a ‘big no no’ so I decided to ditch the canvas and just use a JPanel, I have to translate my Graphics2D object a few times but at least everything works perfectly now (read a few other peoples threads for pointers). I would’ve liked to use a canvas but hey, what can you do? Thanks for everyone’s help, with any luck you’ll all be playing my first full game very soon.