[jdk20] RFR: 8301989: new javax.swing.text.DefaultCaret().setBlinkRate(N) results in NPE [v2]

Alexander Zuev kizune at openjdk.org
Wed Feb 8 21:17:52 UTC 2023


On Wed, 8 Feb 2023 21:02:08 GMT, Phil Race <prr at openjdk.org> wrote:

>> Suppose I have this code
>> 
>> Caret c = new DefaultCaret()
>> c.setBlinkRate(50);
>> c.install(editableJComponent);
>> 
>> BEFORE 4512626 the JDK code looked like this
>> 
>>      if (rate != 0) {
>>             if (flasher == null) {
>>                 flasher = new Timer(rate, handler);
>>             }
>>             flasher.setDelay(rate);
>>         }
>> 
>> 
>> With your fix it looks like this
>> 
>>      if (rate != 0) {
>>             if (component != null && component.isEditable()) {
>>                if (flasher == null) {
>>                    flasher = new Timer(rate, handler);
>>                }
>>              }
>>         }
>> 
>> 
>> So with my sample application code there's a change that my blink rate is completely lost.
>
> So it seems that in such a case, "savedBlinkRate" is still set and that is used to both report the value of blink rate *and* create & start a Timer when it is needed.
> It is a little hard to follow through all those "when it is needed" cases but if we are attached to an enabled & editable component when  focusGained() is called it should then start the flasher timer.

Using the simple code like this one:
```        Caret caret = new DefaultCaret();
        caret.setBlinkRate(10);
        JFrame frame = new JFrame("test");
        JTextArea area = new JTextArea(null, "Some text to make it non-empty", 5, 40);
        area.setEditable(false);
        area.setCaret(caret);
        frame.setLayout(new BorderLayout());
        frame.add(area, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        SwingUtilities.invokeAndWait(() -> area.requestFocus(false));
        SwingUtilities.invokeAndWait(() -> area.setEditable(true));
        SwingUtilities.invokeAndWait(() -> {
            System.out.println(area.getCaret().getBlinkRate());
        });

i tested many possible combinations to see that the blink rate specified in setBlinkRate is preserved and not being overwritten by some code. In some corner cases the cursor does not blink despite reporting the correct blink rate until the focus is lost and regained - but that is still better than the version before JDK-4512626 where in the same corner case the cursor is not visible until the focus is lost and gained again. There is a bug JDK-8299048 that tracks the corner case i am talking about.

-------------

PR: https://git.openjdk.org/jdk20/pull/122



More information about the client-libs-dev mailing list