-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
1.2.0, 1.2.1
-
generic, x86
-
generic, windows_nt
Name: krT82822 Date: 12/01/98
Hello,
I'm using JDK v1.2b4 on WinNT v4.0, SP3. I've included a small sample
program that (nicely) illustrates two problems.
Here's an overview of the problems:
The program removes the VK_ENTER key from the JTextField's Keymap and
sets a JButton as the "default" button. If the JTextField has the focus
when the user presses the ENTER key, the ActionListener for the JButton
is activated rather than the ActionListener for the JTextField. The
program is behaving correctly, but only for the initial LaF. When the
LaF changes, the JTextField's ActionListener starts receiving
ActionEvents, not the JButton. There's also a problem with the caret
not being drawn. Please read on for more details.
The easiest way to explain the problems is to to walk you through the
sample program. The sample program takes a command line parameter to
indicate the initial LaF:
1 = Metal
2 = CDE/Motif
3 = Windows
Do this:
1. Run the program with a command line parameter of 1.
2. Type some text in the JTextField and press ENTER a few times.
3. Notice the output from System.out. Pressing the ENTER key is firing
ActionEvents in the JButton (so far, so good).
4. Change the LaF to Windows by using the shortcut key combination,
ALT-3.
5. *** PROBLEM 1: The JTextField does not draw the caret. Even though
the JTextField still has the focus, no caret is drawn.
6. Even though the caret is invisible, you can still type text in the
JTextField. Do so.
7. Press the ENTER key a few times.
8. *** PROBLEM 2: The JTextField is now receiving the ActionEvents, not
the JButton.
9. Change the LaF back to Metal by pressing Alt-1.
10. Again, the caret is still invisible but you can still type text in
the JTextField. Do so.
11. Press the ENTER key a few times.
12. Now the JButton is receiving ActionEvents again.
PLEASE NOTE:
------------
It turns out that if you change the LaF by pulling down the "Appearance"
menu and selecting a new LaF (rather than using a shortcut key), the
caret *is* drawn correctly. Using the shortcut keys, however, seems to
make the caret invisible.
Given the fact that the JButton is the "default" button and the ENTER
key has been removed from the JTextField keymap, shouldn't the JButton
*always* receive ActionEvents when the JTextField has the focus,
regardless of the current LaF?
import com.sun.java.swing.*;
import java.awt.*;
import java.awt.event.*;
class NetHound{
private static final JFrame mainFrame = new JFrame("NetHound");
private static final JTextField textField = new JTextField(12);
private static final JButton button = new JButton("Default Button");
private static final JPanel panel = new JPanel(new FlowLayout(), false);
public static void main(String[] args){
if(args.length != 1){
System.err.println("Command line parm specifies initial LaF. Must be in [1,3]:\n" +
"1 --> Metal\n2 --> CDE/Motif\n3 --> Windows\n\n");
System.exit(1);
}
// Listen for the main window to close.
mainFrame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
evt.getWindow().dispose();
System.exit(0);
}
});
// Just for grins, we create an ActionListener for the JTextField and the JButton...
ActionListener actionListener = new ActionListener(){
public void actionPerformed(ActionEvent evt){
String source = evt.getSource() == button ? "*** button" : "+++textField";
System.out.println("ActionEvent on --> " + source);
}
};
panel.add(textField);
textField.addActionListener(actionListener);
panel.add(button);
button.addActionListener(actionListener);
mainFrame.getContentPane().add(panel, BorderLayout.CENTER);
// Call method to construct the "Appearance" menu containing the LaF options.
buildLaFMenu(args[0]);
textField.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
textField.getKeymap().removeKeyStrokeBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
mainFrame.setBounds(50, 50, 300, 300);
mainFrame.setVisible(true);
// We had to wait until the mainFrame was realized, otherwise, getRootPane() returns
// null. Now we must call setDefaultButton() within the Swing event handler thread.
SwingUtilities.invokeLater(new Runnable(){
public void run(){
panel.getRootPane().setDefaultButton(button);
}
});
}
private static void buildLaFMenu(String initialLaF){
/*-------------------------------------------------------------------------------------------
* Build the "Appearance" menu. This menu simply contains items for the available LaFs.
* I've hardcoded the LaFs for this sample. In real life I would never do that!
-------------------------------------------------------------------------------------------*/
JMenuBar menuBar = new JMenuBar();
JMenu appearanceMenu = new JMenu("Appearance");
// Listen for a menu item to change the current LaF.
ActionListener LaFMenuListener = new ActionListener(){
public void actionPerformed(ActionEvent evt){
try{
AbstractButton button = (AbstractButton)evt.getSource();
UIManager.setLookAndFeel((String)button.getClientProperty("LaFClassName"));
}
catch(Exception exc){
System.err.println("Error in setting LaF...\n" + exc);
System.exit(1);
}
SwingUtilities.updateComponentTreeUI(mainFrame);
}
};
appearanceMenu.setMnemonic('A');
menuBar.add(appearanceMenu);
mainFrame.setJMenuBar(menuBar);
ButtonGroup bg = new ButtonGroup();
// Add menu items, one for each available LaF.
JCheckBoxMenuItem mi = new JCheckBoxMenuItem("Metal");
mi.putClientProperty("LaFClassName", "com.sun.java.swing.plaf.metal.MetalLookAndFeel");
mi.setMnemonic('M');
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, KeyEvent.ALT_MASK));
mi.addActionListener(LaFMenuListener);
bg.add(mi);
appearanceMenu.add(mi);
if(initialLaF.equals("1"))
mi.doClick();
mi = new JCheckBoxMenuItem("CDE/Motif");
mi.putClientProperty("LaFClassName", "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
mi.setMnemonic('C');
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2, KeyEvent.ALT_MASK));
mi.addActionListener(LaFMenuListener);
bg.add(mi);
appearanceMenu.add(mi);
if(initialLaF.equals("2"))
mi.doClick();
mi = new JCheckBoxMenuItem("Windows");
mi.putClientProperty("LaFClassName", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
mi.setMnemonic('W');
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.ALT_MASK));
mi.addActionListener(LaFMenuListener);
bg.add(mi);
appearanceMenu.add(mi);
if(initialLaF.equals("3"))
mi.doClick();
//-------------------------------------------------------------------------------------------
}
}
(Review ID: 37125)
======================================================================
Name: skT88420 Date: 06/15/99
This bug has been reported on earlier versions of jdk (versons
prior to 1.2) but it seems that the bug is being ignored.
This may seem like a trivial bug but it's an annoying one to
power users who want the feature and developers who don't like
the work around.
JRootPane.setDefaultButton(JButton b)
The defaultButton on a root pane never gets messaged
when a JTextField in the root pane has the focus.
Source:
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame
{
public Test()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
System.out.println(
"Unable to set Application look and feel to the System look and feel");
}
getContentPane().setLayout(new FlowLayout());
JTextField t1 = new JTextField(10);
JButton b1 = new JButton("Button 1");
JButton b2 = new JButton("Button 2");
getContentPane().add(t1);
getContentPane().add(b1);
getContentPane().add(b2);
getRootPane().setDefaultButton(b1);
pack();
show();
}
public static void main(String args[])
{
new Test();
}
}
(Review ID: 58084)
======================================================================
- relates to
-
JDK-4515750 JTextField & non-editable JTextArea bind return key - default btn not accessible
-
- Closed
-