2016-04-26 4 views
1

Есть ли возможность использовать контроллер с графическим интерфейсом JavaFX без использования FXML.Использование контроллера JavaFX без FXML

Я заметил, что файл FXML содержит атрибут fx-controller для привязки контроллера, но я не считаю его простым способом работать с ним.

Любые идеи о наличии арки MVC с JavaFX без использования файла FXML или JavaFX Scene Builder?

+0

Y ou не нужно использовать FXML или SceneBuilder. Вы можете просто создать объекты самостоятельно и самостоятельно добавить их в свою сцену/сцену. Он полностью открыт, как вы его реализуете. Я реализовал библиотеку управления экранами, где он обрабатывает либо FXML, либо созданные вручную экраны. Это можно сделать :) – ManoDestra

ответ

6

Ваш вопрос не особенно ясно мне: вы просто создать классы и в основном связать все вместе со слушателями. Я не знаю, помогает ли это, но вот простой пример, который содержит только пару текстовых полей и ярлык, отображающий их сумму. Это то, что я считаю «классическим MVC»: представление наблюдает за моделью и обновляет элементы пользовательского интерфейса, если модель меняется. Он регистрирует обработчики с элементами пользовательского интерфейса и делегирует контроллеру, если происходят события: контроллер, в свою очередь, обрабатывает ввод (при необходимости) и обновляет модель.

Модель:

package mvcexample; 

import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.ReadOnlyIntegerWrapper; 
import javafx.beans.property.SimpleIntegerProperty; 

public class AdditionModel { 
    private final IntegerProperty x = new SimpleIntegerProperty(); 
    private final IntegerProperty y = new SimpleIntegerProperty(); 
    private final ReadOnlyIntegerWrapper sum = new ReadOnlyIntegerWrapper(); 

    public AdditionModel() { 
     sum.bind(x.add(y)); 
    } 

    public final IntegerProperty xProperty() { 
     return this.x; 
    } 

    public final int getX() { 
     return this.xProperty().get(); 
    } 

    public final void setX(final int x) { 
     this.xProperty().set(x); 
    } 

    public final IntegerProperty yProperty() { 
     return this.y; 
    } 

    public final int getY() { 
     return this.yProperty().get(); 
    } 

    public final void setY(final int y) { 
     this.yProperty().set(y); 
    } 

    public final javafx.beans.property.ReadOnlyIntegerProperty sumProperty() { 
     return this.sum.getReadOnlyProperty(); 
    } 

    public final int getSum() { 
     return this.sumProperty().get(); 
    } 



} 

Контроллер:

package mvcexample; 

public class AdditionController { 

    private final AdditionModel model ; 

    public AdditionController(AdditionModel model) { 
     this.model = model ; 
    } 

    public void updateX(String x) { 
     model.setX(convertStringToInt(x)); 
    } 

    public void updateY(String y) { 
     model.setY(convertStringToInt(y)); 
    } 

    private int convertStringToInt(String s) { 
     if (s == null || s.isEmpty()) { 
      return 0 ; 
     } 
     if ("-".equals(s)) { 
      return 0 ; 
     } 
     return Integer.parseInt(s); 
    } 
} 

Вид:

package mvcexample; 

import javafx.geometry.HPos; 
import javafx.geometry.Pos; 
import javafx.scene.Parent; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.control.TextFormatter.Change; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Priority; 

public class AdditionView { 
    private GridPane view ; 
    private TextField xField; 
    private TextField yField; 
    private Label sumLabel; 

    private AdditionController controller ; 
    private AdditionModel model ; 

    public AdditionView(AdditionController controller, AdditionModel model) { 

     this.controller = controller ; 
     this.model = model ; 

     createAndConfigurePane(); 

     createAndLayoutControls(); 

     updateControllerFromListeners(); 

     observeModelAndUpdateControls(); 

    } 

    public Parent asParent() { 
     return view ; 
    } 

