Skip to content
Advertisement

JTextField render bug if Text-Not-Fitting (JDK 7 till 18)

JTextField has wrong text render on RIGHT_TO_LEFT component orientation

We need a workaround, since whenever JTextField is filled with text that contains:

  • Right to left text like Arabic,
  • Latin numbers,
  • and Latin text.

Then JTextField renders text parts at unexpected locations.

(It only renders right if the complete text Fits inside the JTextField.)

The text we use to reproduce is:

  • صندوق ۴۰×۳۰ پایه دار وایرنگ میتر تک فاز

Other info:

  • Above text is just name of a product, added inside an accounting software we created, but our users have match more render failures than we could reproduce.
  • We reported at: JDK-8194733
  • We have no experience with a custom-render in Java to make workaround, but render of entire text not considering the limit, and clipping that, should do the trick.

Source code for an executable test case:

//
// Like you may notice, below code shows simple JTextField, 
// but once you resize the Window smaller than the text Fits,
// then you experience numbers dancing (moving around randomly).
//
// And trying to select parts of text is even more fatal (random parts are rendered).
//
package test;

import java.awt.ComponentOrientation;

public class JavaBug extends javax.swing.JFrame {

    public static void main(String[] args) {
        JavaBug frame = new JavaBug();
        frame.show();
    }
    
    public JavaBug() {
        javax.swing.JTextField textField = new javax.swing.JTextField();
        
        textField.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
        
        // Below is just name of a product, added inside an accounting software.
        textField.setText("u0635u0646u062Fu0648u0642 u06F4u06F0×u06F3u06F0 u067Eu0627u06CCu0647 u062Fu0627u0631 u0648u0627u06CCu0631u0646u06AF u0645u06CCu062Au0631 u062Au06A9 u0641u0627u0632");
        textField.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        
        getContentPane().add(textField);
        pack();
        this.setLocationRelativeTo(null); //enusre get showed at screen center
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    }
}

Screen shots

Just running above code results to:
just run

After resize, to something less:
after resize


Development Kit or Runtime version:

  • java version “1.8.0_25”
  • Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
  • Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode)

Advertisement

Answer

You can try this

import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;

public class JavaBug extends javax.swing.JFrame {

    public static void main(String[] args) {
        JavaBug frame = new JavaBug();
        frame.show();
    }

    public JavaBug() {
        JTextPane textPane = new JTextPane();
        textPane.setEditorKit(new HTMLEditorKit());
        textPane.setText("<html><font size='+2'>u0635u0646u062Fu0648u0642 u06F4u06F0×u06F3u06F0 u067Eu0627u06CCu0647 u062Fu0627u0631 u0648u0627u06CCu0631u0646u06AF u0645u06CCu062Au0631 u062Au06A9 u0641u0627u0632</font></html>");
        textPane.getDocument().putProperty("i18n", Boolean.TRUE);
        JPanel noWrapPanel = new JPanel( new BorderLayout() );
        noWrapPanel.add( textPane );
        JScrollPane scrollPane = new JScrollPane( noWrapPanel );
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        /* without below right to left force there is an other bug when we press home and
         * try to navigate to end using left key it will never get at end and fall back at start. kind of crazy bug */
        java.util.Locale arabic = new java.util.Locale("ar", "KW");
        ComponentOrientation arabicOrientation = ComponentOrientation.getOrientation(arabic);
        textPane.applyComponentOrientation(arabicOrientation);

        getContentPane().add(scrollPane);
        pack();
        this.setLocationRelativeTo(null); //enusre get showed at screen center
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    }
}
7 People found this is helpful
Advertisement