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

KeyboardFocusManager reports incorrect values in VetoableChange Event

    Details

    • Subcomponent:
    • CPU:
      generic, x86
    • OS:
      generic, windows_2000

      Description



      Name: boT120536 Date: 07/15/2001


      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

      When a VetoableChangeListener is installed on the default KeyboardFocusManager the components reported as old and new values of permanentFocusOwner (and FocusOwner) always identify one side as null, even in the simplest case. My veto decisions need the opposite component, as they are triggered by a focus movement out of a defined set of components. This functionality has only been available through deep hacks in the past, and even then with profound shortcomings. The new focus architecture promised to end all that, but needs the opposite component reported reliably. The opposite component is definitely available because the corresponding FocusEvent reports it correctly. The following test code creates a simple two component frame and reports the focus events.
      >>>>>>> Code starts
      import javax.swing.*;
      import java.awt.event.*;
      import java.awt.*;
      import java.beans.*;

      public class FocusBug extends JFrame {
          JTextField txt1 = new JTextField();
          JTextField txt2 = new JTextField();
          KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();

          public FocusBug() {
              mgr.addVetoableChangeListener("permanentFocusOwner", new Vetoable());
              txt1.setColumns(10);
              txt1.setName("Text1");
              txt1.setText("Text1");
              txt1.addFocusListener(new FocusAdapter() {
                  public void focusLost(FocusEvent e) {
                      System.out.println("Text1 Lost to: " + ((e.getOppositeComponent() == null) ? null : e.getOppositeComponent().getName()));
                  }
                  public void focusGained(FocusEvent e) {
                      System.out.println("Text1 Gained from: " + ((e.getOppositeComponent() == null) ? null : e.getOppositeComponent().getName()));
                  }
              });
              txt2.setColumns(10);
              txt2.setName("Text2");
              txt2.setText("Text2");
              txt2.addFocusListener(new FocusAdapter() {
                  public void focusLost(FocusEvent e) {
                      System.out.println("Text2 Lost to: " + ((e.getOppositeComponent() == null) ? null : e.getOppositeComponent().getName()));
                  }
                  public void focusGained(FocusEvent e) {
                      System.out.println("Text2 Gained from: " + ((e.getOppositeComponent() == null) ? null : e.getOppositeComponent().getName()));
                  }
              });
              this.getContentPane().setLayout(new BorderLayout());
              this.getContentPane().add(txt1, BorderLayout.WEST);
              this.getContentPane().add(txt2, BorderLayout.EAST);
          }
          public static void main(String[] args) {
              JFrame f = new FocusBug();
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.pack();
              f.setVisible(true);
          }
          public class Vetoable implements VetoableChangeListener {
              public Vetoable() {
              }
              public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException {
                  String oldName = (e.getOldValue() == null) ? null : ((JComponent)e.getOldValue()).getName();
                  String newName = (e.getNewValue() == null) ? null : ((JComponent)e.getNewValue()).getName();
                  System.out.println("Vetoable " + e.getPropertyName() + " old: " + oldName + " new: " + newName);
              }
          }
      }
      >>>>>>>> code ends

      When run, the first two lines of output (follows) are correct. The next four are generated by a simple tab or mouse click to move focus. Both PropertyChangeEvents should identify the old and new components in the transition. By the time the first lost focus Event has been delivered (with its opposite component correctly reported) it is too late to veto the transition.

      >>>>>>> output starts
      Vetoable permanentFocusOwner old: null new: Text1
      Text1 Gained from: null
      Vetoable permanentFocusOwner old: Text1 new: null
      Text1 Lost to: Text2
      Vetoable permanentFocusOwner old: null new: Text2
      Text2 Gained from: Text1
      >>>>>>>>>> output ends
      (Review ID: 128090)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                bonealsunw Bret O'neal (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: