Calling awt Frame methods from subclass

OVERTONE picture OVERTONE · Apr 14, 2011 · Viewed 21.3k times · Source

This question is about Frames, Java and Processing.

This questions sounds pretty convoluted but its really not. I'll try keep this to a simple minimum. I'm creating a small ball in a maze game to get my head around physics and rendering. It's been a good experience so far but I've hit a bit of a brick wall.
The general layout I decided on was to contain PApplets within a AWT Frame and have the Frame close. The reason for this is because I was told that you should only have on instance of a Papplet at a time.

PApplet is the Applet class in Processing, a rendering library.

I have 3 classes here including the main

public class Menu extends PApplet
{
//images and buttons 
PImage background, playbtn1, playbtn2, hsbtn1, hsbtn2, abbtn1, abbtn2, exbtn1,     exbtn2;
FBox pBtn, hBtn, eBtn;

FWorld menu;

//simple constructor
public Menu()
{

}

public void setup()
{
    size(600, 400);
    smooth();
    Fisica.init(this);
    menu = new FWorld();

    //loading and placing images
    background = loadImage("MenuAlt.jpg");
    System.out.println(background);
    playbtn1 = loadImage("play1.gif");
    playbtn2 = loadImage("play2.gif");
    hsbtn1 = loadImage("high1.gif");
    hsbtn2 = loadImage("high2.gif");
    exbtn1 = loadImage("exit1.gif");
    exbtn2 = loadImage("exit2.gif");

    //loading and placing buttons
    pBtn = new FBox(120, 150);
    pBtn.setPosition(135, 215);
    pBtn.setDrawable(false);
    hBtn = new FBox(120, 150);
    hBtn.setPosition(295, 215);
    hBtn.setDrawable(false);
    eBtn = new FBox(120, 150);
    eBtn.setPosition(455, 215);
    eBtn.setDrawable(false);

    //add item to world
    menu.add(pBtn);
    menu.add(hBtn);
    menu.add(eBtn);
}

public void draw()
{
    image(background, 0, 0);
    image(playbtn1, 80, 140);
    image(hsbtn1, 237, 135);
    image(exbtn1, 400, 140);

    mouseOver();
    menu.draw();
}

//close this frame an open a new level, high score or exit
//depending on what the use clicks
public void mousePressed()
{
    FBody pressed = menu.getBody(mouseX, mouseY);
    if (pressed == pBtn)
    {
        System.out.println("play game");
        this.getParent().getParent().getParent().getParent().setVisible(false);

        ExampleFrame x = new ExampleFrame(new Level("level1.txt"));
        x.setLocation(this.getParent().getParent().getParent().getParent().getLocation());
    }
    if (pressed == hBtn)
    {
        System.out.println("high scores");
        this.getParent().getParent().getParent().getParent().setVisible(false);

        /* these are just for finding the parent
 System.out.println(this.getName());
 System.out.println(this.getParent().getName());
 System.out.println(this.getParent().getParent().getName());
 System.out.println(this.getParent().getParent().getParent().getName());
 System.out.println(this.getParent().getParent().getParent().getParent().getName());
         */
        ExampleFrame x = new ExampleFrame(new HighScores()); //for testing, you can change this to new menu()
        x.setLocation(this.getParent().getParent().getParent().getParent().getLocation());
    }
    if (pressed == eBtn)
    {
        System.out.println("exit");
        System.exit(0);
    }
}

the exampleFrame class

public class ExampleFrame extends JFrame
{
    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);
        app.init();
    }
}

the main

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

What needs to happen when mousePressed == ebtn is all the stuff in the Frame will be removed and a Highscores Screen will be loaded. highscores is almost the same as menu. There is no need to post code as there is enough here.

The second class is the one which acts as a frame and holds the PApplet

Bottom line, has anyone have any idea how to call the Frame methods from the PApplet or another way to remove all PApplets contents and load another PApplet in?

Answer

Andrew Thompson picture Andrew Thompson · Apr 26, 2011

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 view High 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);
    }
}