JavaFX-действия над элементами одного окна из другого окна - PullRequest
0 голосов
/ 09 ноября 2018

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

sample.fxml, its controller ControllerMain (main window of the program)
find_win.fxml, its ControllerFind controller (modal window "text search")

В модальном окне find_win.fxml есть TextField, в который вводится текст поиска, и при нажатии кнопки Find ControllerFind должен обработать щелчок и вызвать метод поиска и выделить текст поиска в элементе TextArea окно sample.fxml.

<fx: include source = "sample.fxml" fx: id = "textAreaOne" />

и наследование ControllerMain контроллером ControllerFind не помогает достичь решения - в первом случае вся разметка окна полностью включена в модальное окно, во втором случае java.lang.reflect.InvocationTargetException возвращается во время операции над TextArea.

Как реализовать действия над элементами одного окна из другого окна?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

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

Описанное решение здесь .

Короче говоря, необходимо создать экземпляр контроллера-родителя и метод, который принимает экземпляр контроллера-родителя в качестве параметра в контроллере-потомке. Когда новое окно открывается из контроллера-родителя, получите экземпляр контроллера-потомка и укажите ему через созданный метод "this".

Кроме того, в контроллере-потомке можно будет получить доступ к элементам родительского контроллера.

Контроллер-родитель:

package sample;

public class ControllerMain {

    private ControllerFind children;  // controller-child

    //main-window
    @FXML
    public TextArea textAreaOne;
    @FXML
    public MenuItem findMenuItem;

    public void findAction(ActionEvent actionEvent) {
        try {
            Stage stageFind = new Stage();
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("FXML/find_win.fxml"));
            Parent root = loader.load();
            stageFind.setTitle("Find");
            stageFind.setMinHeight(200);
            stageFind.setMinWidth(150);
            stageFind.setResizable(false);
            stageFind.setScene(new Scene(root));
            stageFind.getIcons().add(new Image("image/search.png"));
            stageFind.initModality(Modality.NONE);
            stageFind.show();

            children = loader.getController(); //getting controller of window find_win.fxml
            children.setParent(this);   //setting parent of the controller-child - this

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

Контроллер-ребенок:

package sample.Controllers;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import sample.Classes.DialogManager;
import sample.ControllerMain;

public class ControllerFind {

    //Window "Find"
    @FXML public TextField searchTextField;
    @FXML public Label findTextLabel;
    @FXML public Button okTextFindButton;
    @FXML public Button cancelTextFindButton;
    private String text;
    private ControllerMain controller;

    public void setParent (ControllerMain controller){
        this.controller = controller;
    }

    public ControllerFind getThis(){
        return this;
    }

    public void initialize(){
        System.out.println("psvm");
    }

    public void textFindOkButtonAction(ActionEvent actionEvent) {
        text = (searchTextField.getText());
        if (text.equals("")) {
            DialogManager.showInfoDialog("Error!", "Enter text what you are looking for!");
        } else {
            if (controller.textAreaOne.getText() != null && !controller.textAreaOne.getText().isEmpty()) {
                int index = controller.textAreaOne.getText().indexOf(text);
                if (index == -1) {
                    DialogManager.showInfoDialog("Result", "There isn't text what you are looking for");
                } else {
                    controller.textAreaOne.selectRange(index, index + text.length());
                }
            } else {
                DialogManager.showInfoDialog("Error", "TextArea is empty!");
            }
        }
    }

    public void textFindCancelButtonAction(ActionEvent actionEvent) {
        Node source = (Node) actionEvent.getSource();
        Stage stage = (Stage) source.getScene().getWindow();
        stage.close();
    }
}
0 голосов
/ 09 ноября 2018

Взаимосвязь окон и окон в этой ситуации оптимально использовать TextInputDialog примерно так:

@Override
    public void start(Stage primaryStage){

        Button btn=new Button("Click");
        VBox vbox=new VBox();
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(btn);
        Scene scene=new Scene(vbox, 200,200);

        btn.setOnAction(e->
        {
            TextInputDialog dialog=new TextInputDialog();
            Optional<String> result = dialog.showAndWait();
            if (result.isPresent()){
                System.out.println(result.get());
            }
        });
        primaryStage.setScene(scene);
        primaryStage.show();
    }

, но выделение текста не так просто. Вы можете выполнить поиск строки текста TextArea, сравнить его с результатом из другого окна, а затем выделить его с помощью

textArea.getSelectedRange(firstIndex, lastIndex);

firstIndex и lastIndex являются индексами текста textArea для слова, которое мы ищем. Затем, нажимая кнопку на каждом клике, вы увидите в тексте следующее слово и выделите его. Но если вы настаиваете на выделении каждого слова в одно и то же время, я бы предложил использовать RichTextFX .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...