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

时间:2015-11-19 12:52:53

标签: java multithreading class oop

I'm brand new to Java and have only recently learnt about object oriented programming. 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).

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.

Thanks.

1 个答案:

答案 0 :(得分:1)

你基本上做的是:

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

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

当你创建一个新的Display时,构造函数会创建一个新的Simulation Display,它会创建一个Simulation,它会创建Display一个SimulationDisplay,它会创建一个新的Simulation ... *

所以不要。您Simulation没有理由成为展示广告并拥有另一个Simulation。如果你希望Display中的所有控件都定义一个构造函数,它将Simulation作为参数显示,并在创建它时给它一个模拟:

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

class Simulation {
}

...

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

*如果您想了解更多信息,我建议您google获取有关继承的教程。这里有tutorial from oracle来帮助您入门:"您可以编写一个子类构造函数来调用超类的构造函数,隐式或使用关键字super。" 在您的代码示例中,隐式调用构造函数super()