【问题标题】:View don't refresh Button - Java FX查看不刷新按钮 - Java FX
【发布时间】:2014-09-22 14:40:24
【问题描述】:

这是我在 JAVAFX 中的第一个项目,目前它是一个简单的程序。我的问题是,当程序启动 FXMLLoadLogController 的按钮“loadLogButton”时,会正确收取消息。但是当我在 comboBox 中选择另一种语言时,按钮的设置器工作正常,但视图没有刷新。有什么问题?

RPV:LoadLogController 的函数 chargeI18nValues 工作正常,但从 SolverManager 调用时,程序中的按钮文本没有刷新。

代码:

SolverAssistant.java

public class SolverAssistant extends Application {

    public static ResourceBundle messages;
    public static Utils utils = new Utils();
    public static SolverManager manager;

    @Override
    public void start(Stage stage) throws Exception {
        // Load the resource bundle
        this.chargeResourceBundleLanguage();

        // Load Controllers
        Scene scene = new Scene(new StackPane());
        manager = new SolverManager(scene);
        manager.showMainView();
        stage.setScene(scene);
        stage.show();
    }

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

    public void chargeResourceBundleLanguage() {
        String defaultLanguage = utils.fileReader(new File("lang.txt"));
        switch (defaultLanguage) {
            case "en":
                messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("en"));
                break;
            case "es":
                messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("es"));
                break;
            case "cat":
                messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("cat"));
                break;
            default:
                messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("en"));
                break;
        }
    }
}

SolverManager.java

public class SolverManager {

    private final Scene scene;
    private FXMLMainController mainController;
    private FXMLLoadLogController logController;

    public SolverManager(Scene scene) {
        this.scene = scene;
    }

    public void showMainView() throws IOException {
        FXMLLoader mainLoader = new FXMLLoader(getClass().getResource("FXMLMain.fxml"));
        scene.setRoot((Parent) mainLoader.load());
        mainController = mainLoader.<FXMLMainController>getController();
        FXMLLoader loadLoader = new FXMLLoader(getClass().getResource("FXMLLoadLog.fxml"));
        loadLoader.load();
        logController = loadLoader.<FXMLLoadLogController>getController();
    }

    public void refreshI18nResources() {
        mainController.chargeI18nValues();
        logController.chargeI18nValues();
    }
}

FXMLMainController.java

public class FXMLMainController implements Initializable {

    @FXML
    private ComboBox<String> comboLanguage;

    @FXML
    private Tab loadTab;

    @FXML
    private Tab editTab;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.chargeI18nValues();
        this.chargeLanguageComboBox(SolverAssistant.messages.getLocale());
        comboLanguage.getSelectionModel().selectedItemProperty().addListener(this.languageComboBoxListener());
    }

    public void chargeI18nValues() {
        loadTab.setText(SolverAssistant.messages.getString("LoadLog"));
        editTab.setText(SolverAssistant.messages.getString("EditLog"));
    }

    private void chargeLanguageComboBox(Locale language) {
        comboLanguage.getItems().addAll(
                "Català",
                "English",
                "Español"
        );
        switch (language.getLanguage()) {
            case "cat":
                comboLanguage.setValue("Català");
                break;
            case "es":
                comboLanguage.setValue("Español");
                break;
            case "en":
                comboLanguage.setValue("English");
                break;
        }
    }

    // -------- Listeners
    private ChangeListener languageComboBoxListener() {
        return new ChangeListener() {
            public void stateChanged(ChangeEvent changeEvent) {
            }

            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                switch ((String) newValue) {
                    case "Català":
                        SolverAssistant.messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("cat"));
                        SolverAssistant.utils.fileWriter("lang.txt", "cat");
                        break;
                    case "Español":
                        SolverAssistant.messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("es"));
                        SolverAssistant.utils.fileWriter("lang.txt", "es");
                        break;
                    case "English":
                        SolverAssistant.messages = ResourceBundle.getBundle("bundles.bundle", Locale.forLanguageTag("en"));
                        SolverAssistant.utils.fileWriter("lang.txt", "en");
                        break;
                }
                SolverAssistant.manager.refreshI18nResources();
            }
        };
    }

}

FXMLLoadLogController.java

public class FXMLLoadLogController implements Initializable {

    @FXML
    private Label logNameLabel;

    @FXML
    private TextArea logTextArea;

    @FXML
    private Button loadLogButton;

