Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4193995

JTextField keeps focus, precluding Default Btn from rcvg ActionEvts

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.2.0, 1.2.1
    • client-libs
    • 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)
      ======================================================================

            idk Igor Kushnirskiy (Inactive)
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: