JDK-8156217 : Selected text is shifted on HiDPI display
  • Type: Bug
  • Component: client-libs
  • Affected Version: 9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-05-06
  • Updated: 2017-10-23
  • Resolved: 2016-10-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b143Fixed
Related Reports
Blocks :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Steps to reproduce:
- Run the code below on HiDPI display on Windows
- Select the text from the end to the beginning

The selected text is shifted than the original one.
----------------------
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class CheckTextSelection {

    private static final String TEXT = "aaaaaaaaaaaaaaaaaaaa";

    public static void main(String[] args) {
        SwingUtilities.invokeLater(CheckTextSelection::createAndShowGUI);
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setSize(300, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout());

        JTextField textField = new JTextField(TEXT);
        panel.add(textField);

        frame.getContentPane().add(panel);
        frame.setVisible(true);
    }
}
----------------------
Comments
The fix where reflection is used to detect is a method with floating point arguments overridden: http://cr.openjdk.java.net/~alexsch/8156217/webrev.06/all/ The discussion thread: http://mail.openjdk.java.net/pipermail/swing-dev/2016-September/006614.html
09-09-2016

To check the caret drawing using the modelToView() method run the DefaultCaretTest below on HiDPI display or with option -Dsun.java2d.uiScale=2: ---------------- import java.awt.*; import javax.swing.*; import javax.swing.text.*; public class DefaultCaretTest { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame(); frame.setSize(300, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(new BorderLayout()); JTextField textField = new JTextField("aaaaaaaaaaaaaaa"); textField.setFont(textField.getFont().deriveFont(28.0f)); textField.setCaretColor(Color.RED); textField.setCaret(new DefaultCaret()); panel.add(textField); frame.getContentPane().add(panel); frame.setVisible(true); }); } } ---------------- The caret is shifted to the left for odd number of chars (see attached caret-default-2x and caret-default-4x screenshots). The attached CaretFloatingPointAPITest code shows JTextComponent.modelToView2D() method using for custom caret drawing: -------------- static class CustomCaret implements Caret { @Override public void paint(Graphics g) { int dot = getDot(); Rectangle2D r = null; try { r = useFloatingPointAPI ? component.modelToView2D(dot) : component.modelToView(dot); } catch (BadLocationException e) { return; } // draw a caret using the given rectangle } } --------------- Selecting a radiobutton on the sample allows to choose JTextComponent.modelToView2D(dot) (dark green) and JTextComponent.modelToView(dot) (blue) for the caret drawing. The attached caret-custom-2x screenshot shows the difference between painting the custom caret using JTextComponent.modelToView2D(dot) and JTextComponent.modelToView(dot) methods.
30-08-2016

the remaining work to be done: the work is completed (see webrev http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/all/) the risk level: low a brief justification: Text selection is shifted on HiDPI display. Swing should use new added public API which is introduced by the fix JDK-8132119. However, it is necessary to add a new flag which allows to switch to new floating point API. best estimate of the date by which the feature will be complete: the 25th of August 2016
25-08-2016

The updated fix: webrev which contains only change in public API: http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/public-api webrev with contains all changes: http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/all Discussion: http://mail.openjdk.java.net/pipermail/swing-dev/2016-August/006473.html
15-08-2016

The proposed fix: http://cr.openjdk.java.net/~alexsch/8156217/webrev.00/
06-05-2016