🔒 Locked
[java] hideable panel
Advertisement
Original Post
Could someone tell me the best way to have reuseable panels in my game? I have a panel with a START button and some radio buttons for selecting game difficulty. When the game starts I just hide the panel using panel.setVisible(false); but when I'm ready to use the panel again using panel.setVisible(true) the panel doesn't accept input from the mouse like my Listener quit listening. I'll also want to do the same sort of thing for an in-game menu. Can anyone help me out? Thanks kratz
Hi,
I'm not sure why that would not work for you. It appears to work fine when I tried it.
Make sure that you are creating and adding the listeners to the components that you want to be able to receive event messages. Also make sure that the Panel is added to the ContentPane of the JFrame it's supposed to be in.
Hope this helps! If you can't find the problem post some of your code and I'm sure someone will be able to find the problem.
I'm not sure why that would not work for you. It appears to work fine when I tried it.
import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;import java.util.*;public class HiddenPane extends JFrame implements ActionListener { private java.util.Timer tasker = new java.util.Timer(); private JPanel hiddenPane = new JPanel( new FlowLayout() ); public HiddenPane() { super("Hidden Pane Example"); MouseMotionListener mml = new MouseMotionAdapter() { public void mouseMoved( MouseEvent e ) { System.err.println("Mouse Move Over Component Detected"); } }; JButton start = new JButton("Start My Game Man"); JButton gimme = new JButton("Gimme The Money Biotch"); JButton quit = new JButton("Leave This Trash"); start.addActionListener(this); start.addMouseMotionListener(mml); gimme.addActionListener(this); gimme.addMouseMotionListener(mml); quit.addActionListener(this); quit.addMouseMotionListener(mml); hiddenPane.setBorder( new EmptyBorder(100,0,100,0) ); hiddenPane.add(start); hiddenPane.add(gimme); hiddenPane.add(quit); hiddenPane.addMouseMotionListener( new MouseMotionAdapter() { public void mouseMoved( MouseEvent e ) { System.err.println("The Mosue Moved On My Panel"); } } ); getContentPane().add(hiddenPane); hiddenPane.setVisible(false); tasker.schedule( new TimerTask() { public void run() { hiddenPane.setVisible(true); } }, 5000); addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { exit(); } } ); setSize(640,480); setVisible(true); } public static void main( String args[] ) { new HiddenPane(); } public void exit() { setVisible(false); dispose(); tasker.cancel(); System.exit(0); } public void actionPerformed( ActionEvent e ) { String cmd = e.getActionCommand(); if( cmd.compareTo("Start My Game Man") == 0 ) { System.err.println("start"); }else if( cmd.compareTo("Gimme The Money Biotch") == 0 ) { System.err.println("extras"); }else if( cmd.compareTo("Leave This Trash" ) == 0 ) { System.err.println("quit"); exit(); } System.err.println("There was an action trapped"); } }Make sure that you are creating and adding the listeners to the components that you want to be able to receive event messages. Also make sure that the Panel is added to the ContentPane of the JFrame it's supposed to be in.
Hope this helps! If you can't find the problem post some of your code and I'm sure someone will be able to find the problem.
Hey 5minute thanks for your reply. I finally got the beginning menu to work but I have some questions about your code. 1. Is it better to call addListener on everything or does an addListener on the parent JFrame automatically apply to all the visible child components?
2. I read somewhere that in 1.5 that adding to the contentPane is now the same thing as just adding to the parent frame. Is this true or is there an advantage to using getContentPane().add?
I'm still working on the in-game menu without much success at all. I'm addin the panel like this in my setupGUI function
then I show the panel in my renderPaused function like this
well it erases my whole scene THEN shows the panel which is obviously not what I want. I guess I'm just having a hard time understanding how Swing paints things.
Any suggestions?
Thanks
kratz
2. I read somewhere that in 1.5 that adding to the contentPane is now the same thing as just adding to the parent frame. Is this true or is there an advantage to using getContentPane().add?
I'm still working on the in-game menu without much success at all. I'm addin the panel like this in my setupGUI function
inGamePanel = new JPanel(layout); inGamePanel.setSize(75, 75); inGamePanel.setBackground(Color.black); inGamePanel.setVisible(false); quitButton = new JButton("Quit Game"); inGamePanel.add(quitButton); inGamePanel.setLocation(width/2, height/2); this.getContentPane().add(inGamePanel);then I show the panel in my renderPaused function like this
// clear offscreen canvas g.setColor(Color.black); g.fillRect(0, 0, width, HUD_HEIGHT); g.drawImage(background, 0, HUD_HEIGHT, width, height, this); g.setColor(Color.BLUE); g.setFont(scoreFont); g.drawString("PAUSED", width/2-75, height/2); paintAll(g); //Try to show the ingame menu g.dispose(); strategy.show();well it erases my whole scene THEN shows the panel which is obviously not what I want. I guess I'm just having a hard time understanding how Swing paints things.
Any suggestions?
Thanks
kratz
Quote:
Original post by kratz // clear offscreen canvas g.setColor(Color.black); g.fillRect(0, 0, width, HUD_HEIGHT); g.drawImage(background, 0, HUD_HEIGHT, width, height, this); g.setColor(Color.BLUE); g.setFont(scoreFont); g.drawString("PAUSED", width/2-75, height/2); paintAll(g); //Try to show the ingame menu g.dispose(); strategy.show();
well it erases my whole scene THEN shows the panel which is obviously not what I want. I guess I'm just having a hard time understanding how Swing paints things.
Any suggestions?
Thanks
kratz
There was a similar problem in this post: http://www.gamedev.net/community/forums/topic.asp?topic_id=410448
Call paint(g), instead of paintAll(g).
Hi kratz your welcome, glad to help
regarding your questions:
Afaik, you need to add a listener to any component that you want to listen for events from that includes components within containers. Also if you notice in my example the JPanel no longer receives mouseMoved events when you are scrolling over one of the buttons.
Just a word of caution if you use the JFrame.add() function it will compile in earlier version of Java but you will get a runtime error telling you to use the getContentPane(). So if you are compiling for compatibility with older versions of java its better to use getContentPane().add().
I would suggest trying a different approach to in-game menus. Instead of worrying about displaying a panel on top of the current game frame you could create a undecorated JFrame window or subclass JDialog to create a modal dialog box which won't allow the user to change anything until they close the dialog window as long as you set the parent to the JDialog to be the games JFrame there is also a constructor to deal with a different GraphicsConfiguration but I don't know if that is needed. Though it might be for a fullscreen app.
You probably wouldn't have to change much code at all.
Hope that helps.
regarding your questions:
Quote:
1. Is it better to call addListener on everything or does an addListener on the parent JFrame automatically apply to all the visible child components?
Afaik, you need to add a listener to any component that you want to listen for events from that includes components within containers. Also if you notice in my example the JPanel no longer receives mouseMoved events when you are scrolling over one of the buttons.
Quote:Well I did some research into the swing changes in 1.5 and here it is straight from the horses mouth. Of Course this only applies to 1.5 and will only work with the most recent jre. So to be compatible with earlier version of Java I would refrain from using JFrame.add(); and use JFrame.getContentPane().add(). The main reason behind using the getContentPane() was that swing was built on top of java.awt and JFrame was made a subclass of Frame. So I guess they needed a special Panel or something and they used that as the root which voided the Frame.add() function which actually is a convenience function for addImpl(). That method is now shown in the javax.swing.JFrame javadoc as being overridden and uses the ContentPane instead of using the java.awt.Frame implementation of the method which uses java.awt.Frame's built in pane.
2. I read somewhere that in 1.5 that adding to the contentPane is now the same thing as just adding to the parent frame. Is this true or is there an advantage to using getContentPane().add?
Just a word of caution if you use the JFrame.add() function it will compile in earlier version of Java but you will get a runtime error telling you to use the getContentPane(). So if you are compiling for compatibility with older versions of java its better to use getContentPane().add().
Quote:
I'm still working on the in-game menu without much success at all. I'm addin the panel like this in my setupGUI function
...
then I show the panel in my renderPaused function like this
...
well it erases my whole scene THEN shows the panel which is obviously not what I want. I guess I'm just having a hard time understanding how Swing paints things.
Any suggestions?
I would suggest trying a different approach to in-game menus. Instead of worrying about displaying a panel on top of the current game frame you could create a undecorated JFrame window or subclass JDialog to create a modal dialog box which won't allow the user to change anything until they close the dialog window as long as you set the parent to the JDialog to be the games JFrame there is also a constructor to deal with a different GraphicsConfiguration but I don't know if that is needed. Though it might be for a fullscreen app.
You probably wouldn't have to change much code at all.
Hope that helps.
Quote:
Original post by kratz
5Minute thanks for the insights and the suggestion. I think I will give subclassing a JDialog a try and see if I get better results.
Thanks
Kratz
Anytime Kratz and please let us know how things work out.
this is giving me such a headache. Either I'm just a piss-poor programmer or Swing is a convoluted pile of crap.
I decided to try working with a customized JDialog as an in-game menu but I can't even get this to work.
Remembering that I'm in fullscreen exclusive mode, I set up my dialog like this
and here is my continuous loop
Here is the check for Esc key to pause game and show the dialog
this of course is in the keyPressed sub
and lastly here is the entire code for my renderPaused sub
well all of this ALMOST works except when I press escape, the game pauses correctly but the dialog buttons don't show until I wave the mouse over them.
Someone please save me cause I'm ready to smash something.
Kratz
I decided to try working with a customized JDialog as an in-game menu but I can't even get this to work.
Remembering that I'm in fullscreen exclusive mode, I set up my dialog like this
inGamePanel = new JDialog(this);inGamePanel.setVisible(false);inGamePanel.setLayout(layout);inGamePanel.setIgnoreRepaint(true);inGamePanel.setBackground(Color.BLACK);inGamePanel.setPreferredSize(new Dimension(100, 200)); inGamePanel.setSize(inGamePanel.getPreferredSize());inGamePanel.setUndecorated(true);inGamePanel.setResizable(false); inGamePanel.setLocation((width-inGamePanel.getWidth())/2, (height-inGamePanel.getHeight())/2);inGamePanel.add(quitButton);inGamePanel.add(resumeButton);and here is my continuous loop
while(running){ (Graphics2D)strategy.getDrawGraphics();if(manager.isPaused()){ renderPaused(myGraphics); while(manager.isPaused()) Thread.yield(); continue;}//End if //Update sprites //Do regular rendering }//End WhileHere is the check for Esc key to pause game and show the dialog
this of course is in the keyPressed sub
//Check for ESC key to pull up inGameMenu if(e.getKeyCode() == e.VK_ESCAPE) { manager.pause(); inGamePanel.setVisible(true);}//End ifand lastly here is the entire code for my renderPaused sub
private void renderPaused(Graphics2D g){ // clear offscreen canvas g.setColor(Color.black); g.fillRect(0, 0, width, HUD_HEIGHT); g.drawImage(background, 0, HUD_HEIGHT, width, height, null); g.setColor(Color.BLUE); g.setFont(scoreFont); g.drawString("PAUSED", width/2-75, height/2); inGamePanel.paint(inGamePanel.getGraphics()); g.dispose(); strategy.show();}//End renderPausedwell all of this ALMOST works except when I press escape, the game pauses correctly but the dialog buttons don't show until I wave the mouse over them.
Someone please save me cause I'm ready to smash something.
Kratz
Hi Kratz,
I used a tutorial I am working on for an RTS game and added in a JDialog InGame menu. At first I was having the same problem you were with the buttons not showing. But then I looked a little closer and I found the problem. I was using java.awt.Components in a JDialog box. I then switched my buttons from java.awt.Button to javax.swing.JButton and everything worked fine.
Here is my code for the JDialog box.
SimpleRTS is a subclass of JFrame and has its own rendering method. To show the dialog box just use the following line in your main frame:
new InGameDialog( this, true );
Just make sure that you are using ALL SWING COMPONENTS. It's very bad to mix swing and awt. I hope that this can solve the problem your having and also help avoid further problems.
I used a tutorial I am working on for an RTS game and added in a JDialog InGame menu. At first I was having the same problem you were with the buttons not showing. But then I looked a little closer and I found the problem. I was using java.awt.Components in a JDialog box. I then switched my buttons from java.awt.Button to javax.swing.JButton and everything worked fine.
Here is my code for the JDialog box.
import javax.swing.border.*;import java.awt.*;import javax.swing.*;import java.awt.event.*;public class InGameDialog extends JDialog { private SimpleRTS myParent = null; public InGameDialog( SimpleRTS parent, boolean modal ) { super(parent,modal); myParent = parent; setUndecorated(true); setIgnoreRepaint(false);// setAlwaysOnTop(true); setSize(400,300); //center this dialog in the middle of the parent frame int width = parent.getWidth(); int height = parent.getHeight(); Point screenCenter = new Point(width/2,height/2); setLocationRelativeTo(parent); setLocation( new Point( (int)(screenCenter.getX()-getWidth()/2), (int)(screenCenter.getY()-getHeight()/2) ) ); JButton q = new JButton("Quit"); q.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { setVisible(false); dispose(); myParent.cleanup(); System.exit(0); } } ); JButton s = new JButton("Save"); s.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { } } ); JButton l = new JButton("Load"); l.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { } } ); JButton o = new JButton("Options"); o.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { } } ); JButton r = new JButton("Resume"); r.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { setVisible(false); dispose(); } } ); JPanel mid = new JPanel(); mid.setBorder( new EmptyBorder(20,50,20,50) ); mid.setLayout( new GridLayout(6,1) ); mid.add( s ); mid.add( l ); mid.add( o ); mid.add( q ); mid.add( new JSeparator() ); mid.add( r ); getContentPane().setLayout( new BorderLayout() ); getContentPane().add( "Center", mid ); setVisible(true); } }new InGameDialog( this, true );
Just make sure that you are using ALL SWING COMPONENTS. It's very bad to mix swing and awt. I hope that this can solve the problem your having and also help avoid further problems.
Hey 5Minute thanks for the reply. You've been a big help. I think I got it mostly straightened out now. There were several things I was doing wrong. I thought that using setignoreRepaint(true) meant that I had to explicitly call some sort of paint function on my panel when I wanted to show it. So I was trying to paint using a Graphics2D object that I got from my main JFrame which was apparently causing strange behavior. All of this in addition to the fact that I was trying to paoint in the wrong places. Anyways, on to the next brick wall. Again thanks a million for your help.
Kratz
Kratz
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement