从子类调用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一个PAppletnew 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元素。 在我的头顶, JTabbedPane
, JSplitPane
, JDesktopPane
/ JInternalFrame
,在JDialog
或JOptionPane
popup高分。
截图
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); } }