    private void observeModelAndUpdateControls() { 
     model.xProperty().addListener((obs, oldX, newX) -> 
       updateIfNeeded(newX, xField)); 

     model.yProperty().addListener((obs, oldY, newY) -> 
       updateIfNeeded(newY, yField)); 

     sumLabel.textProperty().bind(model.sumProperty().asString()); 
    } 

    private void updateIfNeeded(Number value, TextField field) { 
     String s = value.toString() ; 
     if (! field.getText().equals(s)) { 
      field.setText(s); 
     } 
    } 

    private void updateControllerFromListeners() { 
     xField.textProperty().addListener((obs, oldText, newText) -> controller.updateX(newText)); 
     yField.textProperty().addListener((obs, oldText, newText) -> controller.updateY(newText)); 
    } 

    private void createAndLayoutControls() { 
     xField = new TextField(); 
     configTextFieldForInts(xField); 

     yField = new TextField(); 
     configTextFieldForInts(yField); 

     sumLabel = new Label(); 

     view.addRow(0, new Label("X:"), xField); 
     view.addRow(1, new Label("Y:"), yField); 
     view.addRow(2, new Label("Sum:"), sumLabel); 
    } 

    private void createAndConfigurePane() { 
     view = new GridPane(); 

     ColumnConstraints leftCol = new ColumnConstraints(); 
     leftCol.setHalignment(HPos.RIGHT); 
     leftCol.setHgrow(Priority.NEVER); 

     ColumnConstraints rightCol = new ColumnConstraints(); 
     rightCol.setHgrow(Priority.SOMETIMES); 

     view.getColumnConstraints().addAll(leftCol, rightCol); 

     view.setAlignment(Pos.CENTER); 
     view.setHgap(5); 
     view.setVgap(10); 
    } 

    private void configTextFieldForInts(TextField field) { 
     field.setTextFormatter(new TextFormatter<Integer>((Change c) -> { 
      if (c.getControlNewText().matches("-?\\d*")) { 
       return c ; 
      } 
      return null ; 
     })); 
    } 
} 

класс Применение:

package mvcexample; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class MVCExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     AdditionModel model = new AdditionModel(); 
     AdditionController controller = new AdditionController(model); 
     AdditionView view = new AdditionView(controller, model); 

     Scene scene = new Scene(view.asParent(), 400, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

Вот что я говорил. Использование «Классического MVC» на JavaFX без FXML; Спасибо, что это достаточно справедливо –

2

Я использую JavaFX широко и не использую FXML или сценарий. Поэтому я могу поручиться, что это можно сделать.

Ниже приведен автоматический код, созданный моей IDE, чтобы получить основной класс JavaFX. Это будет корень вашего приложения. Затем вы добавите его для создания своего приложения.

public class NewFXMain extends Application { 

@Override 
public void start(Stage primaryStage) { 
    Button btn = new Button(); 
    btn.setText("Say 'Hello World'"); 
    btn.setOnAction(new EventHandler<ActionEvent>() { 

     @Override 
     public void handle(ActionEvent event) { 
      System.out.println("Hello World!"); 
     } 
    }); 

    StackPane root = new StackPane(); 
    root.getChildren().add(btn); 

    Scene scene = new Scene(root, 300, 250); 

    primaryStage.setTitle("Hello World!"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    launch(args); 
} 

} 
+0

Спасибо за ваш ответ, но мне интересно, как связать контроллер с представлением без FXML, потому что я хочу его как MVC 3-уровневый –

+2

@HassamAbdelillah Какой вид? Если вы не используете FXML, вам нечего связывать. Вы просто передаете свои вызовы из компонентов пользовательского интерфейса непосредственно в компоненты контроллера. Когда вы создаете компоненты, вы все равно привязываете свои действия к действиям контроллера в коде, поэтому в этом случае нет привязки. Вам нужна только эта методология для FXML. Вы можете увидеть действие, связанное с элементом управления в ответе Хосе выше. – ManoDestra

Смежные вопросы