modules/controls/src/main/java/com/sun/javafx/scene/control/behavior/TextFieldBehavior.java
Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
@@ -23,10 +23,11 @@
* questions.
*/
package com.sun.javafx.scene.control.behavior;
+import com.sun.javafx.scene.control.Properties;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.WeakChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
@@ -34,19 +35,21 @@
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.TextField;
+import javafx.scene.control.skin.TextFieldSkin;
+import com.sun.javafx.scene.control.skin.Utils;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.stage.Screen;
import javafx.stage.Window;
import com.sun.javafx.PlatformUtil;
import com.sun.javafx.geom.transform.Affine3D;
-import com.sun.javafx.scene.control.skin.TextFieldSkin;
-import com.sun.javafx.scene.text.HitInfo;
+
+import static javafx.scene.control.skin.TextFieldSkin.TextPosInfo;
import static com.sun.javafx.PlatformUtil.isMac;
import static com.sun.javafx.PlatformUtil.isWindows;
/**
* Text field behavior.
@@ -57,14 +60,14 @@
private TwoLevelFocusBehavior tlFocus;
private ChangeListener<Scene> sceneListener;
private ChangeListener<Node> focusOwnerListener;
public TextFieldBehavior(final TextField textField) {
- super(textField, TEXT_INPUT_BINDINGS);
+ super(textField);
contextMenu = new ContextMenu();
- if (IS_TOUCH_SUPPORTED) {
+ if (Properties.IS_TOUCH_SUPPORTED) {
contextMenu.getStyleClass().add("text-input-context-menu");
}
handleFocusChange();
@@ -101,22 +104,22 @@
if (textField.getScene() != null) {
textField.getScene().focusOwnerProperty().addListener(weakFocusOwnerListener);
}
// Only add this if we're on an embedded platform that supports 5-button navigation
- if (com.sun.javafx.scene.control.skin.Utils.isTwoLevelFocus()) {
+ if (Utils.isTwoLevelFocus()) {
tlFocus = new TwoLevelFocusBehavior(textField); // needs to be last.
}
}
@Override public void dispose() {
if (tlFocus != null) tlFocus.dispose();
super.dispose();
}
private void handleFocusChange() {
- TextField textField = getControl();
+ TextField textField = getNode();
if (textField.isFocused()) {
if (PlatformUtil.isIOS()) {
// special handling of focus on iOS is required to allow to
// control native keyboard, because nat. keyboard is poped-up only when native
@@ -170,11 +173,11 @@
public void setTextFieldSkin(TextFieldSkin skin) {
this.skin = skin;
}
@Override protected void fire(KeyEvent event) {
- TextField textField = getControl();
+ TextField textField = getNode();
EventHandler<ActionEvent> onAction = textField.getOnAction();
ActionEvent actionEvent = new ActionEvent(textField, null);
textField.fireEvent(actionEvent);
textField.commitValue();
@@ -184,11 +187,11 @@
}
}
@Override
protected void cancelEdit(KeyEvent event) {
- TextField textField = getControl();
+ TextField textField = getNode();
if (textField.getTextFormatter() != null) {
textField.cancelEdit();
} else {
forwardToParent(event);
}
@@ -201,11 +204,11 @@
@Override protected void replaceText(int start, int end, String txt) {
skin.replaceText(start, end, txt);
}
@Override protected void deleteFromLineStart() {
- TextField textField = getControl();
+ TextField textField = getNode();
int end = textField.getCaretPosition();
if (end > 0) {
replaceText(0, end, "");
}
@@ -233,12 +236,11 @@
private boolean focusGainedByMouseClick = false;
private boolean shiftDown = false;
private boolean deferClick = false;
@Override public void mousePressed(MouseEvent e) {
- TextField textField = getControl();
- super.mousePressed(e);
+ TextField textField = getNode();
// We never respond to events if disabled
if (!textField.isDisabled()) {
// If the text field doesn't have focus, then we'll attempt to set
// the focus and we'll indicate that we gained focus by a mouse
// click, which will then NOT honor the selectOnFocus variable
@@ -253,17 +255,17 @@
// only if there is no selection should we see the caret
// setCaretOpacity(if (textInputControl.dot == textInputControl.mark) then 1.0 else 0.0);
// if the primary button was pressed
if (e.isPrimaryButtonDown() && !(e.isMiddleButtonDown() || e.isSecondaryButtonDown())) {
- HitInfo hit = skin.getIndex(e.getX(), e.getY());
+ TextPosInfo hit = skin.getIndex(e.getX(), e.getY());
String text = textField.textProperty().getValueSafe();
- int i = com.sun.javafx.scene.control.skin.Utils.getHitInsertionIndex(hit, text);
+ int i = Utils.getHitInsertionIndex(hit, text);
final int anchor = textField.getAnchor();
final int caretPosition = textField.getCaretPosition();
if (e.getClickCount() < 2 &&
- (IS_TOUCH_SUPPORTED ||
+ (Properties.IS_TOUCH_SUPPORTED ||
(anchor != caretPosition &&
((i > anchor && i < caretPosition) || (i < anchor && i > caretPosition))))) {
// if there is a selection, then we will NOT handle the
// press now, but will defer until the release. If you
// select some text and then press down, we change the
@@ -305,11 +307,11 @@
contextMenu.hide();
}
}
@Override public void mouseDragged(MouseEvent e) {
- final TextField textField = getControl();
+ final TextField textField = getNode();
// we never respond to events if disabled, but we do notify any onXXX
// event listeners on the control
if (!textField.isDisabled() && !deferClick) {
if (e.isPrimaryButtonDown() && !(e.isMiddleButtonDown() || e.isSecondaryButtonDown())) {
if (!(e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown())) {
@@ -318,12 +320,11 @@
}
}
}
@Override public void mouseReleased(MouseEvent e) {
- final TextField textField = getControl();
- super.mouseReleased(e);
+ final TextField textField = getNode();
// we never respond to events if disabled, but we do notify any onXXX
// event listeners on the control
if (!textField.isDisabled()) {
setCaretAnimating(false);
if (deferClick) {
@@ -334,20 +335,20 @@
setCaretAnimating(true);
}
}
@Override public void contextMenuRequested(ContextMenuEvent e) {
- final TextField textField = getControl();
+ final TextField textField = getNode();
if (contextMenu.isShowing()) {
contextMenu.hide();
} else if (textField.getContextMenu() == null) {
double screenX = e.getScreenX();
double screenY = e.getScreenY();
double sceneX = e.getSceneX();
- if (IS_TOUCH_SUPPORTED) {
+ if (Properties.IS_TOUCH_SUPPORTED) {
Point2D menuPos;
if (textField.getSelection().getLength() == 0) {
skin.positionCaret(skin.getIndex(e.getX(), e.getY()), false);
menuPos = skin.getMenuPosition();
} else {
@@ -357,86 +358,62 @@
menuPos = skin.getMenuPosition();
}
}
if (menuPos != null) {
- Point2D p = getControl().localToScene(menuPos);
- Scene scene = getControl().getScene();
+ Point2D p = getNode().localToScene(menuPos);
+ Scene scene = getNode().getScene();
Window window = scene.getWindow();
Point2D location = new Point2D(window.getX() + scene.getX() + p.getX(),
window.getY() + scene.getY() + p.getY());
screenX = location.getX();
sceneX = p.getX();
screenY = location.getY();
}
}
- skin.populateContextMenu(contextMenu);
+ populateContextMenu(contextMenu);
double menuWidth = contextMenu.prefWidth(-1);
- double menuX = screenX - (IS_TOUCH_SUPPORTED ? (menuWidth / 2) : 0);
+ double menuX = screenX - (Properties.IS_TOUCH_SUPPORTED ? (menuWidth / 2) : 0);
Screen currentScreen = com.sun.javafx.util.Utils.getScreenForPoint(screenX, 0);
Rectangle2D bounds = currentScreen.getBounds();
if (menuX < bounds.getMinX()) {
- getControl().getProperties().put("CONTEXT_MENU_SCREEN_X", screenX);
- getControl().getProperties().put("CONTEXT_MENU_SCENE_X", sceneX);
- contextMenu.show(getControl(), bounds.getMinX(), screenY);
+ getNode().getProperties().put("CONTEXT_MENU_SCREEN_X", screenX);
+ getNode().getProperties().put("CONTEXT_MENU_SCENE_X", sceneX);
+ contextMenu.show(getNode(), bounds.getMinX(), screenY);
} else if (screenX + menuWidth > bounds.getMaxX()) {
double leftOver = menuWidth - ( bounds.getMaxX() - screenX);
- getControl().getProperties().put("CONTEXT_MENU_SCREEN_X", screenX);
- getControl().getProperties().put("CONTEXT_MENU_SCENE_X", sceneX);
- contextMenu.show(getControl(), screenX - leftOver, screenY);
+ getNode().getProperties().put("CONTEXT_MENU_SCREEN_X", screenX);
+ getNode().getProperties().put("CONTEXT_MENU_SCENE_X", sceneX);
+ contextMenu.show(getNode(), screenX - leftOver, screenY);
} else {
- getControl().getProperties().put("CONTEXT_MENU_SCREEN_X", 0);
- getControl().getProperties().put("CONTEXT_MENU_SCENE_X", 0);
- contextMenu.show(getControl(), menuX, screenY);
+ getNode().getProperties().put("CONTEXT_MENU_SCREEN_X", 0);
+ getNode().getProperties().put("CONTEXT_MENU_SCENE_X", 0);
+ contextMenu.show(getNode(), menuX, screenY);
}
}
e.consume();
}
-// var hadFocus = false;
-// var focused = bind (skin.control as TextInputControl).focused on replace old {
-// if (focused) {
-// hadFocus = true;
-// focusChanged(true);
-// } else {
-// if (hadFocus) {
-// focusChanged(false);
-// }
-// hadFocus = false;
-// }
-// }
-//
-// protected function focusChanged(f:Boolean):Void {
-// def textInputControl = skin.control as TextInputControl;
-// if (f and textInputControl.selectOnFocus and not focusGainedByMouseClick) {
-// textInputControl.selectAll();
-// } else if (not f) {
-// textInputControl.commit();
-// focusGainedByMouseClick = false;
-// displaySoftwareKeyboard(false);
-// }
-// }
-//
- protected void mouseSingleClick(HitInfo hit) {
+ protected void mouseSingleClick(TextPosInfo hit) {
skin.positionCaret(hit, false);
}
- protected void mouseDoubleClick(HitInfo hit) {
- final TextField textField = getControl();
+ protected void mouseDoubleClick(TextPosInfo hit) {
+ final TextField textField = getNode();
textField.previousWord();
if (isWindows()) {
textField.selectNextWord();
} else {
textField.selectEndOfNextWord();
}
}
- protected void mouseTripleClick(HitInfo hit) {
- getControl().selectAll();
+ protected void mouseTripleClick(TextPosInfo hit) {
+ getNode().selectAll();
}
// Enumeration of all types of text input that can be simulated on
// touch device, such as iPad. Type is passed to native code and
// native text component is shown. It's used as workaround for iOS