简体   繁体   English

如何正确设置能够运行模拟的画布

[英]How do I correctly set up canvas capable on running a simulation

I'm brand new to Java and have only recently learnt about object oriented programming.我是 Java 的新手,最近才了解面向对象的编程。 I'm trying to create a program which can run a simulation, the general idea is that I want a part of the screen dedicated to buttons/sliders and another part to be dedicated the the Canvas running the simulation.我正在尝试创建一个可以运行模拟的程序,一般的想法是我希望屏幕的一部分专用于按钮/滑块,另一部分专用于运行模拟的画布。 For now I'm not worried about the simulation itself, I'm just trying to get some graphics on the canvas (which is smaller than the JFrame).现在我并不担心模拟本身,我只是想在画布上获得一些图形(比 JFrame 小)。

Here is my code (I'll try to leave some explanation below it)这是我的代码(我会尽量在下面留下一些解释)

public class Launcher {

    public static void main(String[] args){

        Display display = new Display();

    }

}

. .

import java.awt.*;
import javax.swing.*;

public class Display {

    public final int width = 1280, height = 720;
    public final int cwidth = 894, cheight = 504;
    public final String title = "Mechancis Simulator";
    private JFrame frame;
    //private JPanel panel;
    private Canvas canvas;
    private Simulation simulation;

    public Display(){

        initDisplay();

        simulation = new Simulation();

    }

    private void initDisplay(){

        frame = new JFrame(title);
        frame.setSize(width, height);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        /*panel = new JPanel();
        panel.setSize(width, height);
        panel.setLocation(0,0); */

        canvas = new Canvas();
        canvas.setPreferredSize(new Dimension(cwidth, cheight));
        canvas.setMaximumSize(new Dimension(cwidth, cheight));
        canvas.setMinimumSize(new Dimension(cwidth, cheight));
        canvas.setLocation(width - (cwidth +15), 15);

        //panel.add(canvas);
        frame.add(canvas);

        /* Add code for buttons/sliders/boxes here */

        /* Add these to panel */

    }

    public JFrame getFrame(){
        return frame;
    }

    public Canvas getCanvas(){
        return canvas;
    }

}

. .

import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.*;
import javax.swing.*;

public class Simulation extends Display implements Runnable {

    private boolean running = false;
    private Thread thread;

    private BufferStrategy bs;
    private Graphics g;

    public Simulation(){

    }

    private void init(){

    }

    private void tick(){

    }

    private void render(){
        bs = getCanvas().getBufferStrategy();
        if(bs == null){
            getCanvas().createBufferStrategy(3);
            return;
        }
        g = bs.getDrawGraphics();
        //Draw Here!


        //End Drawing!
        bs.show();
        g.dispose();
    }

    public void run(){

        init();

        while(running){
            tick();
            render();
        }

        stop();

    }

    public synchronized void start(){
        if(running)
            return;
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public synchronized void stop(){
        if(!running)
            return;
        running = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

When I run the program the window starts going crazy.当我运行程序时,窗口开始变得疯狂。 I'm quite new to classes and threading so maybe that is the problem.我对类和线程很陌生,所以也许这就是问题所在。 I just want to be able to run the simulation after setting up Frame and Canvas in the Display object.我只是希望能够在 Display 对象中设置 Frame 和 Canvas 后运行模拟。

Thanks.谢谢。

What you're doing basically is this:你在做什么基本上是这样的:

class Display {
    private final Simulation sim;
    public Display() { sim = new Simulation(); }
}

class Simulation extends Display {
    public Simulation() { }
}

when you create a new Display the constructor creates a new Simulation which is a Display which creates a new Simulation which is a Display which creates a new Simulation which is a Display which creates a new Simulation ...*当您创建一个新的Display ,构造函数会创建一个新的Simulation ,它是一个Display ,它创建一个新的Simulation ,它是一个Display ,它创建一个新的Simulation ,它是一个Display ,它创建一个新的Simulation ...*

So don't.所以不要。 There's no reason for your Simulation to be a display and to own another Simulation .您的Simulation没有理由成为显示器并拥有另一个Simulation If you want all the control in Display define a constructor that takes as an argument the Simulation it's displaying and give it a simulation when you create it:如果您希望Display所有控件定义一个构造函数,该构造函数将其显示的Simulation作为参数,并在创建时为其提供模拟:

class Display {
    private final Simulation sim;
    public Display(Simulation sim) { this.sim = sim; }
}

class Simulation {
}

...

Display display = new Display(new Simulation());

*I suggest you google for a tutorial on inheritance, if you wish to know more. *如果你想了解更多,我建议你谷歌搜索关于继承的教程。 Here's the tutorial from oracle to get you started: "You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super."以下是oracle 的入门教程“您可以编写一个子类构造函数,以隐式或使用关键字 super 调用超类的构造函数。” In your code example the constructor super() is invoked implicitly.在您的代码示例中,构造函数super()被隐式调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM