JavaFX: если узел равен узлу - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть простая программа на JavaFX, такая как:
Layout

Когда я нажимаю первую кнопку, она помещает content1 с правой стороны разделенного экрана. Когда я нажимаю кнопку 2, она помещает content2 справа (ведет себя так, как должно).

Но когда, например, в Text2 есть текстовое поле, и я снова нажимаю кнопку 2, оно сбрасывается.
Как проверить, что я уже в контенте 2?

Контроллер. java:

@FXML private SplitPane splitpane;
@FXML private Node content;


@FXML
public void initialize() {
    changeContent(new ContentA());
}



@FXML
public void onMenuClickA(ActionEvent event) {
    changeContent(new ContentA());
}
@FXML
public void onMenuClickB(ActionEvent event) {
    changeContent(new ContentB());
}




private void changeContent(Node node) {
    if (node.equals(content)) {        // <---- Not working
        System.out.println("Same");
    }
    List<Node> splitpaneItems = splitpane.getItems();
    splitpaneItems.set(splitpaneItems.indexOf(content), node);
    content = node;
}

ContentA. java:

public class ContentA extends HBox {

public ContentA() {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/contents/Test1.fxml"));

    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);

    try {
        fxmlLoader.load();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1 Ответ

4 голосов
/ 20 февраля 2020

Существует несколько возможных решений, в зависимости от того, какое именно поведение вы хотите.

Если вы никогда не хотите сбросить отдельные компоненты, просто предварительно загрузите их в методе initialize() и сохраните их в переменных экземпляра:

public class Controller {

    @FXML private SplitPane splitpane;

    private ContentA contentA ;
    private ContentB contentB ; 

    private int contentIndex ;        

    @FXML
    public void initialize() {
        contentA = new ContentA();
        contentB = new ContentB();
        contentIndex = splitPane.getItems().size() ;
        splitPane.getItems().set(contentIndex, contentA);
    }



    @FXML
    public void onMenuClickA(ActionEvent event) {
        changeContent(contentA);
    }
    @FXML
    public void onMenuClickB(ActionEvent event) {
        changeContent(contentB);
    }

    private void changeContent(Node node) {
        splitpaneItems.set(contentIndex, node);
    }

}

На с другой стороны, если вы хотите «сбросить» содержимое при загрузке, но хотите запретить пользователю перезагружать текущее содержимое, вы можете просто отключить самую последнюю нажатую кнопку:

public class Controller {

    @FXML private SplitPane splitpane;
    @FXML private Button buttonA ;
    @FXML private Button buttonB ;

    private int contentIndex ;        


    @FXML
    public void initialize() {
        buttonA.setDisable(true);
        contentIndex = splitPane.getItems().size() ;
        changeContent(new ContentA()); 
    }



    @FXML
    public void onMenuClickA(ActionEvent event) {
        buttonA.setDisable(true);
        buttonB.setDisable(false);
        changeContent(new ContentA());
    }
    @FXML
    public void onMenuClickB(ActionEvent event) {
        buttonA.setDisable(false);
        buttonB.setDisable(true);
        changeContent(new ContentB());
    }




    private void changeContent(Node node) {
        splitpaneItems.set(splitpaneItems.indexOf(content), node);
    }

}

Наконец, если вы хотите иметь возможность управлять различным поведением для разного контента (например, всегда перезагружать контент A, никогда не перезагружать контент B), вам необходимо использовать переменную, чтобы отслеживать состояние контента. enum хорошо подходит для этого:

public class Controller {

    private ContentB contentB  ;


    public enum Content {
        A(() -> new ContentA()),
        B(() -> contentB) ;


        private final Supplier<Node> nodeLoader ;

        Content(Supplier<Node> nodeLoader) {
            this.nodeLoader = nodeLoader ;
        }

        public Node getContent() {
            return nodeLoader.get();
        }
    }

    private Content currentContent ; 


    @FXML
    public void initialize() {

        contentB = new ContentB();

        contentIndex = splitPane.getItems().size() ;
        changeContent(Content.A);
    }



    @FXML
    public void onMenuClickA(ActionEvent event) {
        changeContent(Content.A);
    }
    @FXML
    public void onMenuClickB(ActionEvent event) {
        changeContent(Content.B);
    }

    private void changeContent(Content content) {
        this.currentContent = content ;
        splitpaneItems.set(contentIndex, content.getContent());
    }

}
...