    //private String logName;
    private final String logName = "C:\\Users\\Daniel\\Desktop\\ahmaxsat-ls-ms_crafted-COMPLETE-1800-3500-2.log";
    private String log;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.chargeI18nValues();
    }

    public void chargeI18nValues() {
        loadLogButton.setText(SolverAssistant.messages.getString("OpenNewLog"));
    }

    // -------- Actions
    @FXML
    private void openLog(ActionEvent event) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle(SolverAssistant.messages.getString("Open"));
        fileChooser.setCurrentDirectory(new File("."));
        // Selecting File
        //if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
        if (true) {
            //File file = fileChooser.getSelectedFile();
            log = SolverAssistant.utils.fileReader(new File(logName));
            logNameLabel.setText(logName);
            logTextArea.setText(log);
        }
    }
}

【问题讨论】:

  • 检查SolverAssistant.messages.getString(...) 中的chargeI18nValues() 方法是否在组合框项目更改时返回具有正确语言的正确字符串。
  • 是的,如果我放一个 System.out.println(loadLogButton.getText());在设置后的 LoadLogController 的 chargeI18nValues 函数中,告诉我按钮可以很好地更改文本,但它没有显示在视图上。就好像视图没有刷新一样……
  • 哪个版本的 API 和操作系统?尝试创建新的演示项目,您将在按钮单击时将标签文本设置为任意值。通过这样做,将确定prbolem 环境特定还是您的代码特定。
  • 一个简单的代码在新项目中运行良好,关键是刷新了主视图,我的意思是,选项卡上的文本正确更改并显示,但选项卡的内容发生了变化但第一次更改后没有刷新。也许问题是我如何链接选项卡(AnchorPanel)的内容,因为在初始化之后我可以更改它们,但它没有显示出来。我在 W8 上工作,这里是 github,也许很容易看到问题:github.com/danielcasanovas/SolverAssistant

标签: java swing javafx javafx-8


【解决方案1】:

问题在于有 2 个子/子 FXML(及其控制器)实例。它们是:
1) 使用FXMLLoaderSolverManager.showMainView() 加载
2) 通过&lt;fx:include&gt;s

FXMLMain.fxml 加载

场景包含通过包含加载的场景,但文本更改发生在其他场景中。要解决您需要的问题,您需要选择其中一种方法,删除包含或删除 fxmlloadings。这是第二种方法:

public class SolverManager {

    private final Scene scene;
    private FXMLMainController mainController;
//    private FXMLLoadLogController loadLogController;
//    private FXMLEditLogController editLogController;

    public SolverManager(Scene scene) {
        this.scene = scene;
    }

    public void showMainView() throws IOException {
        FXMLLoader mainLoader = new FXMLLoader(getClass().getResource("FXMLMain.fxml"));
        scene.setRoot((Parent) mainLoader.load());
        mainController = mainLoader.<FXMLMainController>getController();

//        FXMLLoader loadLoader = new FXMLLoader(getClass().getResource("FXMLLoadLog.fxml"));
//        loadLoader.load();
//        loadLogController = loadLoader.<FXMLLoadLogController>getController();
//        FXMLLoader editLoader = new FXMLLoader(getClass().getResource("FXMLEditLog.fxml"));
//        editLoader.load();
//        editLogController = editLoader.<FXMLEditLogController>getController();
    }

    public void refreshI18nResources() {
        mainController.chargeI18nValues();
//        loadLogController.chargeI18nValues();
//        editLogController.chargeI18nValues();
    }
}

将以下行添加到FXMLMainController

@FXML
private FXMLLoadLogController barTabPageLoadController;

@FXML
private FXMLEditLogController barTabPageEditController;

(变量名来自fx:id + Controller。见Subcontroller not being injected into main controller

并在同一个文件中更改以下内容

public void chargeI18nValues() {
    loadTab.setText(SolverAssistant.messages.getString("LoadLog"));
    editTab.setText(SolverAssistant.messages.getString("EditLog"));
    barTabPageLoadController.chargeI18nValues();
    barTabPageEditController.chargeI18nValues();
}

【讨论】:

  • 有道理,这是我的第一个项目,我的概念还不清楚,今天下午我会尝试但似乎真的很好的解决方案,非常感谢您的帮助!
猜你喜欢
  • 2012-12-07
  • 2013-01-03
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2013-02-05
  • 2019-10-25
  • 1970-01-01
相关资源
最近更新 更多