Calling awt Frame methods from subclass

Solution 1:

What needs to happen when mousePressed == ebtn is all the stuff in the Frame will be removed and a Highscores Screen will be loaded

The demo. below of a nested CardLayout adds an ActionListener instead of a MouseListener. It reacts to both mouse and keyboard input.

There are a multitude of other ways to include more than one GUI element in the same screen space. Off the top of my head, JTabbedPane, JSplitPane, JDesktopPane/JInternalFrame, popping the high scores in a JDialog or JOptionPane..

Screenshots

Game viewHigh Scores view

CardLayoutDemo.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class CardLayoutDemo {

    public static void main(String[] args) {

        Runnable r = new Runnable () {
            public void run() {
                final JRadioButton game = new JRadioButton("Game", true);
                JRadioButton highScores = new JRadioButton("High Scores");

                ButtonGroup bg = new ButtonGroup();
                bg.add( game );
                bg.add( highScores );

                JPanel buttons = new JPanel(new 
                    FlowLayout(FlowLayout.CENTER, 5, 5));
                buttons.add( game );
                buttons.add( highScores );

                JPanel gui = new JPanel(new BorderLayout(5,5));
                gui.add(buttons, BorderLayout.SOUTH);

                final CardLayout cl = new CardLayout();
                final JPanel cards = new JPanel(cl);
                gui.add(cards);
                cards.add(new JLabel("Level 1"), "game");
                cards.add(new JLabel("High Scores"), "scores");

                ActionListener al = new ActionListener(){
                    public void actionPerformed(ActionEvent ae) {
                        if (game.isSelected()) {
                            cl.show(cards, "game");
                        } else {
                            cl.show(cards, "scores");
                        }
                    }
                };
                game.addActionListener(al);
                highScores.addActionListener(al);

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Solution 2:

In order to answer How to call the Frame methods from the PApplet?, I have modified your code snippet to bare minimum. In this modified version when the user click mouse button a System.out is fired.

Now there are two ways in which you can access your Frame object. But before that let me state these two points:

  • When you create a PApplet like new ExampleFrame(new Menu()); and add it in your JFrame like this add(app, BorderLayout.CENTER); then a complex hierarchy of windows/panels are created.

Like this:

javax.swing.JPanel
    javax.swing.JLayeredPane
        javax.swing.JRootPane
            test.ExampleFrame
  • PApplet provides a public field for setting and accessing your frame object. And amazingly it is called frame :). You can set it before calling app.init();

>>Code

** Checkout the comments in the code**

Modified ExampleFrame.java

import java.awt.BorderLayout;    
import javax.swing.JFrame;    
import processing.core.PApplet;

public class ExampleFrame extends JFrame
{
    private static final long serialVersionUID = 4792534036194728580L;
    PApplet app;

    public ExampleFrame(PApplet emApp)
    {
        super("Ball Maze Game");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocation(200, 200);

        app = emApp;
        setSize(615,438);
        setVisible(true);

        setLayout(new BorderLayout());

        add(app, BorderLayout.CENTER);

        // Setting my frame object
        app.frame = this;       
        app.init();
    }

    // Sample Method
    public void sampleMethod(String msg)
    {
        System.out.println("I think '"+ msg +"' called me !!");
    }
}

Modified Menu.java

import java.awt.Container;

import processing.core.PApplet;
import processing.core.PImage;

public class Menu extends PApplet
{
    private static final long serialVersionUID = -6557167654705489372L;

    PImage background;
    static String tab = "";

    //simple constructor
    public Menu()
    {

    }

    public void setup()
    {
        size(600, 400);
        smooth();

        background = loadImage("C:/temp/background.jpg");
    }

    public void draw()
    {
        image(background, 0, 0);
    }

    public void mousePressed()
    {
        Container p = getParent();
        tab = "";

        // FIRST WAY OF ACCESSING PARENT FRAME
        while(p != null)
        {
            //printParentTree(p);
            if(p instanceof ExampleFrame)
            {
                ExampleFrame myframe = (ExampleFrame)p;
                myframe.sampleMethod("First Way");
                break;
            }
            p = p.getParent();
        }

        // SECOND WAY OF ACCESSING PARENT FRAME     
        if(frame != null && (frame instanceof ExampleFrame))
        {
            ExampleFrame myframe = (ExampleFrame)p;
            myframe.sampleMethod("Second Way");
        }
    }

    void printParentTree(Container p) 
    {
        System.out.println(tab+p.getClass().getName());
        tab +='\t';
    }
}

Checkout the public void mousePressed() method.

For completeness, I am also including Main.java.

public class Main {
    public static void main(String[] args){
        new ExampleFrame(new Menu());
    }
}

Now to answer Remove all PApplets contents and load another PApplet in

Well I have not tested it. But you can add a JPanel to your JApplet and do all your drawing on that i.e creating child controls etc. When feel like redrawing then call JPanel.removeAll(). Which as per javadoc:

Removes all the components from this container. This method also notifies the layout manager to remove the components from this container's layout via the removeLayoutComponent method.

After this call repaint on the JPanel. Try it out, it might work :).