Skip to content

Fix #1511: TextField.setAlignment(CENTER) is now accepted#5120

Merged
shai-almog merged 2 commits into
masterfrom
fix-1511-textfield-center-alignment
May 30, 2026
Merged

Fix #1511: TextField.setAlignment(CENTER) is now accepted#5120
shai-almog merged 2 commits into
masterfrom
fix-1511-textfield-center-alignment

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

Closes #1511. The 2015 reporter wanted a centre-aligned TextField with a NUMERIC constraint (PIN entry / score widgets / calculator-style inputs). TextField.setAlignment(Component.CENTER) had thrown IllegalArgumentException("CENTER alignment is not supported in TextField.") since the very first commit in 2012, so the reporter had to settle for TextArea (which accepts CENTER but does not enforce the NUMERIC constraint as tightly).

There is no technical reason for the restriction:

  • TextArea.setAlignment already accepts CENTER and just routes to Style.setAlignment like every other Component.
  • No special-case code in the focus caret, native edit overlay, or render path looked at the CENTER value with intent to reject it.

Dropping the IAE and delegating to super.setAlignment lets a numeric-constrained TextField be centred while keeping its constraint, exactly what the reporter asked for.

Test plan

  • New regression test TextFieldCenterAlignmentTest:
    • setAlignmentCenterIsAcceptedOnTextField: the IAE no longer fires, the underlying Style.getAlignment() is CENTER on both selected and unselected styles, and the NUMERIC constraint is preserved.
    • setAlignmentLeftRightAndCenterAllWork: round-trip through LEFT → CENTER → RIGHT.
  • Full TextField/TextArea sweep -- 64 tests including TextAreaTest, the TextFieldCaretColorTest#2780 and TextFieldHintStylingTest regression samples -- stays green.
  • ASCII-only sources verified.
  • CI verification.

Why I had to fix one test assertion mid-implementation

The first cut of the test asserted on tf.getAllStyles().getAlignment(). Component.getAllStyles() returns a proxy Style whose setAlignment fans out to the four sub-styles but does not update the proxy's own align field, so the proxy's getter always returned the original LEFT. Reading from getUnselectedStyle().getAlignment() / getSelectedStyle().getAlignment() is the correct round-trip and exposes the real behaviour the test cares about. That's a subtle gotcha worth flagging in the codebase but it is not part of #1511.

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 30, 2026

Compared 122 screenshots: 122 matched.

