从子类调用 awt Frame 方法 [英] Calling awt Frame methods from subclass

查看:35
本文介绍了从子类调用 awt Frame 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是关于框架、Java 和处理.

This question is about Frames, Java and Processing.

这个问题听起来很复杂,但事实并非如此.我会尽量把它保持在一个简单的最低限度.我正在迷宫游戏中创建一个小球,以了解物理和渲染.到目前为止,这是一次不错的体验,但我碰到了一些砖墙.
我决定的一般布局是在 AWT 框架中包含 PApplet 并关闭框架.这样做的原因是因为有人告诉我,您一次只能拥有一个 Papplet 实例.

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.

PAppletProcessing 中的 Applet 类,一个渲染库.

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

我这里有 3 个课程,包括主课程

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

exampleFrame 类

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

主要

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

当 mousePressed == ebtn 时需要发生的事情是框架中的所有内容都将被删除并加载一个高分屏幕.高分几乎与菜单相同.不需要贴代码,这里已经足够了.

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.

第二个类是作为框架并保存 PApplet 的类

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

最重要的是,有没有人知道如何从 PApplet 调用 Frame 方法或以其他方式删除所有 PApplet 内容并加载另一个 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?

推荐答案

为了回答如何从 PApplet 调用 Frame 方法?,我已将您的代码片段修改为最低限度.在这个修改后的版本中,当用户单击鼠标按钮时,会触发 System.out.

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.

现在有两种方法可以访问您的 Frame 对象.但在此之前,让我先说明以下两点:

Now there are two ways in which you can access your Frame object. But before that let me state these two points:

  • 当你创建一个像 new ExampleFrame(new Menu()); 的 PApplet 并将它添加到你的 JFrame 中时,像这样 add(app, BorderLayout.CENTER); 然后创建一个复杂的窗口/面板层次结构.
  • 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.

像这样:

javax.swing.JPanel
    javax.swing.JLayeredPane
        javax.swing.JRootPane
            test.ExampleFrame

  • PApplet 提供了一个公共字段,用于设置和访问您的框架对象.令人惊讶的是,它被称为 frame :).你可以在调用之前设置它 app.init();
    • 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();
    • >>代码

      ** 查看代码中的注释**

      ** Checkout the comments in the code**

      修改后的 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.

      For completeness, I am also including Main.java.

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

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

      好吧,我还没有测试过.但是您可以将 JPanel 添加到您的 JApplet 并在其上进行所有绘图,即创建子控件等.当想要重新绘制时,请调用 JPanel.removeAll().根据 javadoc:

      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:

      从这里删除所有组件容器.这个方法也通知布局管理器删除来自这个容器的组件通过 removeLayoutComponent 进行布局方法.

      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.

      JPanel 上调用 repaint 之后.试试看,它可能会奏效:)

      After this call repaint on the JPanel. Try it out, it might work :).

      这篇关于从子类调用 awt Frame 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