Hello everyone :)
I'm learning Java and I'm creating a pong game. There is something I don't understand how to do though. It's how do I make it so that when a button in one panel is pushed, it calls a method in another panel. Let me quickly explain the basics of my program so that question will make any sense:

I have a main class called Pong, which simply creates a frame and adds a panel called PongPanel.

public class PongPanel extends JPanel
{    

    public PongPanel()   
    {

        setLayout (new BorderLayout());
        setPreferredSize (new Dimension(400, 200));        

        game = new GamePanel();
        ButtonPanel buttons = new ButtonPanel();
        
        add(game, BorderLayout.CENTER);
        add(buttons, BorderLayout.SOUTH);

    }

}

The PongPanel, as you can see, creates two more panels, a GamePanel where all the game logic takes place, and a ButtonPanel, where buttons like "New game" and "Switch sides" are found. Inside the GamePanel there is a method called initalizeNewGame(). I want to call this method when the button "New Game" is pushed in the buttonpanel. How do I do that?

Here is the buttonpanel code, the problem is at the bottom:

public class ButtonPanel extends JPanel
{
    private String buttonText = "New Game";
    private JButton button;


    public ButtonPanel()
    {        
                
        button = new JButton(buttonText);
        button.addActionListener(new ButtonListener());
        
        add(button);     

    }

    public void toggleButtonEnabled()
    {
        if (button.isEnabled())
            button.setEnabled(false);
        else
            button.setEnabled(true);
    }

    private class ButtonListener implements ActionListener
    {
        public void actionPerformed (ActionEvent event)
        {
            if (button.isEnabled())                
                    //call initializeNewGame();  <<---- what to write here???                        

        }
    }
 }

I've tried writing GamePanel.initializeNewGame(), game.initalizeNewGame(), to no avail, I seem to be missing something, is it out of scope? Should something somewhere be static? Please help me understand why it won't work or what I should do. Thank you in advance :)

Recommended Answers

All 4 Replies

So... it looks like the 2 parts to your system need to know about each other - or at least ButtonPanel needs to have access to the instance of GamePanel so it can call its methods.
One way is to pass the instance of GamePanel to ButtonPanel in ButtonPanel's constructor. ButtonPanel can then keep a copy of that and use it to call GamePanel's methods

game = new GamePanel();
ButtonPanel buttons = new ButtonPanel(game);
...
public class ButtonPanel...
  private GamePanel game;
  public ButtonPanel(GamePanel game) { 
    this.game = game;
    ...
  }
  ...
  game.initalizeNewGame()

Nice!! That worked liked a charm :) Thank you so much!
If I need GamePanel to call methods in ButtonPanel, will the same trick work?

Kindof... you need to run one constructor to get the object to pass to the other constructor, so the simple version only works for passing one way. You can pass both ways by doing something like

game = new GamePanel();
ButtonPanel buttons = new ButtonPanel(game);
buttons.setGamePanel(game); // need to define this method in ButtonPanel class

ps. This is pushing the boundary of doing things in a single layer - if you had a third panel you would definitely be better off by going to an MVC architecture (or at least VC) where your Panels are the views, and a new Controller class has responsibility for creating all the views and handling all the logic between them. In that case each view class just needs a reference to the controller, not to any of the other views.

Thank you, it's all much clearer now :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.