从子类调用awt框架方法

这个问题是关于框架,Java和处理 。

这个问题听起来很复杂,但实际上并非如此。 我会尽量保持这个简单的最低限度。 我正在迷宫游戏中创build一个小球,让我的脑袋围绕着物理和渲染。 到目前为止,这是一个很好的经验,但我碰到了一堵砖墙。
我决定的总体布局是在AWT框架内包含PApplet,并closures框架。 原因是因为我被告知你一次只能有一个Papplet的实例。

PApplet是Processing (一个渲染库)中的Applet类。

这里有三个class,其中包括主class

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

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

主要的

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

当mousePressed == ebtn是框架中的所有东西都将被删除,并且高分屏幕将被加载。 高分几乎与菜单相同。 没有必要发布代码,因为这里有足够的。

第二类是作为框架并持有PApplet的类

底线,有任何人有任何想法如何从PApplet调用框架方法或另一种方式来删除所有的PApplets内容并加载另一个PApplet?

为了回答如何从PApplet调用框架方法? ,我修改了你的代码片段到最低限度。 在这个修改版本中,当用户点击鼠标button时,一个System.out被触发。

现在有两种方法可以访问你的Frame对象。 但在此之前,让我说出这两点:

  • 当你像new ExampleFrame(new Menu());一样创build一个PApplet new ExampleFrame(new Menu()); 并添加到您的JFrame像这样add(app, BorderLayout.CENTER); 那么创build一个复杂的窗口/面板层次结构。

喜欢这个:

 javax.swing.JPanel javax.swing.JLayeredPane javax.swing.JRootPane test.ExampleFrame 
  • PApplet提供了一个公共字段来设置和访问您的框架对象。 而令人惊讶的是它被称为frame :)。 你可以在调用app.init();之前设置它app.init();

>>代码

**检出代码中的注释**

修改了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

 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()方法。

为了完整性,我也包括Main.java。

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

现在回答删除所有PApplet内容并加载另一个PApplet

那么我没有testing它。 但是你可以添加一个JPanel到你的JApplet并且完成所有的绘图工作,比如创build子控件等。当重新绘制时,调用JPanel.removeAll() 。 根据javadoc:

删除此容器中的所有组件。 此方法还会通知布局pipe理器通过removeLayoutComponent方法从此容器的布局中移除组件。

JPanel上调用这个repaint调用之后。 试试看,它可能会工作:)。

当mousePressed == ebtn是框架中的所有东西将被删除,并将加载高分屏幕

演示。 在嵌套的CardLayout下面添加一个ActionListener而不是MouseListener 。 它对鼠标键盘input都有反应。

在同一个屏幕空间中,还有许多其他方法可以包含多个GUI元素。 在我的头顶, JTabbedPaneJSplitPaneJDesktopPane / JInternalFrame ,在JDialogJOptionPanepopup高分。

截图

游戏视图高分数视图

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