Llamando a awt Métodos de cuadro de la subclase

Esta pregunta es sobre Marcos, Java y Procesamiento .

Esta pregunta suena bastante intrincada, pero en realidad no es así. Trataré de mantener esto en un mínimo simple. Estoy creando una pequeña bola en un juego de laberinto para entender mi física y renderizar. Ha sido una buena experiencia hasta el momento, pero he golpeado un poco de una pared de ladrillos.
El diseño general que decidí era contener PApleplets dentro de un Marco AWT y cerrar el Marco. La razón de esto es porque me dijeron que solo debería tener instancias de un Papplet a la vez.

PApplet es la clase Applet en Processing , una biblioteca de renderizado.

Tengo 3 clases aquí, incluida la principal

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

la clase exampleFrame

 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(); } } 

el principal

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

Lo que debe suceder cuando mousePressed == ebtn es que todas las cosas en Frame se eliminarán y se cargará una pantalla de Highscores. las puntuaciones altas son casi las mismas que en el menú. No hay necesidad de publicar código ya que aquí hay suficiente.

La segunda clase es la que actúa como un marco y contiene el PApplet

En pocas palabras, ¿alguien tiene alguna idea de cómo llamar a los métodos Frame desde el PApplet u otra forma de eliminar todos los contenidos de PApplets y cargar otro PApplet?

Para responder a cómo llamar a los métodos Frame desde PApplet? , Modifiqué tu fragmento de código al mínimo. En esta versión modificada, cuando el usuario hace clic en el botón del mouse, se System.out un System.out .

Ahora hay dos formas en que puede acceder a su objeto Frame . Pero antes de eso permítanme decir estos dos puntos:

  • Cuando crea un PApplet como new ExampleFrame(new Menu()); y add(app, BorderLayout.CENTER); en tu JFrame como este add(app, BorderLayout.CENTER); luego se crea una jerarquía compleja de ventanas / paneles.

Me gusta esto:

 javax.swing.JPanel javax.swing.JLayeredPane javax.swing.JRootPane test.ExampleFrame 
  • PApplet proporciona un campo público para configurar y acceder a su objeto de marco. Y sorprendentemente se llama frame :). Puede configurarlo antes de llamar a app.init();

>> Código

** Verifique los comentarios en el código **

Modificado 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 !!"); } } 

Menu.java modificado

 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'; } } 

public void mousePressed() método public void mousePressed() .

Para completar, también estoy incluyendo Main.java.

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

Ahora para responder Elimine todos los contenidos de PAplets y cargue otro PApplet en

Bueno, no lo he probado. Pero puedes agregar un JPanel a tu JApplet y hacer todos tus dibujos sobre eso, es decir, crear controles secundarios, etc. Cuando te JPanel.removeAll() redibujar, llama a JPanel.removeAll() . Que según javadoc:

Elimina todos los componentes de este contenedor. Este método también notifica al administrador de disposición que elimine los componentes del diseño de este contenedor a través del método removeLayoutComponent.

Después de esta llamada JPanel en JPanel . Pruébelo, podría funcionar :).

Lo que debe suceder cuando mousePressed == ebtn es todo lo que se eliminará en el Frame y se cargará una pantalla de Highscores

La demo debajo de un CardLayout nested se agrega un ActionListener lugar de un MouseListener . Reacciona a la entrada del mouse y del teclado.

Hay una multitud de otras formas de incluir más de un elemento GUI en el mismo espacio de pantalla. Fuera de mi cabeza, JTabbedPane , JSplitPane , JDesktopPane / JInternalFrame , apareciendo los puntajes más altos en un JDialog o JOptionPane .

Capturas de pantalla

Vista del juegoVista de puntajes altos

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