web-dev-qa-db-fra.com

Java 8u161/8u162 permet à l'application Swing d'utiliser le processeur

Lorsque vous exécutez une application Swing sur 8u161 ou 8u162 et que le focus est dans un JTextField et que vous passez à une autre application (comme Chrome), l'utilisation de la CPU de l'application passe à 15% sur mon PC Windows 10 à 8 cœurs occupé à traiter des événements).

Il suffit d’exécuter l’application et de basculer plusieurs fois ..__ Si je clique sur l’onglet dans le volet à onglets, l’utilisation de l’UC tombe à 0 comme prévu. 

public class Test {
  public static void main(String... args) {
    SwingUtilities.invokeLater(() -> {
      JFrame f = new JFrame("Test");
      JTabbedPane tp = new JTabbedPane();
      tp.addTab("tab 1", new JTextField(20));
      f.add(tp);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.pack();
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

J'ai essayé de regarder la file d'attente des événements pour voir ce qui se passe et il semble que le dernier événement soit traité encore et encore

Si j'ajoute ceci au programme ci-dessus, j'obtiens beaucoup de Java.awt.event.InvocationEvent [INVOCATION_DEFAULT, exécutable = Sun.awt.windows.WInputMethod ...

Toolkit.getDefaultToolkit().getSystemEventQueue().Push(new EventQueue(){
  @Override protected void dispatchEvent(AWTEvent event) {
    System.out.println(event);
    super.dispatchEvent(event);
  }
});

Fonctionne bien sur 8u151, 8u152 et 9.0.4

Beaucoup de clients qui passent à la version 161 et rencontrent ce problème. Toute suggestion de solution de contournement est donc très appréciée . J'ai déjà signalé un bogue avec Oracle

JProfiler montre ceci:  enter image description here

Semble fonctionner correctement sur 8u172 b02

Selon openjdk cela a été introduit par 8184016 et corrigé par 8183504

18
Brian S.

Vos clients utilisent-ils des méthodes de saisie? Si vous n'avez pas besoin d'activer les méthodes de saisie, je suggère que vous puissiez le désactiver.

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              JFrame f = new JFrame("Test");
              JTabbedPane tp = new JTabbedPane();
              JTextField tf = new JTextField();
              tf.enableInputMethods(false); // disable IM
              tp.addTab("tab 1", tf);
              f.add(tp);
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.pack();
              f.setLocationRelativeTo(null);
              f.setVisible(true);
            }
        });
    }
}
0
ino2yoshi

C’est probablement assez moche, mais c’est une solution de contournement que j’ai créée à partir de mes observations sur la date du bogue. Je suis sûr qu'il est possible de créer une meilleure solution de contournement en comprenant mieux pourquoi le bogue survient en premier lieu.

Cela empêche fondamentalement toute JTextComponent d'être focalisée car la première chose après que la fenêtre soit focalisée, transfère le focus sur un autre composant (upFocusCycle(component) pour ma place dans le cadre/la boîte de dialogue), puis la renvoie à la JTextComponent. Je ne sais pas si cela fonctionnera dans tous les cas ou peut-être même casse quelque chose, mais cela semble fonctionner pour moi. Utilisez à vos propres risques évidemment.

public class JTextFieldTest {

    public static final void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            // Install workaround, without this the bug occurs
            installTextComponentFocusWorkaround();

            JFrame window = new JFrame("Test");
            window.setLocationByPlatform(true);
            window.add(new JButton("Button"), BorderLayout.CENTER);
            window.add(new JTextField(), BorderLayout.SOUTH);
            window.pack();
            window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            window.setVisible(true);
        });
    }

    public static void installTextComponentFocusWorkaround() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addVetoableChangeListener(new VetoableChangeListener() {

            private boolean rejectNext = false;
            private JComponent target;

            @Override
            public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
                if (evt.getNewValue() != null) {
                    if (evt.getPropertyName().equals("focusOwner")) {
                        if (evt.getNewValue() instanceof JTextComponent) {
                            if (rejectNext) {
                                JComponent component = (JComponent) evt.getNewValue();
                                KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle(component);
                                target = component;
                                System.out.println("Rejected JTextComponent focus");
                                throw new PropertyVetoException("Rejected JTextComponent focus", evt);
                            }
                        } else {
                            rejectNext = false;
                            if (target != null) {
                                System.out.println("Temp focus: " + evt.getNewValue());
                                target.requestFocus();
                                target = null;
                            }
                        }
                    } else if (evt.getPropertyName().equals("focusedWindow")) {
                        System.out.println("Window focused");
                        rejectNext = true;
                    }
                }
            }
        });
    }

}

J'ai aussi essayé des choses comme effacer complètement le focus ou seulement lancer une PropertyVetoException, mais seulement concentrer quelque chose d'autre avant que JTextComponent ne semble fonctionner.

Je cherche JTextComponent parce que le bogue s'est produit pour moi avec à la fois JTextField et JTextArea, bien que je ne sois pas sûr que d'autres classes soient également affectées.

0
user2375667