I am making a pacman game. The plan is to have a GUI that will show the welcome page and a JButton that reads "Play." After the user presses the "Play" button, it will open a new panel that will have an image that will consist of the instructions. On the instructions panel, there will be a JButton that reads "Continue." This will take the user to a GUI with four JButtons reading "Easy," "Medium," "Hard," and "QUIT." The actionPerformed methods for these buttons have already been coded and it works properly (a new JFrame will open with the corresponding Panel to each level, QUIT will quit the program).
The way I created this is that I made a class called GUIPanel and all the panels will open when the GUIPanel object is instantiated.
After I completed the GUI with the levels, that's when I decided to add the Welcome panel and and Instructions panel. So far, I have written code for the Welcome panel. I added it above the code for the level-buttons.
My problem is that whenever I run it, a frame is created but there is no panel. PLEASE HELP ME!! THIS PROJECT IS DUE TOMORROW.
//*****************************
// GUI : Panel
//
// Updated : May 4th, 2017
//
//*****************************
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
public class GUIPanel extends JPanel
{
private Graphics g;
private BufferedImage buffer;
public GUIPanel()
{
try{
//welcome panel
JPanel welcome = new JPanel();
ImageIcon title = new ImageIcon("welcome.png");
buffer = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
g = buffer.getGraphics();
g.drawImage(title.getImage(), 400, 400, 200, 200, null);
//add button and listener and add onto welcome (JPanel)
JButton play = new JButton("Play");
play.addActionListener(new PlayListener());
welcome.add(play);
}
catch(Exception e){
}
}
private class PlayListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
try{
JFrame playFrame = new JFrame();
//creating the panel
JPanel panel = new JPanel();
add(panel);
/*creating the Easy button which will allow the
user to play the EASY LEVEL of Karelman */
JButton easyButton = new JButton("Easy");
easyButton.setBackground(Color.BLUE);
easyButton.setForeground(Color.WHITE);
easyButton.addActionListener(new EasyListener());
panel.add(easyButton);
/*creating the Medium button which will allow the
user to play the MEDIUM LEVEL of Karelman */
JButton mediumButton = new JButton("Medium");
mediumButton.setBackground(Color.BLUE);
mediumButton.setForeground(Color.WHITE);
mediumButton.addActionListener(new MediumListener());
panel.add(mediumButton);
/*creating the random button which will allow the
user to play the HARD LEVEL of Karelman*/
JButton hardButton = new JButton("Hard");
hardButton.setBackground(Color.BLUE);
hardButton.setForeground(Color.WHITE);
hardButton.addActionListener(new HardListener());
hardButton.setBounds(40, 100, 100, 60);
panel.add(hardButton);
/*creating the quit button for exiting the program*/
JButton quitButton = new JButton("QUIT");
quitButton.setBackground(Color.BLUE);
quitButton.setForeground(Color.WHITE);
quitButton.addActionListener(new QuitListener());
quitButton.setBounds(150, 300, 25, 25);
panel.add(quitButton);
}
catch(Exception i){
}
}
}
/*
EasyListener is attached to the Easy Button
It will open the Easy Level by creating a
new frame which will use Easy Ghosts.
*/
private class EasyListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
try{
JFrame frame = new JFrame("PLAY KARELMAN -- EASY");
frame.setSize(708, 738);
frame.setLocation(350, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//create panel for Easy Level within frame
EasyPanel easy = new EasyPanel();
frame.setContentPane(easy);
}
catch(IOException i){
}
}
}
/*
MediumListener is attached to the Medium Button
It will open the Medium Level by creating a
new frame which will use Medium Ghosts.
*/
private class MediumListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
try{
JFrame frame = new JFrame("PLAY KARELMAN -- MEDIUM");
frame.setSize(708, 738);
frame.setLocation(350, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//create panel for Medium Level within frame
MediumPanel medium = new MediumPanel();
frame.setContentPane(medium);
}
catch(IOException i){
}
}
}
/*
HardListener is attached to the Hard Button
It will open the Hard Level by creating a
new frame which will use Hard Ghosts.
*/
private class HardListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
try{
JFrame frame = new JFrame("PLAY KARELMAN -- HARD");
frame.setSize(708, 738);
frame.setLocation(350, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//create panel for Hard Level within frame
HardPanel hard = new HardPanel();
frame.setContentPane(hard);
}
catch(IOException i){
}
}
}
/*
QuitListener is attached to the Quit Button
It will make a system call to exit the program.
*/
private class QuitListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
}
Related
Having problems creating a custom JButton that is an Image. I had everything working with a normal JButton (like in the comment on the 2nd line) this way I wouldn't have to get an InputStream and start the button has an icon.
The trouble I'm having is that when I pressed the replay button (to play again) the window closes and only one window should pop out (as it happens with a "normal" JButton) but in this case 4-5 windows reopen and I don't know why.
I started thinking it was because the time to get an InputStream and doing ImageIO.read() the game would start and see that the variable running was false and then started reopening windows until it's true but I can't see how to verify that.
Note: I have functions that on ActionPerformed verify if the snake has collided and if so running = false and GameOver() will be called
public class GamePanel extends JPanel implements ActionListener {
JButton replay; //= new JButton("Play Again");
GamePanel() {
...
try {
InputStream is_replay = this.getClass().getResourceAsStream("/Snake/lib/img/playagain.png");
ImageIcon icon = new ImageIcon(ImageIO.read(is_replay));
replay = new JButton(icon);
replay.setBorder(BorderFactory.createEmptyBorder());
replay.setContentAreaFilled(false);
...
} catch (IOException|FontFormatException e) {
e.printStackTrace();
}
this.add(replay);
replay.setVisible(false);
replay.setBounds(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT - 200, 200, 100);
...
startGame();
}
public void startGame() {
spawnApple();
running = true;
timer = new Timer(DELAY, this);
timer.start();
}
public void gameOver(Graphics g) {
...
replay.setVisible(true);
replay.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == replay) {
JComponent comp = (JComponent)e.getSource();
Window win = SwingUtilities.getWindowAncestor(comp);
win.dispose(); //It will close the current window
new GameFrame(); //It will create a new game
}
}
});
}
}
public class GameFrame extends JFrame {
GameFrame() {
JPanel panel = new GamePanel();
this.add(panel);
panel.setLayout(null); //Needed to add components
this.setTitle("Snake Game");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.pack(); //Fit JFrame to the components
this.setVisible(true);
this.setLocationRelativeTo(null);
}
}
public class SnakeGame {
public static void main(String[] args) throws Exception {
new GameFrame();
}
}
"in this case 4-5 windows reopen"
This suggests that you are probably adding multiple ActionListeners to the replay JButton. A new listener is added each time game over method is called, and this is incorrect. I would not add the ActionListener to the button in the game over method but rather add it once where you create the replay button.
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?
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
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);
}
}
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 :).
I have been trying to make a button for my program but for some reason I can't click it.
The program is a space invaders game where the gameplay is, for the most part, implemented. However I have decided to create a main menu, and have gotten stuck on getting to button to fully work.
I have been playing around with it for a while, but every time the user clicks where the button is, nothing happens. There is no animation for holding down the left mouse.
Yet when tab is pressed, the button can be highlighted, and can be pressed with the space space.
Here is my code:
public class Main extends Canvas implements Runnable{
public static void main(String[] args) {
JFrame frame = new JFrame();
final JButton startgamebutton = new JButton("Start Game");
startgamebutton.setBounds(200, 500, 400, 50);
JComponent component = frame.getRootPane();
Main main = new Main();
Container cp = frame.getContentPane();
frame.add(main);
frame.setTitle("Space Invaders");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
cp.add(startgamebutton);
cp.add(main);
main.Start();
startgamebutton.setBounds(200, 500, 400, 50);
startgamebutton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == startgamebutton) {
System.out.println("start button Pressed ");
}}
});
}
}
I'm trying to make a little game that will first show the player a simple login screen where they can enter their name (I will need it later to store their game state info), let them pick a difficulty level etc, and will only show the main game screen once the player has clicked the play button. I'd also like to allow the player to navigate to a (hopefully for them rather large) trophy collection, likewise in what will appear to them to be a new screen.
So far I have a main game window with a grid layout and a game in it that works (Yay for me!). Now I want to add the above functionality.
How do I go about doing this? I don't think I want to go the multiple JFrame route as I only want one icon visible in the taskbar at a time (or would setting their visibility to false effect the icon too?) Do I instead make and destroy layouts or panels or something like that?
What are my options? How can I control what content is being displayed? Especially given my newbie skills?
A simple modal dialog such as a JDialog should work well here. The main GUI which will likely be a JFrame can be invisible when the dialog is called, and then set to visible (assuming that the log-on was successful) once the dialog completes. If the dialog is modal, you'll know exactly when the user has closed the dialog as the code will continue right after the line where you call setVisible(true) on the dialog. Note that the GUI held by a JDialog can be every bit as complex and rich as that held by a JFrame.
Another option is to use one GUI/JFrame but swap views (JPanels) in the main GUI via a CardLayout. This could work quite well and is easy to implement. Check out the CardLayout tutorial for more.
Oh, and welcome to stackoverflow.com!
Here is an example of a Login Dialog as #HovercraftFullOfEels suggested.
Username: stackoverflow Password: stackoverflow
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
public class TestFrame extends JFrame {
private PassWordDialog passDialog;
public TestFrame() {
passDialog = new PassWordDialog(this, true);
passDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new TestFrame();
frame.getContentPane().setBackground(Color.BLACK);
frame.setTitle("Logged In");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
});
}
}
class PassWordDialog extends JDialog {
private final JLabel jlblUsername = new JLabel("Username");
private final JLabel jlblPassword = new JLabel("Password");
private final JTextField jtfUsername = new JTextField(15);
private final JPasswordField jpfPassword = new JPasswordField();
private final JButton jbtOk = new JButton("Login");
private final JButton jbtCancel = new JButton("Cancel");
private final JLabel jlblStatus = new JLabel(" ");
public PassWordDialog() {
this(null, true);
}
public PassWordDialog(final JFrame parent, boolean modal) {
super(parent, modal);
JPanel p3 = new JPanel(new GridLayout(2, 1));
p3.add(jlblUsername);
p3.add(jlblPassword);
JPanel p4 = new JPanel(new GridLayout(2, 1));
p4.add(jtfUsername);
p4.add(jpfPassword);
JPanel p1 = new JPanel();
p1.add(p3);
p1.add(p4);
JPanel p2 = new JPanel();
p2.add(jbtOk);
p2.add(jbtCancel);
JPanel p5 = new JPanel(new BorderLayout());
p5.add(p2, BorderLayout.CENTER);
p5.add(jlblStatus, BorderLayout.NORTH);
jlblStatus.setForeground(Color.RED);
jlblStatus.setHorizontalAlignment(SwingConstants.CENTER);
setLayout(new BorderLayout());
add(p1, BorderLayout.CENTER);
add(p5, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
jbtOk.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (Arrays.equals("stackoverflow".toCharArray(), jpfPassword.getPassword())
&& "stackoverflow".equals(jtfUsername.getText())) {
parent.setVisible(true);
setVisible(false);
} else {
jlblStatus.setText("Invalid username or password");
}
}
});
jbtCancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
parent.dispose();
System.exit(0);
}
});
}
}
I suggest you insert the following code:
JFrame f = new JFrame();
JTextField text = new JTextField(15); //the 15 sets the size of the text field
JPanel p = new JPanel();
JButton b = new JButton("Login");
f.add(p); //so you can add more stuff to the JFrame
f.setSize(250,150);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Insert that when you want to add the stuff in. Next we will add all the stuff to the JPanel:
p.add(text);
p.add(b);
Now we add the ActionListeners to make the JButtons to work:
b.addActionListener(this);
public void actionPerforemed(ActionEvent e)
{
//Get the text of the JTextField
String TEXT = text.getText();
}
Don't forget to import the following if you haven't already:
import java.awt.event*;
import java.awt.*; //Just in case we need it
import java.x.swing.*;
I hope everything i said makes sense, because sometimes i don't (especially when I'm talking coding/Java) All the importing (if you didn't know) goes at the top of your code.
Instead of adding the game directly to JFrame, you can add your content to JPanel (let's call it GamePanel) and add this panel to the frame. Do the same thing for login screen: add all content to JPanel (LoginPanel) and add it to frame. When your game will start, you should do the following:
Add LoginPanel to frame
Get user input and load it's details
Add GamePanel and destroy LoginPanel (since it will be quite fast to re-create new one, so you don't need to keep it memory).
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?
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
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);
}
}
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 :).