我正在使用Javafx开发一个应用程序,其中我在tabpane中有不同的选项卡。所以每个项目都有不同的控制器,比如Tabs有不同的控制器,每个tabpane都有独立的控制器。
我想要做的是用户无法切换到另一个标签,除非他填写当前标签上的所有元素,如文本字段,复选框等。
我做了研究,发现了一个接近我的问题的解决方案,但是开发人员在application中使用的方法与我的方法没什么不同,他将所有内容放在主控制器中,如:
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.ListBinding;
import javafx.beans.binding.LongBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Pane;
import javafx.scene.web.WebView;
public class MainController {
@FXML
private TextField firstNameTextField ;
@FXML
private TextField lastNameTextField ;
@FXML
private TextField emailTextField ;
@FXML
private TextField zipCodeTextField ;
@FXML
private Tab nameTab ;
@FXML
private Tab contactTab ;
@FXML
private Tab confirmationTab ;
@FXML
private TabPane tabPane ;
@FXML
private TitledPane nameTabErrorList ;
@FXML
private Pane nameTabErrorMessages ;
@FXML
private TitledPane contactTabErrorList ;
@FXML
private Pane contactTabErrorMessages ;
@FXML
private WebView browser ;
@FXML
private Label nameTabErrorInstructions ;
@FXML
private Label contactTabErrorInstructions ;
public void initialize() {
// Bit of a hack. Probably need a ValidationBinding extends BooleanBinding with a message property:
Map<BooleanBinding, String> messages = new HashMap<>();
tabPane.getSelectionModel().select(nameTab);
BooleanBinding firstNameInvalid = emptyTextFieldBinding(firstNameTextField, "First Name is required", messages);
BooleanBinding lastNameInvalid = emptyTextFieldBinding(lastNameTextField, "Last Name is required", messages);
final Pattern emailPattern = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*@[a-zA-Z][a-zA-Z0-9_]+(\\.[a-zA-Z][a-zA-Z0-9_]*)+");
BooleanBinding emailInvalid = patternTextFieldBinding(emailTextField, emailPattern, "You must enter a valid email", messages);
final Pattern zipPattern = Pattern.compile("[0-9]{5}");
BooleanBinding zipInvalid = patternTextFieldBinding(zipCodeTextField, zipPattern, "You must enter a 5-digit zip code", messages);
BooleanBinding[] nameTabBindings = { firstNameInvalid, lastNameInvalid } ;
BooleanBinding[] contactTabBindings = { emailInvalid, zipInvalid } ;
BooleanBinding nameTabInvalid = any(nameTabBindings);
BooleanBinding contactTabInvalid = any(contactTabBindings);
contactTab.disableProperty().bind(nameTabInvalid);
confirmationTab.disableProperty().bind(nameTabInvalid.or(contactTabInvalid));
nameTabErrorInstructions.visibleProperty().bind(nameTabInvalid);
contactTabErrorInstructions.visibleProperty().bind(contactTabInvalid);
bindMessageLabels(nameTabBindings, nameTabErrorMessages.getChildren(), messages);
final LongBinding nameTabErrorCount = count(nameTabBindings);
nameTabErrorList.textProperty().bind(Bindings.format("%d %s on this page", nameTabErrorCount,
Bindings.when(nameTabErrorCount.isEqualTo(1)).then("error").otherwise("errors")));
bindMessageLabels(contactTabBindings, contactTabErrorMessages.getChildren(), messages);
final LongBinding contactTabErrorCount = count(contactTabBindings);
contactTabErrorList.textProperty().bind(Bindings.format("%d %s on this page", contactTabErrorCount,
Bindings.when(contactTabErrorCount.isEqualTo(1)).then("error").otherwise("errors")));
browser.getEngine().load("http://www.google.com");
}
private void bindMessageLabels(BooleanBinding[] validationBindings, List<Node> labelList, Map<BooleanBinding, String> messages) {
ListBinding<Node> nodeListBinding = new ListBinding<Node>() {
{
// calling bind(...) here won't work, neither will using WeakInvalidationListeners. Not sure why....
InvalidationListener invalidationListener = obs -> invalidate();
Arrays.stream(validationBindings).forEach(binding ->
binding.addListener(invalidationListener));
}
@Override
protected ObservableList<Node> computeValue() {
return FXCollections.observableList(
Arrays.stream(validationBindings)
.filter(BooleanBinding::get)
.map(messages::get).map(Label::new)
.collect(Collectors.toList())
);
}
};
Bindings.bindContent(labelList, nodeListBinding);
}
private BooleanBinding emptyTextFieldBinding(TextField textField, String message, Map<BooleanBinding, String> messages) {
BooleanBinding binding = Bindings.createBooleanBinding(() ->
textField.getText().trim().isEmpty(), textField.textProperty());
configureTextFieldBinding(binding, textField, message, messages);
return binding ;
}
private BooleanBinding patternTextFieldBinding(TextField textField, Pattern pattern, String message, Map<BooleanBinding, String> messages) {
BooleanBinding binding = Bindings.createBooleanBinding(() ->
!pattern.matcher(textField.getText()).matches(), textField.textProperty());
configureTextFieldBinding(binding, textField, message, messages);
return binding ;
}
private void configureTextFieldBinding(BooleanBinding binding, TextField textField, String message, Map<BooleanBinding, String> messages) {
messages.put(binding, message);
if (textField.getTooltip() == null) {
textField.setTooltip(new Tooltip());
}
String tooltipText = textField.getTooltip().getText();
binding.addListener((obs, oldValue, newValue) -> {
updateTextFieldValidationStatus(textField, tooltipText, newValue, message);
});
updateTextFieldValidationStatus(textField, tooltipText, binding.get(), message);
}
private BooleanBinding any(BooleanBinding[] bindings) {
return Bindings.createBooleanBinding(() ->
Arrays.stream(bindings).anyMatch(BooleanBinding::get), bindings);
}
private LongBinding count(BooleanBinding[] bindings) {
return Bindings.createLongBinding(() ->
Arrays.stream(bindings).filter(BooleanBinding::get).collect(Collectors.counting()), bindings);
}
private void updateTextFieldValidationStatus(TextField textField,
String defaultTooltipText, boolean invalid, String message) {
textField.pseudoClassStateChanged(PseudoClass.getPseudoClass("validation-error"), invalid);
String tooltipText ;
if (invalid) {
tooltipText = message;
} else {
tooltipText = defaultTooltipText;
}
if (tooltipText == null || tooltipText.isEmpty()) {
textField.setTooltip(null);
} else {
Tooltip tooltip = textField.getTooltip();
if (tooltip == null) {
textField.setTooltip(new Tooltip(tooltipText));
} else {
tooltip.setText(tooltipText);
}
}
}
}
但在很多情况下,因为我为每个标签设置了不同的控制器,我如何才能与不同的控制器实现相似:
TabPaneManager.java
public class TabPaneManager {
@FXML
private TabPane tabPane ;
@FXML
private Tab aTab ;
@FXML
private Tab bTab ;
@FXML
private Tab cTab ;
public void initialize() {
}
}
aTabController.java
public class aTabController {
@FXML
private JFXCheckBox aCheckBox ;
@FXML
private JFXCheckBox bCheckBox ;
@FXML
private JFXComboBox<String> aComboBox ;
@FXML
private JFXTextField aTextField ;
@FXML
private JFXTextField bTextField ;
@FXML
private JFXTextField cTextField ;
public void initialize() {
}
}
bTabController.java
public class bTabController {
@FXML
private JFXCheckBox aCheckBox ;
@FXML
private JFXTextField aTextField ;
@FXML
private JFXTextField bTextField ;
public void initialize() {
}
}
cTabController.java
public class cTabController {
@FXML
private JFXTextField aTextField ;
@FXML
private JFXTextField bTextField ;
@FXML
private JFXTextField cTextField ;
@FXML
private JFXButton aButton ;
public void initialize() {
}
}
答案 0 :(得分:0)
如果符合要求,只需广告跟随标签。
aTabComboBoxKeyActionPerformed(KeyEvent evt){
if(evt.getKeyCode()==KeyEvent.VK_RETURN)
if(combo1.getSelectedIndex()!=-1 && textField.getText().matches("Your idea")||et.c.)
tabbedPanel.addTab(bTab);
}