@Override public Change apply(final Change c) { if (settingDefaultOn == c.getControl()) { return c; } if (c.isContentChange() && !correctContentChange(c)) { return null; } adjustCaretPosition(c); return c; }
private boolean correctContentChange(final Change c) { Optional<String> correctNewText = Optional.empty(); if (c.isReplaced()) { correctNewText = correctReplacedText(c); } else if (c.isAdded()) { correctNewText = correctAddedText(c); } else if (c.isDeleted()) { correctNewText = correctDeletedText(c); } if (correctNewText.isPresent()) { final int start = c.getRangeStart(); c.setRange(start, Math.min(start + correctNewText.get().length(), c.getControlText().length())); c.setText(correctNewText.get()); } return correctNewText.isPresent(); }
private Optional<String> correctAddedText(final Change c) { final int start = c.getRangeStart(); final String text = c.getText(); final StringBuilder newText = new StringBuilder(text.length()); for (int i = start; i - start < text.length() && i < mask.length; i++) { final char ch = text.charAt(i - start); if (mask[i].isAllowed(ch)) { newText.append(mask[i].tranform(ch)); } else { return Optional.empty(); } } return Optional.of(newText.toString()); }
private Optional<String> correctDeletedText(final Change c) { int start = c.getRangeStart(); final int end = c.getRangeEnd(); final StringBuilder newText = new StringBuilder(end - start); for (int i = start; i < end; i++) { newText.append(mask[i].getDefault()); } // For backspace case for (int i = start; i > 0 && !mask[i].isNavigable(); i--, start--) { newText.insert(0, mask[i - 1].getDefault()); } c.setRange(start, end); return Optional.of(newText.toString()); }
private void adjustCaretPosition(final Change c) { final int oldPosition = c.getControlCaretPosition(); int position = Math.min(c.getCaretPosition(), mask.length); if (oldPosition != position) { final int sign = (position > oldPosition ? 1 : -1); while (position > 0 && position < mask.length && !mask[position].isNavigable()) { position += sign; } while (position < mask.length && !mask[position].isNavigable()) { position++; } } position = Math.min(position, c.getControlNewText().length()); if (c.getAnchor() == c.getCaretPosition()) { c.setAnchor(position); } c.setCaretPosition(position); }
private Optional<String> correctReplacedText(final Change c) { final int start = c.getRangeStart(); final int end = c.getRangeEnd(); final String text = c.getText(); final StringBuilder newText = new StringBuilder(end - start); for (int i = start; i - start < text.length() && i < end && i < mask.length; i++) { final char ch = text.charAt(i - start); if (mask[i].isAllowed(ch)) { newText.append(mask[i].tranform(ch)); } else { return Optional.empty(); } } for (int i = start + text.length(); i < end && i < mask.length; i++) { newText.append(mask[i].getDefault()); } return Optional.of(newText.toString()); }
/** * Číselný filter s intervalem * * @param min Spodní hranice intervalu * @param max Horní hranice intervalu * @return {@link UnaryOperator} */ public static UnaryOperator<Change> integerFilter(final int min, final int max) { return t -> { if (t.isAdded()) { if (t.getText().matches(INTEGER_PATTERN)) { t.setText(String.valueOf(min)); } } if (t.isReplaced()) { if (t.getText().matches(INTEGER_PATTERN)) { t.setText(t.getControlText().substring(t.getRangeStart(), t.getRangeEnd())); } } if (t.isDeleted()) { if (t.getControlNewText().isEmpty()) { t.setText(String.valueOf(min)); } } long value = Long.parseLong(t.getControlNewText()); if (value > max || value < min) { return null; } if (t.getText().equals(String.valueOf(min))) { t.setCaretPosition(1); } return t; }; }
public UnaryOperator<Change> getFilter(String id, ObservableValue<?> property) { PropertyDescriptor pds = getPropertyDescriptor(id); Class<?> type = pds.getPropertyType(); Column column = pds.getReadMethod().getAnnotation(Column.class); if (Number.class.isAssignableFrom(type)) { return uk.ltd.mediamagic.fx.converters.Filters.numeric(); } else if (String.class.isAssignableFrom(type) && column != null) { return uk.ltd.mediamagic.fx.converters.Filters.width(column.length()); } return null; }
/** * Replaces {@link #nameTextField} responsible for editing name with new one. <br> * It's needed because when we do {@link #recreateValidationSupport()}, the old * ValidationSupport object still have registered validator to nameTextField. So to garbage * collect old ValidationSupport object also we have to dump nameTextField with it. */ private void recreateNameTextField() { TextField newTextField = new TextField(); newTextField.setMaxWidth(250.0); newTextField.setPrefWidth(250.0); GUIUtil.replaceChildInPane(nameTextField, newTextField); nameTextField = newTextField; nameTextField.setDisable(!inputAllowed); // Let's not allow very long names UnaryOperator<Change> filter = c -> { if (c.getControlNewText().length() > 35) { logger.debug("The CuteElement's name is too long to pass the input filter."); return null; } return c; }; nameTextField.setTextFormatter(new TextFormatter<>(filter)); // Reset nameTextField on ESC key nameTextField.setOnKeyReleased(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent t) { if (t.getCode() == KeyCode.ESCAPE) { nameTextField.setText(originalName); // When root's parent is focused, second hit to Escape key will close panel root.getParent().requestFocus(); } } }); }
public LocalRepoPane(final LocalRepo localRepo) { this.localRepo = assertNotNull(localRepo, "localRepo"); this.repoSyncDaemon = RepoSyncDaemonLs.getRepoSyncDaemon(); this.repoSyncTimer = RepoSyncTimerLs.getRepoSyncTimer(); loadDynamicComponentFxml(LocalRepoPane.class, this); nameTextField.setTextFormatter(new TextFormatter<String>(new UnaryOperator<Change>() { @Override public Change apply(Change change) { String text = change.getText(); if (text.startsWith("_") && change.getRangeStart() == 0) return null; if (text.indexOf('/') >= 0) return null; return change; } })); bind(); updateActivities(); updateState(); updateNextSync(); updateSyncPeriodUi(); final EventHandler<? super MouseEvent> syncStateMouseEventFilter = event -> showSyncStateDialog(); syncStateStartedFinishedTextField.addEventFilter(MouseEvent.MOUSE_CLICKED, syncStateMouseEventFilter); syncStateSeverityLabel.addEventFilter(MouseEvent.MOUSE_CLICKED, syncStateMouseEventFilter); historyPaneSupport = new HistoryPaneSupport(this); tabPane.getSelectionModel().selectedItemProperty().addListener((InvalidationListener) observable -> createOrForgetUserRepoKeyListPane()); createOrForgetUserRepoKeyListPane(); }
public ValidityPane(final CreatePgpKeyParam createPgpKeyParam) { this.createPgpKeyParam = assertNotNull(createPgpKeyParam, "createPgpKeyParam"); //$NON-NLS-1$ loadDynamicComponentFxml(ValidityPane.class, this); validityNumberSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, Integer.MAX_VALUE)); validityNumberSpinner.valueProperty().addListener((InvalidationListener) observable -> { updateValiditySeconds(); updateComplete(); }); validityNumberSpinner.getEditor().setTextFormatter(new TextFormatter<String>(new UnaryOperator<Change>() { @Override public Change apply(Change change) { final String text = change.getControlNewText(); // We cannot accept an empty String, because the IntegerValueFactory runs into an NPE, then :-( try { Integer.parseInt(text); } catch (NumberFormatException x) { return null; } return change; } })); validityTimeUnitComboBox.setItems(FXCollections.observableArrayList(TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.DAY)); validityTimeUnitComboBox.setConverter(timeUnitStringConverter); validityTimeUnitComboBox.getSelectionModel().clearAndSelect(0); validityTimeUnitComboBox.valueProperty().addListener((InvalidationListener) observable -> updateValiditySeconds()); createPgpKeyParam.addPropertyChangeListener(CreatePgpKeyParam.PropertyEnum.validitySeconds, validitySecondsPropertyChangeListener); updateValidityNumberSpinner(); updateComplete(); }