JavaFX:如果所选选项卡的数据验证失败,则禁止选择其他选项卡 [英] JavaFX: Prevent selection of a different tab if the data validation of the selected tab fails

查看:155
本文介绍了JavaFX:如果所选选项卡的数据验证失败,则禁止选择其他选项卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个将数据存储在本地h2数据库中的CRUD应用程序。我是JavaFX的新手。我使用 jfxml TabPane 到3 Tab c>使用 Scene Builder 2.0 创建。每个标签包含一个 AncorPane ,它包含所有控件:标签 EditText 等等。使用一个控制器管理 TabPane 选项卡。此函数用于创建和更新数据。它是从显示所有数据的网格调用的。一个非常基本的CRUD应用程序。

I'm creating a CRUD application that store data in a local h2 DB. I'm pretty new to JavaFX. I've created a TabPane to with 3 Tab using an jfxml created with Scene Builder 2.0. Each Tab contains an AncorPane that wrap all the controls: Label, EditText, and more. Both the TabPane and the Tabs are managed using one controller. This function is used to create and to update the data. It's called from a grid that display all the data. A pretty basic CRUD app.

我陷入了验证阶段:当用户更改选项卡时,通过选择另一个选项卡,它被称为相应选项卡的验证方法。如果选项卡的验证失败,我希望选择保留在此选项卡上。

I'm stuck in the validation phase: when the user change the tab, by selecting another tab, it's called a validation method of the corresponding tab. If the validation of the Tab fails, I want that the selection remains on this tab.

为实现此目的,我实现了以下 ChangeListener <我的 TabPane SelectionModel 上的/ code>:

To achieve this I've implemented the following ChangeListener on the SelectionModel of my TabPane:

boolean processingTabValidationOnChange = false;

tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
                if (processingTabValidationOnChange == false) {
                    boolean success;

                    switch (t.intValue()) {
                        case 0: success = validationTab1Passed();
                                break;
                        case 1: success = validationTab2Passed();
                                break;
                        case 1: success = validationTab3Passed();
                                break;
                        default: success = false;    
                    }
                    if (success == false) {
                        processingTabValidationOnChange = true;
                        // select the previous tab
                        tabPane.getSelectionModel().select(t.intValue());
                        processingTabValidationOnChange = false;
                    }
                }
            }
        });

我不确定这是正确的做法,因为:

I'm not sure that this is the right approach because:


  1. 事件已更改被触发两次,一次用于用户选择,另一次用于 。选择(t.intValue())。为了避免这种情况,我使用了全局字段boolean processingTabValidationOnChange ...非常脏我知道。

  2. <$ c $之后c> .select(t.intValue()) TabPane显示正确的选项卡,但选项卡的内容为空,就好像 AnchorPane 被隐藏了。我无法再次选择包含错误的选项卡,因为它已被选中。

  1. The event changed is fired two times, one for the user selection and one for the .select(t.intValue()). To avoid this I've used a global field boolean processingTabValidationOnChange... pretty dirty I know.
  2. After the .select(t.intValue()) the TabPane displays the correctly Tab as selected but the content of the tab is empty as if the AnchorPane was hidden. I cannot select again the tab that contains the errors because it's already selected.

任何帮助都将不胜感激。

Any help would be appreciated.

Elvis

推荐答案

正如我对詹姆斯的答案所评论的那样,我一直在寻找一种干净的解决方案。简而言之,防止用户在当前选项卡的验证失败时更改为其他选项卡。我提出了一个实现 ChangeListener 的解决方案,但正如我所解释的那样:它不是很干净而且(小细节)它不起作用!

As I commented to the James's answer, I was looking for a clean solution to the approach that I've asked. In short, to prevent the user to change to a different tab when the validation of the current tab fails. I proposed a solution implementing the ChangeListener but, as I explained: it's not very "clean" and (small detail) it doesn't work!

好的,问题是用于切换回上一个标签的代码:

Ok, the problem was that the code used to switch back the previous tab:

tabPane.getSelectionModel().select(t.intValue());

在切换标签本身完成之前被调用,因此它最终被选中..但是隐藏了。

is called before the process of switching of the tab itself it's completed, so it ends up selected... but hidden.

为了防止这种情况,我使用了 Platform.runLater()。更改选项卡后执行代码 .select()。完整代码变为:

To prevent this I've used Platform.runLater(). The code .select() is executed after the change of tab. The full code becomes:

//global field, to prevent validation on .select(t.intValue());
boolean skipValidationOnTabChange = false;

tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

    @Override
    public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
        if (skipValidationOnTabChange == false) {
            boolean success;

            switch (t.intValue()) {
                case 0:
                    success = validationTab1Passed();
                    break;
                case 1:
                    success = validationTab2Passed();
                    break;
                case 1:
                    success = validationTab3Passed();
                    break;
                default:
                    success = false;
            }
            if (success == false) {
                Platform.runLater(new Runnable() {

                    @Override
                    public void run() {
                        skipValidationOnTabChange = true;
                        tabPane.getSelectionModel().select(t.intValue());
                        skipValidationOnTabChange = false;
                    }
                });
            }
        }
    }
});

无论如何,如果有人有更好的解决方案来实现这一点,那么欢迎你。在示例中使用像 consume()这样的方法来阻止选项卡被选中两次。这样我就可以消除全局字段 skipValidationOnTabChange

Anyway, if anyone has a better solution to accomplish this, you're welcome. In example using a method like consume() to prevent the tab to be selected two times. This way I can eliminated the global field skipValidationOnTabChange.

猫王

这篇关于JavaFX:如果所选选项卡的数据验证失败,则禁止选择其他选项卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