5 Replies Latest reply: Mar 8, 2010 6:55 PM by 843853 RSS

    Issue with adding JPanel objects with layout managers

    843853
      Hi. The games I made in the past did not contain any customized menus (ie. not from JOptionPane) different components dividing the display screen... so I thought I would try to on my current game I'm working on. So here's the issue: I'm trying to set the GUI up for the game screen.. but when I try to add in additional JPanel objects into the my main JFrame object, all of the JPanel objects stack up at the very top left corner (their not supposed to because I am using a layout manager). Here's my simplified version of the code:
      public void setUpGame(){
           MainGame game = new MainGame();
                
           game.setLayout(new BoxLayout(game, BoxLayout.Y_AXIS) );
                      
              playPanel = new PlayPanel(); // don't worry about this.. it's a subclass of JPanel.
            playPanel.setPreferredSize( new Dimension(playPanel.width, playPanel.height) );     
              game.add(playPanel);
      
              JPanel collections = new JPanel();
              collections.setLayout(new FlowLayout() );
              collections.setPreferredSize( new Dimension( 1280, 256));
      
              miniMapPanel = new MiniMapPanel(); // subclass of JPanel.
           miniMapPanel.setPreferredSize( new Dimension(miniMapPanel.width, miniMapPanel.height) );
              collections.add(miniMapPanel);
      
              statsPanel = new StatsPanel();
           statsPanel.setPreferredSize( new Dimension(statsPanel.width , statsPanel.height ) );
              collections.add(statsPanel);
      
              ... // I do the same thing for StatsPanel and CommandPanel objects
      
              game.add(collections);
              add(game);
      
              // referencing to the JFrame object
              this.pack(); 
              setVisible(true);
              setFocusable(true);
      }
      Notes:
      -The sum of miniMapPanel.width, statsPanel.width, ... , commandPanel.width add up to 1280 pixels.
      - miniMapPanel.height, statsPanel.height, ... , commandPanel.height all have the same height of 256 pixels.
      - What I'm trying to do is set up a GUI very similar to that of StarCraft, and WarCraft.
      - The game is set up in full screen.

      When I compile the program, I see (and I've tested for it) that all of the JPanel objects that were created are all stacked one on top of each other, in the top left corner of the screen. Any ideas and/or suggestions are welcome.
        • 1. Re: Issue with adding JPanel objects with layout managers
          gimbal2
          Try BorderLayout in stead. Add the playPanel to the BorderLayout.CENTER and add the collections panel to the BorderLayout.PAGE_END.

          LayoutManagers can give unexpected results; basically it is a question of playing around with them until you get a setup that works for you. I generally use BorderLayout as the outer layout manager, then combinations of different layout managers (including other BorderLayout panels) inside it.
          • 2. Re: Issue with adding JPanel objects with layout managers
            843853
            Thanks for the reply. After adjusting my code... I got it to work, but now I'm faced with another (minor) issue.
            When the JFrame is created, I see the playPanel at the center while the other JPanels just beneath it, which is what I want (thanks for your advice). However, I cannot see any of the components that I have created in the other JPanels (miniMapPanel, statsPanel, optionPanel, and commandPanel) (ie. I have created JButtons in the optionPanel and when I run my program, the JButtons are only visible when I move the mouse cursor directly on their locations.

            One possibility is that the repaint methods are constantly being invoked which overwrites the visibility of those components (Although I have nothing being drawn in that area).

            I have another question: If the above is the real reason causing this issue, how do I go about to fixing it? (ie. how do I invoke paint methods for those components onto the JPanel's paint method?)

            Edit: When i invoke methods like
              gamePanel.setBorder(BorderFactory.createLineBorder(Color.black));
              ...
              collections.setBorder(BorderFactory.createLineBorder(Color.black));
              
            How come I don't see the black border lines when the JFrame is created?

            Edited by: weng001 on Mar 6, 2010 5:49 PM
            • 3. Re: Issue with adding JPanel objects with layout managers
              843853
              Hi weng,

              Try the following code example. I think the issue might be in your overridden methods if you did.
                  public static void main(String[] args) {
              
                      JPanel viewPanel = new JPanel();
                      viewPanel.setBackground(Color.GREEN);
                      viewPanel.add(new JLabel("You see a hut here..."));
              
                      JPanel minimapPanel = new JPanel();
                      minimapPanel.setBackground(Color.WHITE);
                      minimapPanel.add(new JLabel("Minimap!"));
              
                      JPanel commandPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
                      commandPanel.add(new JButton("Characters"));
                      commandPanel.add(new JButton("Inventory"));
                      commandPanel.add(new JButton("World Map"));
                      commandPanel.add(new JButton("Menu"));
              
                      JPanel lifeAndManaPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
                      lifeAndManaPanel.add(new JLabel("Life: 999/999"));
                      lifeAndManaPanel.add(new JLabel("Mana: 999/999"));
              
                      JPanel statusPanel = new JPanel(new BorderLayout());
                      statusPanel.add(commandPanel, BorderLayout.PAGE_START);
                      statusPanel.add(lifeAndManaPanel, BorderLayout.CENTER);
              
                      JPanel bottomPanel = new JPanel(new BorderLayout());
                      bottomPanel.add(minimapPanel, BorderLayout.LINE_START);
                      bottomPanel.add(statusPanel, BorderLayout.CENTER);
              
                      JPanel game = new JPanel(new BorderLayout());
                      game.add(viewPanel, BorderLayout.CENTER);
                      game.add(bottomPanel, BorderLayout.PAGE_END);
              
                      JFrame frame = new JFrame();
                      frame.getContentPane().setLayout(new BorderLayout());
                      frame.getContentPane().add(game, BorderLayout.CENTER);
                      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                      frame.setSize(800, 600);
                      frame.setVisible(true);
                  }
              • 4. Re: Issue with adding JPanel objects with layout managers
                gimbal2
                weng001 wrote:

                I have another question: If the above is the real reason causing this issue, how do I go about to fixing it? (ie. how do I invoke paint methods for those components onto the JPanel's paint method?)
                Perhaps you are adding everything when the JFrame is already visible? The generic trick is to create the JFrame, add everything to it and then in the end do a JFrame.pack(); JFrame.setVisible(true); These two calls will do the following:

                - pack() will cause the frame to layout everything (a job done by the layout managers); in this step the sizes and spacings are all determined. One feature of pack() is that it will make the frame fit tightly around the components.

                - setVisible(true) will make the frame visible, and thus cause the entire frame to be painted.



                When you already have a visible constructed frame and you make changes to it, you should call validate() on the frame to make it revalidate all its inner components (alternatively, if you modify one specific panel, you could revalidate() that panel only). The validate() step will make the frame update its internal bookkeeping of the components. Sometimes in rare occasions, you also need to manually call repaint() on the frame or component you changed; if after the update things look wrong, try the repaint() call.

                Alternative to the validate() call is to call pack(), which will again resize the frame to make sure everything fits inside it - as a side-effect everything will be revalidated as well.
                • 5. Re: Issue with adding JPanel objects with layout managers
                  843853
                  Thanks for all of your insightful advice. I have figured out the problem, although it was not necessarily the things you mentioned above. The main problem to my issue was because I have overwritten the paint(Graphics g) method for all of the panel objects. When the repaint() method is called, it removes any of the already create visible components and thus, why I get a blank screen and why the JButtons only showed when my mouse hovered over them. Did a little google search on this and found out I just needed to move all the code in the paint(Graphics g) method into another method called paintComponents(Graphics g). That did the trick. Thanks.. although I'll probably run into another issue in a little while lol.