JavaFX:如果所选选项卡的数据验证失败,则禁止选择其他选项卡 [英] JavaFX: Prevent selection of a different tab if the data validation of the selected tab fails
问题描述
我正在创建一个将数据存储在本地h2数据库中的CRUD应用程序。我是JavaFX的新手。我使用 jfxml $ c $创建了一个
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:
- 事件
已更改
被触发两次,一次用于用户选择,另一次用于。选择(t.intValue())
。为了避免这种情况,我使用了全局字段booleanprocessingTabValidationOnChange
...非常脏我知道。 - <$ c $之后c> .select(t.intValue()) TabPane显示正确的选项卡,但选项卡的内容为空,就好像
AnchorPane
被隐藏了。我无法再次选择包含错误的选项卡,因为它已被选中。
- 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 booleanprocessingTabValidationOnChange
... pretty dirty I know. - After the
.select(t.intValue())
the TabPane displays the correctly Tab as selected but the content of the tab is empty as if theAnchorPane
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屋!