developer tip

FXML 컨트롤러 클래스에 액세스

copycodes 2020. 12. 11. 08:23
반응형

FXML 컨트롤러 클래스에 액세스


메인 애플리케이션이나 다른 단계에서 화면의 정보를 업데이트하기 위해 언제든지 FXML 컨트롤러 클래스와 통신하고 싶습니다.

이것이 가능한가? 나는 그것을 할 방법을 찾지 못했습니다.

정적 함수는 방법이 될 수 있지만 양식의 컨트롤에 액세스 할 수 없습니다.

어떤 아이디어?


컨트롤러는 FXMLLoader

FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource("foo.fxml").openStream());
FooController fooController = (FooController) fxmlLoader.getController();

메인 스테이지에 저장하고 getFooController () getter 메서드를 제공합니다.
다른 클래스 나 단계에서로드 된 "foo.fxml"페이지를 새로 고쳐야 할 때마다 컨트롤러에서 요청하십시오.

getFooController().updatePage(strData);

updatePage ()는 다음과 같을 수 있습니다.

// ...
@FXML private Label lblData;
// ...
public void updatePage(String data){
    lblData.setText(data);
}
// ...

FooController 클래스에서.
이렇게하면 다른 페이지 사용자가 페이지의 내부 구조에 대해 신경 쓰지 않습니다 Label lblData.

또한 볼 https://stackoverflow.com/a/10718683/682495을 . JavaFX 2.2 FXMLLoader에서는 개선되었습니다.


허용되는 답변을 명확히하고 JavaFX를 처음 사용하는 다른 사용자를 위해 약간의 시간을 절약하기 위해 :

JavaFX FXML 응용 프로그램의 경우 NetBeans는 다음과 같이 기본 클래스에서 시작 메서드를 자동 생성합니다.

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();
}

이제 컨트롤러 클래스에 액세스하려면 FXMLLoader load()메서드를 정적 구현에서 인스턴스화 된 구현으로 변경 한 다음 인스턴스의 메서드를 사용하여 다음과 같이 컨트롤러를 가져올 수 있습니다.

//Static global variable for the controller (where MyController is the name of your controller class
static MyController myControllerHandle;

@Override
public void start(Stage stage) throws Exception {
    //Set up instance instead of using static load() method
    FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
    Parent root = loader.load();

    //Now we have access to getController() through the instance... don't forget the type cast
    myControllerHandle = (MyController)loader.getController();

    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();
}

또 다른 해결책은 컨트롤러 클래스에서 컨트롤러를 설정하는 것입니다.

public class Controller implements javafx.fxml.Initializable {

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // Implementing the Initializable interface means that this method
        // will be called when the controller instance is created
        App.setController(this);
    }

}

이것은 코드가 로컬 리소스 등을 적절하게 처리하는 완전한 기능의 FXMLLoader 인스턴스를 만드는 데 다소 지저분하기 때문에 사용하는 것을 선호하는 솔루션입니다.

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
}

@Override
public void start(Stage stage) throws Exception {
    URL location = getClass().getResource("/sample.fxml");
    FXMLLoader loader = createFXMLLoader(location);
    Parent root = loader.load(location.openStream());
}

public FXMLLoader createFXMLLoader(URL location) {
    return new FXMLLoader(location, null, new JavaFXBuilderFactory(), null, Charset.forName(FXMLLoader.DEFAULT_CHARSET_NAME));
}

On the object's loading from the Main screen, one way to pass data that I have found and works is to use lookup and then set the data inside an invisible label that I can retrieve later from the controller class. Like this:

Parent root = FXMLLoader.load(me.getClass().getResource("Form.fxml"));
Label lblData = (Label) root.lookup("#lblData");
if (lblData!=null) lblData.setText(strData); 

This works, but there must be a better way.

참고URL : https://stackoverflow.com/questions/10751271/accessing-fxml-controller-class

반응형