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

SwingNode does not keep focus when there are multiple of them

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Manjaro Linux
      OpenJDK Runtime Environment Corretto-21.0.3.9.1
      Oracle OpenJDK 22.0.2

      A DESCRIPTION OF THE PROBLEM :
      When requestFocus() is called for a SwingNode, the SwingNode and its content gain focus, then shortly after (within less than a second), they both lose focus.
      This behavior occurs when a Pane has at least two SwingNode children with content, and after requestFocus() has already been called for one of the SwingNodes.
      There seems to be no way to stop this behavior once it has started.

      I suspect that this is related to the bug report JDK-8334114 from bugs.openjdk.org

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Set up a stage with a scene and pane.
      2. Add two SwingNodes to the pane.
      3. Set the contents of those SwingNodes with swing components, preferably ones where the viewer can tell right away when focus is gained and lost, such as JTextField.
      4. Call requestFocus() for one of the SwingNodes through the result of an EventHandler.
      5. Call requestFocus() on the other SwingNode the same way. The problem may already have appeared in step 4.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The SwingNode and its content keep the focus that they gain.
      ACTUAL -
      The SwingNode and its content lose the focus that they gain, almost immediately.

      ---------- BEGIN SOURCE ----------
      public class Main extends Application {
        private Pane scenePane;

        @Override
        public void start(Stage stage) {
          scenePane = new Pane();

          Scene scene = new Scene(scenePane, 100, 100);
          stage.setScene(scene);

          stage.show();

          JTextField jTextField1 = new JTextField("JTextField 1");
          jTextField1.setName("JTextField 1");
          JTextField jTextField2 = new JTextField("JTextField 2");
          jTextField2.setName("JTextField 2");

          FocusListener focusListener = new FocusListener() {
            @Override
            public void focusGained(java.awt.event.FocusEvent e) {
              System.out.println("Focus gained: " + e.getComponent().getName());
            }

            @Override
            public void focusLost(java.awt.event.FocusEvent e) {
              System.out.println("Focus lost: " + e.getComponent().getName() + ", new focus owner: " + java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());
            }
          };

          jTextField1.addFocusListener(focusListener);
          jTextField2.addFocusListener(focusListener);

          SwingNode swingNode1 = new SwingNode();
          SwingNode swingNode2 = new SwingNode();

          Platform.runLater(() -> {
            scenePane.getChildren().add(swingNode1);
            scenePane.getChildren().add(swingNode2);
          });

          swingNode2.setTranslateY(30);

          SwingUtilities.invokeLater(() -> {
            swingNode1.setContent(jTextField1);
            swingNode2.setContent(jTextField2);
          });

          scenePane.addEventFilter(MouseEvent.ANY, this::handleMouseEvent);
        }

        private void handleMouseEvent(MouseEvent event) {
          if (event.getEventType() == MouseEvent.MOUSE_CLICKED) {
            if (event.getTarget() instanceof Node node) {
              node.requestFocus();
            }
          }
        }

        public static void main(String[] args) {
          launch();
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Using a focusListener added to the Swing component, call event.getComponent().requestFocus() when focus is lost.

      This workaround has many undesired side effects, such as making the caret in JTextArea blink abnormally. It also makes certain Swing components practically unusable, such as JComboBox.

      FREQUENCY : always


        1. capture.mkv
          876 kB
        2. Test.java
          2 kB

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: