[jdk20] RFR: 4512626: Non-editable JTextArea provides no visual indication of keyboard focus [v2]
Alexander Zvegintsev
azvegint at openjdk.org
Fri Dec 16 01:33:06 UTC 2022
On Thu, 15 Dec 2022 07:29:32 GMT, Alexander Zuev <kizune at openjdk.org> wrote:
>> Set the text caret to be visible but not blinking on the non-editable text area. Fix the regression test that becames unstable after the change.
>
> Alexander Zuev has updated the pull request incrementally with one additional commit since the last revision:
>
> Fixed MultiSelectionText so it is now stable on Linux
> Removed both fixed tests from ProblemList
src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java line 389:
> 387: } else {
> 388: if (getBlinkRate() != 0) {
> 389: savedBlinkRate = getBlinkRate();
Look like this can override blink rate set by user:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
public class CaretThing {
static JFrame frame;
static JTextField textField;
static Robot robot;
static JButton button;
static void printBlinkRate() {
System.err.println("Caret blink rate: " + textField.getCaret().getBlinkRate());
}
static void requestFocus(Component component) throws InterruptedException, InvocationTargetException {
robot.waitForIdle();
robot.delay(300);
SwingUtilities.invokeAndWait(() -> {
System.err.println("Requesting focus on " + component);
printBlinkRate();
component.requestFocus();
printBlinkRate();
});
}
static void changeEditable() throws InterruptedException, InvocationTargetException {
robot.waitForIdle();
robot.delay(300);
SwingUtilities.invokeAndWait(()-> {
System.err.println("Changing editable");
printBlinkRate();
textField.setEditable(!textField.isEditable());
printBlinkRate();
});
}
public static void main(String[] args) throws Exception {
robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(50);
SwingUtilities.invokeAndWait(() -> {
frame = new JFrame("Hey");
frame.setLocationRelativeTo(null);
textField = new JTextField("Some long field value");
textField.setEditable(false);
frame.setLayout(new BorderLayout());
frame.add(textField, BorderLayout.NORTH);
button = new JButton("Button");
button.addActionListener((e)-> printBlinkRate());
frame.add(button, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
button.requestFocus();
textField.getCaret().setBlinkRate(2500);
});
requestFocus(textField);
requestFocus(button); // comment this to get 0 blink rate on editable field
changeEditable();
requestFocus(textField);
SwingUtilities.invokeAndWait(CaretThing::printBlinkRate);
}
}
Running the sample above at least two possible misbehaviors(tested on Linux):
* you will receive blink rate `500` instead of user set `2500`
* but if you comment `requestFocus(button);` line then blink rate will be `0` (it shows non-blinking cursor)
<hr>
Other than that I am worried about `getBlinkRate()` does not return the same value as passed to`setBlinkRate()` (e.g. case when component is not editable, possible JCK issue?)
src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java line 1050:
> 1048: flasher = new Timer(rate, handler);
> 1049: }
> 1050: flasher.setDelay(rate);
Coming back to negative rate, looks like this changes the previous behavior:
Before the fix it did throw IAE in all cases:
https://github.com/openjdk/jdk20/blob/ca39eb906692568347e7f264520593188f9276cf/src/java.desktop/share/classes/javax/swing/Timer.java#L397-L406
After the fix IAE is thrown only if component is editable<br>
In case of non-editable and may throw it way later after `setEditable(true)` call and focus gain.
-------------
PR: https://git.openjdk.org/jdk20/pull/21
More information about the client-libs-dev
mailing list