-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
6u10
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0_10-rc2"
Java(TM) SE Runtime Environment (build 1.6.0_10-rc2-b31)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
JTextComponent.getActions() method is supposed to specify the list of commands/actions for the text editor component, which will be augmented to the plugged-in ui specific actions.
We have a scenario, where we want to override the default JTextField.notifyAction (when user presses ENTER key on a FormattedTextField) for a set of JFormattedTextFields. For this purpose, we subclass JFormattedTextField and override this getActions() method with our custom TextAction for JTextField.notifyAction. Now if we use this subclassed JFormattedTextField, everything works fine as expected. But in our application the default JFormattedTextField could also be used. So if we have both the default and customized JFormattedTextFields, our custom notify action is not working on our customized JFormattedTextFields.
On debugging, we found that BasicTextUI uses these actions to specify the UI actionmap for all instances of the ui class JFormattedTextField (or for that matter any type of JTextComponents). Rather it should be used for each instances of JTextComponents. So it will only use the getActions() of the text editor component, for which the the UI class is created first and will ignore the getActions of other textComponents.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the testcase below
2. It will show 2 JFormattedTextFields. Tab to second textField with text "MyFormattedTextField"
3. Press "ENTER" key
4. Nothing is printed in the console.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When you press ENTER key on MyFormattedTextField, "Custom Action of MyFormattedTextField" should be printed in the console.
ACTUAL -
"Custom Action of MyFormattedTextField" is not outputted to the console.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.event.ActionEvent;
import javax.swing.Action;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.TextAction;
public class SwingTextBug extends JPanel
{
public SwingTextBug()
{
// if we create MyFormattedTextField first, then our getActions are
// picked up by the UI class
JFormattedTextField text1 = new JFormattedTextField("JFormattedTextField");
MyFormattedTextField text2 = new MyFormattedTextField("MyFormattedTextField");
// Workaround - uncomment the line below to make it work
// _configureEditorAction(text2);
add(text1);
add(text2);
}
private void _configureEditorAction(JFormattedTextField field)
{
field.getActionMap().put(JTextField.notifyAction, new CommitAction());
}
private class MyFormattedTextField extends JFormattedTextField
{
public MyFormattedTextField(Object o)
{
super(o);
}
public Action[] getActions()
{
// this will not work. this getActions are not picked up
Action[] actions = new Action[]{new CommitAction()};
return TextAction.augmentList(super.getActions(), actions);
}
}
// Custom Action
private class CommitAction extends TextAction
{
public CommitAction()
{
super(JTextField.notifyAction);
}
public void actionPerformed(ActionEvent ae)
{
System.out.println("Custom Action of MyFormattedTextField");
}
}
public static void main(String args[])
{
JFrame fr = new JFrame("SwingTextBug");
fr.add(new SwingTextBug());
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.pack();
fr.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of overriding getActions(), we can change the action map of all the JFormattedTextFields using getActionMap() and putting the action into component's action map.
In the testcase, uncomment the line - "_configureEditorAction(text2); "inside the constructor of the testcase class.
java version "1.6.0_10-rc2"
Java(TM) SE Runtime Environment (build 1.6.0_10-rc2-b31)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
JTextComponent.getActions() method is supposed to specify the list of commands/actions for the text editor component, which will be augmented to the plugged-in ui specific actions.
We have a scenario, where we want to override the default JTextField.notifyAction (when user presses ENTER key on a FormattedTextField) for a set of JFormattedTextFields. For this purpose, we subclass JFormattedTextField and override this getActions() method with our custom TextAction for JTextField.notifyAction. Now if we use this subclassed JFormattedTextField, everything works fine as expected. But in our application the default JFormattedTextField could also be used. So if we have both the default and customized JFormattedTextFields, our custom notify action is not working on our customized JFormattedTextFields.
On debugging, we found that BasicTextUI uses these actions to specify the UI actionmap for all instances of the ui class JFormattedTextField (or for that matter any type of JTextComponents). Rather it should be used for each instances of JTextComponents. So it will only use the getActions() of the text editor component, for which the the UI class is created first and will ignore the getActions of other textComponents.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the testcase below
2. It will show 2 JFormattedTextFields. Tab to second textField with text "MyFormattedTextField"
3. Press "ENTER" key
4. Nothing is printed in the console.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When you press ENTER key on MyFormattedTextField, "Custom Action of MyFormattedTextField" should be printed in the console.
ACTUAL -
"Custom Action of MyFormattedTextField" is not outputted to the console.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.event.ActionEvent;
import javax.swing.Action;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.TextAction;
public class SwingTextBug extends JPanel
{
public SwingTextBug()
{
// if we create MyFormattedTextField first, then our getActions are
// picked up by the UI class
JFormattedTextField text1 = new JFormattedTextField("JFormattedTextField");
MyFormattedTextField text2 = new MyFormattedTextField("MyFormattedTextField");
// Workaround - uncomment the line below to make it work
// _configureEditorAction(text2);
add(text1);
add(text2);
}
private void _configureEditorAction(JFormattedTextField field)
{
field.getActionMap().put(JTextField.notifyAction, new CommitAction());
}
private class MyFormattedTextField extends JFormattedTextField
{
public MyFormattedTextField(Object o)
{
super(o);
}
public Action[] getActions()
{
// this will not work. this getActions are not picked up
Action[] actions = new Action[]{new CommitAction()};
return TextAction.augmentList(super.getActions(), actions);
}
}
// Custom Action
private class CommitAction extends TextAction
{
public CommitAction()
{
super(JTextField.notifyAction);
}
public void actionPerformed(ActionEvent ae)
{
System.out.println("Custom Action of MyFormattedTextField");
}
}
public static void main(String args[])
{
JFrame fr = new JFrame("SwingTextBug");
fr.add(new SwingTextBug());
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.pack();
fr.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Instead of overriding getActions(), we can change the action map of all the JFormattedTextFields using getActionMap() and putting the action into component's action map.
In the testcase, uncomment the line - "_configureEditorAction(text2); "inside the constructor of the testcase class.