JavaFX-允许类访问控制器方法以在画布上绘制

JavaFX-允许类访问控制器方法以在画布上绘制,java,model-view-controller,javafx,Java,Model View Controller,Javafx,我的项目中有以下文件: main.java用于启动应用程序 RootLayout.fxml&RootlayoutController.java,作为主舞台,将用于菜单栏 Overview.fxml和OverviewController.java用于应用程序的主窗口 point.java包含应用程序逻辑 OverviewController的test()-方法由按钮的onAction事件触发。 本质上,我正在寻找一种方法,让Point.java类访问OverviewController.jav

我的项目中有以下文件:

  • main.java用于启动应用程序
  • RootLayout.fxml&RootlayoutController.java,作为主舞台,将用于菜单栏
  • Overview.fxml和OverviewController.java用于应用程序的主窗口
  • point.java包含应用程序逻辑
OverviewController的test()-方法由按钮的onAction事件触发。 本质上,我正在寻找一种方法,让Point.java类访问OverviewController.java类,这样它就可以调用相关的drawPoint(双x,双y)方法

我研究这个问题已经有一段时间了,但一直找不到一个可以理解的答案——因为我对JavaFX的了解有点有限

非常感谢您抽出时间回答我的问题

Main.java

    public class Main extends Application {

    public Stage primaryStage;
    private BorderPane rootLayout;

    public Main(){

    }




    @Override
    public void start(Stage primaryStage) throws Exception{

            this.primaryStage = primaryStage;
            this.primaryStage.setTitle("");
            initRootLayout();
            showOverview();

    }

    public void initRootLayout(){
        try {

            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class
                    .getResource("view/RootLayout.fxml"));
            rootLayout = (BorderPane) loader.load();

            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.setHeight(900);
            primaryStage.setWidth(900);

            // Give the controller access to the main app.
            RootLayoutController controller = loader.getController();
            controller.setMainApp(this);

            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
    public void showOverview(){
        try {

            // Load Overview
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class.getResource("view/Overview.fxml"));
            AnchorPane overview = (AnchorPane) loader.load();

            // Set overview into the center of root layout.
            rootLayout.setCenter(overview);

            // Give the controller access to the main app.
            OverviewController controller = loader.getController();
            controller.setMainApp(this);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

   public class OverviewController {

       private sample.Main Main;

       public void setMainApp(Main mainApp) {
           this.Main = mainApp;
       }

       @FXML
       Canvas canvas;

       public void test(){
         Point point = new Point(5,5);
         point.drawPoint();
       }

       public void draw(double x, double y){

         GraphicsContext gc = canvas.getGraphicsContext2D();
         gc.setFill(Color.rgb(255, 0, 0));
         gc.fillOval(x-4, y-4, 8, 8);

       }
 }
Point.java

public class Point {

    public double x;
    public double y;

    point(double x, double y){      
      this.x = x;
      this.y = y;      
    }
    drawPoint(){
      // This is where I want to build a reference to OverviewController.java's draw(double x, double y)-Method
    } 
  }

我建议使用模型-视图-控制器(或类似模式)方法,而不是试图让数据类型
访问控制器类

这样,您就可以让任何有权访问模型的控制器生成点。您的
OverviewController
只需观察模型(或其包含的特定属性)即可将点绘制到画布上,等等

创建模型类:

public class Model {

    private final ObservableList<Point> points = FXCollections.observableArrayList();

    public ObservableList<Point> getPoints() {
        return points ;
    }

    // other data you need to share...

}
现在你可以做:

public class OverviewController {

       private Model model ;

       public void initModel(Model model) {
           this.model = model ;
           this.model.getPoints().addListener((Change<? extends Point> change) -> {
               while (change.next()) {
                   if (change.wasAdded()) {
                       for (Point p : change.getAddedSublist()) {
                           draw(p.x, p.y);
                       }
                   }
               }
           });
       }

       @FXML
       Canvas canvas;

       public void test(){
         Point point = new Point(5,5);
         model.getPoints().add(point);
       }

       public void draw(double x, double y){

         GraphicsContext gc = canvas.getGraphicsContext2D();
         gc.setFill(Color.rgb(255, 0, 0));
         gc.fillOval(x-4, y-4, 8, 8);

       }
 }

另外,你看,这是非常相似的感谢你的回答-它真的帮助我在正确的方向上指导。我一直在想,如果我不仅想听听从ObservableList点添加或删除的对象,还想听听它们属性的变化,那么实现将如何变化,但我可能已经找到了(您的)答案:我还将尝试研究您在源代码中给我的各种提示。您所附的链接也帮助我更好地理解了MVC。
public class OverviewController {

       private Model model ;

       public void initModel(Model model) {
           this.model = model ;
           this.model.getPoints().addListener((Change<? extends Point> change) -> {
               while (change.next()) {
                   if (change.wasAdded()) {
                       for (Point p : change.getAddedSublist()) {
                           draw(p.x, p.y);
                       }
                   }
               }
           });
       }

       @FXML
       Canvas canvas;

       public void test(){
         Point point = new Point(5,5);
         model.getPoints().add(point);
       }

       public void draw(double x, double y){

         GraphicsContext gc = canvas.getGraphicsContext2D();
         gc.setFill(Color.rgb(255, 0, 0));
         gc.fillOval(x-4, y-4, 8, 8);

       }
 }
public class RootLayoutController {

    private Model model ;

    public void initModel(Model model) {
        this.model = model ;
    }

    // handler that adds a point:
    @FXML
    private void addPoint(MouseEvent e) {
        Point p = new Point(e.getX(), e.getY());
        model.getPoints().add(p);
    }
}