From a81aabac789872c793e3118cc38fbbb2aab331ee Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Mon, 13 Jul 2026 11:04:07 +0300 Subject: [PATCH] Fix #5370: honor TextField horizontal alignment while editing A right- (or center-) aligned TextField jumped to the left the moment editing started, because the native inline editor ignored the field's horizontal alignment on Android and in the JavaSE simulator. iOS already honored it (CodenameOne_GLViewController.m maps alignment 3->right, 4-> center), so those two ports drifted out of sync and produced the visible jump (and, with a hint, a right-aligned hint next to a left-placed cursor). Android (InPlaceEditView): set the EditText gravity from the field's absolute alignment instead of only flipping on isRTL(). The value is snapshotted into TextAreaData on the CN1 EDT (new absoluteAlignment field) so it is read safely off the EDT like the other cached properties. JavaSE simulator (editString): set the single-line Swing editor's horizontal alignment (JTextField / JPasswordField) from the field's absolute alignment. getAbsoluteAlignment() already resolves LEFT/RIGHT for RTL, so the prior RTL behavior is preserved. Co-Authored-By: Claude Opus 4.8 --- .../impl/android/InPlaceEditView.java | 24 +++++++++++++++---- .../com/codename1/impl/javase/JavaSEPort.java | 17 +++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Ports/Android/src/com/codename1/impl/android/InPlaceEditView.java b/Ports/Android/src/com/codename1/impl/android/InPlaceEditView.java index 5004e161737..f9bb4c141f5 100644 --- a/Ports/Android/src/com/codename1/impl/android/InPlaceEditView.java +++ b/Ports/Android/src/com/codename1/impl/android/InPlaceEditView.java @@ -651,6 +651,7 @@ static class TextAreaData { final int scrollX; final int scrollY; final int verticalAlignment; + final int absoluteAlignment; final int height; final int width; final int fontHeight; @@ -694,6 +695,10 @@ int getVerticalAlignment() { return verticalAlignment; } + int getAbsoluteAlignment() { + return absoluteAlignment; + } + boolean isRTL() { return isRTL; } @@ -733,6 +738,7 @@ String getHint() { paddingBottom = s.getPaddingBottom(); isTextField = (ta instanceof TextField); verticalAlignment = ta.getVerticalAlignment(); + absoluteAlignment = ta.getAbsoluteAlignment(); height = ta.getHeight(); width = ta.getWidth(); fontHeight = s.getFont().getHeight(); @@ -874,10 +880,20 @@ public boolean onActionItemClicked(ActionMode mode, mEditText.setLayoutParams(mEditLayoutParams); - if(textArea.isRTL()){ - mEditText.setGravity(Gravity.RIGHT | Gravity.TOP); - }else{ - mEditText.setGravity(Gravity.LEFT | Gravity.TOP); + // Honor the field's horizontal alignment (issue #5370) so a right- or + // center-aligned field doesn't jump to the left when the native editor + // takes over. getAbsoluteAlignment() already resolves LEFT/RIGHT for RTL, + // so it covers the previous RTL-only behavior too. + switch (textArea.getAbsoluteAlignment()) { // snapshot value, safe off the EDT + case Component.RIGHT: + mEditText.setGravity(Gravity.RIGHT | Gravity.TOP); + break; + case Component.CENTER: + mEditText.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); + break; + default: + mEditText.setGravity(Gravity.LEFT | Gravity.TOP); + break; } mEditText.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); diff --git a/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java b/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java index cd310f49673..8642d1d5d05 100644 --- a/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java +++ b/Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java @@ -9368,6 +9368,23 @@ public void run() { }); */ } + // Honor the field's horizontal alignment (issue #5370) so a right- or + // center-aligned field doesn't jump to the left when the native editor + // takes over. getAbsoluteAlignment() already resolves LEFT/RIGHT for RTL. + // Both JTextField and JPasswordField (a JTextField subclass) support this. + if (t instanceof JTextField) { + switch (((com.codename1.ui.TextArea)cmp).getAbsoluteAlignment()) { + case com.codename1.ui.Component.RIGHT: + ((JTextField)t).setHorizontalAlignment(JTextField.RIGHT); + break; + case com.codename1.ui.Component.CENTER: + ((JTextField)t).setHorizontalAlignment(JTextField.CENTER); + break; + default: + ((JTextField)t).setHorizontalAlignment(JTextField.LEADING); + break; + } + } swingT = t; textCmp = swingT; } else {