Просто хотел получить ответ на этот вопрос для элементов управления TextField в JavaFX. Я уверен, что то же самое можно применить и к другим элементам управления текстовым вводом. Я получил эту идею, просмотрев некоторый код, который включал изменение цвета каретки по умолчанию с использованием подкласса класса TextFieldSkin
. Если вы внимательно посмотрите, суперкласс TextFieldSkin
содержит ссылку на экземпляр Path
, который представляет курсор в защищенном поле с именем caretPath
. Хотя это своего рода хакерское решение, оно предоставляет разработчикам абсолютные координаты Caret гораздо более безопасным способом, чем большинство хаков, которые я видел.
public class TextFieldCaretControlSkin extends TextFieldSkin {
public TextFieldCaretControlSkin(TextField textField, Stage stage) {
super(textField);
Popup popup = new Popup();
// Make the popup appear to the right of the caret
popup.setAnchorLocation(PopupWindow.AnchorLocation.CONTENT_BOTTOM_LEFT);
// Make sure its position gets corrected to stay on screen if we go out of screen
popup.setAutoFix(true);
// Add list view (mock autocomplete popup)
popup.getContent().add(new ListView<String>());
// listen for changes in the layout bounds of the caret path
caretPath.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
@Override
public void changed(ObservableValue<? extends Bounds> observable,
Bounds oldValue, Bounds newValue) {
popup.hide();
// get the caret's x position relative to the textfield.
double x = newValue.getMaxX();
// get the caret's y position relative to the textfield.
double y = newValue.getMaxY();
Point2D p = caretPath.localToScene(x, y);
/*
* If the coordinates are negatives then the Path is being
* redrawn and we should just skip further processing.
*/
if (x == -1.0 || y == -1.0)
return;
// show the popup at these absolute coordinates.
popup.show(textField,
p.getX() + caretPath.getScene().getX() +
caretPath.getScene().getWindow().getX(),
p.getY() + caretPath.getScene().getY() +
caretPath.getScene().getWindow().getY() -
newValue.getHeight()); // put the popup on top of the caret
}
});
}
}
Чтобы использовать, вам нужно будет встроить это в какой-то подкласс элемента управления вводом текста и не забудьте сделать textField.setSkin(new TextFieldCaretControlSkin(textField))
. Возможно, есть лучшие способы сделать это, поскольку я не эксперт по JavaFX, но я просто хотел поделиться этим решением с остальным миром на случай, если оно даст некоторое представление.
Надеюсь это поможет!
person
Nadeem Douba
schedule
21.05.2015