Native Android coverage

  • 📊 Line coverage: 12.84% (7478/58222 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.44% (37420/358465), branch 4.33% (1467/33850), complexity 5.42% (1762/32532), method 9.48% (1445/15249), class 15.57% (331/2126)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 12.84% (7478/58222 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.44% (37420/358465), branch 4.33% (1467/33850), complexity 5.42% (1762/32532), method 9.48% (1445/15249), class 15.57% (331/2126)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 880.000 ms
Base64 CN1 encode 188.000 ms
Base64 encode ratio (CN1/native) 0.214x (78.6% faster)
Base64 native decode 1015.000 ms
Base64 CN1 decode 312.000 ms
Base64 decode ratio (CN1/native) 0.307x (69.3% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 30, 2026

Compared 122 screenshots: 122 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 320 seconds

Build and Run Timing

Metric Duration
Simulator Boot 94000 ms
Simulator Boot (Run) 1000 ms
App Install 20000 ms
App Launch 64000 ms
Test Execution 314000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 718.000 ms
Base64 CN1 encode 2202.000 ms
Base64 encode ratio (CN1/native) 3.067x (206.7% slower)
Base64 native decode 530.000 ms
Base64 CN1 decode 1359.000 ms
Base64 decode ratio (CN1/native) 2.564x (156.4% slower)
Base64 SIMD encode 657.000 ms
Base64 encode ratio (SIMD/native) 0.915x (8.5% faster)
Base64 encode ratio (SIMD/CN1) 0.298x (70.2% faster)
Base64 SIMD decode 439.000 ms
Base64 decode ratio (SIMD/native) 0.828x (17.2% faster)
Base64 decode ratio (SIMD/CN1) 0.323x (67.7% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 57.000 ms
Image createMask (SIMD on) 9.000 ms
Image createMask ratio (SIMD on/off) 0.158x (84.2% faster)
Image applyMask (SIMD off) 122.000 ms
Image applyMask (SIMD on) 64.000 ms
Image applyMask ratio (SIMD on/off) 0.525x (47.5% faster)
Image modifyAlpha (SIMD off) 156.000 ms
Image modifyAlpha (SIMD on) 54.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.346x (65.4% faster)
Image modifyAlpha removeColor (SIMD off) 271.000 ms
Image modifyAlpha removeColor (SIMD on) 89.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.328x (67.2% faster)
Image PNG encode (SIMD off) 1562.000 ms
Image PNG encode (SIMD on) 2059.000 ms
Image PNG encode ratio (SIMD on/off) 1.318x (31.8% slower)
Image JPEG encode 938.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 30, 2026

Compared 122 screenshots: 122 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 182 seconds

Build and Run Timing

Metric Duration
Simulator Boot 63000 ms
Simulator Boot (Run) 1000 ms
App Install 11000 ms
App Launch 10000 ms
Test Execution 308000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 488.000 ms
Base64 CN1 encode 1575.000 ms
Base64 encode ratio (CN1/native) 3.227x (222.7% slower)
Base64 native decode 266.000 ms
Base64 CN1 decode 892.000 ms
Base64 decode ratio (CN1/native) 3.353x (235.3% slower)
Base64 SIMD encode 403.000 ms
Base64 encode ratio (SIMD/native) 0.826x (17.4% faster)
Base64 encode ratio (SIMD/CN1) 0.256x (74.4% faster)
Base64 SIMD decode 436.000 ms
Base64 decode ratio (SIMD/native) 1.639x (63.9% slower)
Base64 decode ratio (SIMD/CN1) 0.489x (51.1% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 57.000 ms
Image createMask (SIMD on) 9.000 ms
Image createMask ratio (SIMD on/off) 0.158x (84.2% faster)
Image applyMask (SIMD off) 174.000 ms
Image applyMask (SIMD on) 57.000 ms
Image applyMask ratio (SIMD on/off) 0.328x (67.2% faster)
Image modifyAlpha (SIMD off) 130.000 ms
Image modifyAlpha (SIMD on) 50.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.385x (61.5% faster)
Image modifyAlpha removeColor (SIMD off) 131.000 ms
Image modifyAlpha removeColor (SIMD on) 59.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.450x (55.0% faster)
Image PNG encode (SIMD off) 930.000 ms
Image PNG encode (SIMD on) 922.000 ms
Image PNG encode ratio (SIMD on/off) 0.991x (0.9% faster)
Image JPEG encode 534.000 ms

shai-almog and others added 2 commits May 30, 2026 20:32
TextField.setAlignment(int) had thrown IllegalArgumentException for
Component.CENTER since the initial commit in 2012. That blocked a
common use case the 2015 reporter ran into: a numeric-constraint
TextField that needs to be centred for PIN entry / score widgets /
calculator-style inputs. There is no technical reason for the
restriction -- TextArea.setAlignment already accepts CENTER and the
rendering pipeline routes through Style.setAlignment regardless.

Drop the IAE and delegate to super.setAlignment. The styling, focus
caret rendering and edit-mode native overlays all read the alignment
from the Style object exactly the same way they do for LEFT and
RIGHT; no special-case code looked at the CENTER value with intent to
reject it.

Closes #1511.

Adds maven/core-unittests/.../TextFieldCenterAlignmentTest.java with:
- setAlignmentCenterIsAcceptedOnTextField: the IAE no longer fires,
  the underlying Style's alignment field is CENTER, and the NUMERIC
  constraint is preserved.
- setAlignmentLeftRightAndCenterAllWork: round-trip through all three
  cardinal alignments.

Full TextField/TextArea sweep (64 tests) stays green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous commit on this branch removed the IllegalArgumentException
from TextField.setAlignment(CENTER) but left an override whose body was
just super.setAlignment(align). PMD's UselessOverridingMethod rule
fails the build on that pattern, so CI was red.

Delete the override entirely. TextArea.setAlignment now handles every
case identically (no LEFT/RIGHT/CENTER asymmetry), so dropping the
override gives the exact same behaviour and matches the rest of the
TextField API surface that simply inherits its TextArea implementation.
Test coverage stays identical via TextFieldCenterAlignmentTest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog force-pushed the fix-1511-textfield-center-alignment branch from 5cc73a0 to dfa077e Compare May 30, 2026 17:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 30, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog shai-almog merged commit 231a9f4 into master May 30, 2026
19 checks passed
@shai-almog shai-almog deleted the fix-1511-textfield-center-alignment branch May 30, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cant create a field aligned center with constraint numeric

1 participant