【问题标题】:Java FX MVC multiple viewsJava FX MVC 多视图
【发布时间】:2019-11-07 20:17:12
【问题描述】:

我正在使用 Java FX(类项目需要),并且我正在努力格式化我的 MVC,以便我可以将多个视图加载到舞台上(各种场景)。我有一个控制器,如下所示,它有 2 个 View1 实例。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.animation.AnimationTimer;

public class Controller extends Application {

public int page = 0;

private View1 view2;
private View1 view1;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage theStage) {
    view1 = new View1(theStage);
    view2 = new View1(theStage);
    new AnimationTimer() {
        public void handle(long currentNanoTime)
        {
            switch (page){
                case 0:
                    view1.update();
                    break;
                case 1:
                    view2.update();
                    break;
                default:
                    page = 0;
            }
            try {
                Thread.sleep(33);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
    theStage.show();
  }

}

问题出现在view2 = new View1(theStage); 行。没有这条线,输出是一个带有背景图像的大画布。但是,使用该行时,没有背景图像,它只是一个空白画布。下面是我的视图,我尽量简化了,只用一张背景图来判断是否加载正确。 (为了保持简洁,我省略了导入,如果需要我可以将它们重新添加)

public class View1 {
Stage theStage;
Group root;
Scene theScene;
Canvas canvas;

// value of the height and width of screen
int canvasWidth = 1000;
int canvasHeight = 800; 

GraphicsContext gc;

Image background;

//View1 constructor initialize the starting position for the image
//Called in controller
public View1(Stage theStage) {


    this.theStage = theStage;
    this.theStage.setTitle("Estuary Game");

    root = new Group();
    theScene = new Scene(root);
    this.theStage.setScene(theScene);

    canvas = new Canvas(canvasWidth, canvasHeight);
    root.getChildren().add(canvas);
    gc = canvas.getGraphicsContext2D();

    background = createImage("assets/mini-game-1.png");
}

//Read image from file and return
private Image createImage(String image_file) {
    Image img = new Image(image_file);
    return img;
}

//method used to repaint on the image and called in controller
public void update() {
    // draw background and sharkMove such like current
    gc.drawImage(background, 0, 0);

}

}

我不确定我是否正确处理了多个视图,我的意图是只有多个场景,但我不确定如何构建它。

【问题讨论】:

    标签: java javafx model-view-controller


    【解决方案1】:

    试试下面的结构(下面的代码是一个文件的mre。复制粘贴到SwitchScene.java然后运行):

    import javafx.animation.AnimationTimer;
    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.image.ImageView;
    import javafx.stage.Stage;
    
    public class SwitchScene extends Application {
    
        public int page = 0;
    
        @Override
        public void start(Stage theStage) {
    
            new Controller(theStage);
            theStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    class Controller {
    
        private final View1 view1,  view2;
        private final Stage stage;
    
        private static final String[] images = {
                "https://findicons.com/files/icons/345/summer/128/cake.png",
                "http://icons.iconarchive.com/icons/atyourservice/service-categories/128/Sweets-icon.png"
        };
    
        Controller(Stage stage) {
            this.stage = stage;
            view1 = new View1(images[0]);
            view2 = new View1(images[1]);
            swapScenes();
        }
    
        void swapScenes(){
    
            new AnimationTimer() {
    
                int page = 2;
                @Override
                public void handle(long currentNanoTime){
                    switch (page){
                        case 2:
                            page = 1;
                            stage.setScene(new Scene(new Group(view1)));
                            break;
                        case 1:
                            page = 2;
                            stage.setScene(new Scene(new Group(view2)));
                            break;
                    }
    
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    }
    
    class View1 extends ImageView {
    
        public View1(String imagePath) {
            super(imagePath);
        }
    }
    

    编辑:使用画布的View1 版本:

    class View1 extends Group {
    
        public View1(String imagePath) {
    
            Image img = new Image(imagePath);
            Canvas canvas = new Canvas(img.getWidth(), img.getHeight());
            GraphicsContext gc = canvas.getGraphicsContext2D();
            gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());
            getChildren().add(canvas);
        }
    }
    

    【讨论】:

    • 非常感谢您的回复。我觉得这与我需要的非常接近,但是,鉴于我需要创建一个画布并且我需要变量 gc (GraphicsContext),因此我可以在屏幕上填充大量项目。如果不将舞台或场景传递给视图,如何做到这一点?
    • 我很高兴它有帮助。 View1 可以是任何Node。例如,它可以是 GroupPane 。您可以让 View1 扩展 Node 并根据您的需要进行修改。
    • 我收到一条错误消息,上面写着Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: View2@7c69d5da[styleClass=root]is already set as root of another scene 我想这可能是因为我一直在实例化一个新场景,但我不确定。
    • 不清楚在什么情况下。您是否正在尝试将相同的根设置为两个场景?如需更多帮助,请发布新问题并附上minimal reproducible example
    • 感谢您的所有帮助,我将解决方案标记为正确,因为这是我需要的。但是,第二张图片没有出现。它在空白屏幕和第一个视图之间波动。
    猜你喜欢
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2018-02-26
    相关资源
    最近更新 更多