versión versiones update soporte descargas descargar anteriores java swing

versiones - Java 8u161/8u162 hace que la aplicación Swing use la CPU



java versión 6 (2)

Al ejecutar una aplicación Swing en 8u161 u 8u162 y enfocar está en un JTextField, usted cambia a otra aplicación (como Chrome) y vuelve a usar la CPU. Procesamiento de eventos ocupado).

Simplemente ejecuta la aplicación y cambia un par de veces. Si hago clic en la pestaña del panel de pestañas, el uso de la CPU cae a 0 como se esperaba.

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); }); } }

He intentado mirar la cola de eventos para ver qué sucede y se parece mucho a que el último evento se procesa una y otra vez

Si agrego esto al programa anterior, obtengo una gran cantidad de java.awt.event.InvocationEvent [INVOCATION_DEFAULT, runnable = sun.awt.windows.WInputMethod ...

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

Funciona bien en 8u151, 8u152 y 9.0.4

Tengo muchos clientes que se están actualizando a 161 y tienen este problema, por lo que cualquier sugerencia para una solución es muy apreciada. He archivado un error con Oracle

JProfiler muestra esto:

Parece funcionar bien en 8u172 b02

Según openjdk esto fue introducido por 8184016 y corregido por 8183504


¿Están sus clientes utilizando métodos de entrada? Si no necesita habilitar los métodos de entrada, le sugiero que lo deshabilite.

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); } }); } }


Probablemente esto sea bastante feo, pero es una solución que creé en función de mis observaciones sobre cuándo se produce el error. Estoy seguro de que es posible crear una solución alternativa mejor con una mejor comprensión de por qué exactamente se produce el error en primer lugar.

Básicamente evita que se centre cualquier JTextComponent cuando lo primero que se enfoca en la ventana, transfiere el foco a otro componente ( upFocusCycle(component) para mí se coloca en el marco / diálogo) y luego lo transfiere nuevamente al JTextComponent . No sé si esto funcionará en todos los casos o tal vez incluso romperá algo, pero parece funcionar para mí. Utilizar a su propio riesgo, obviamente.

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; } } } }); } }

También probé cosas como eliminar el enfoque por completo o solo lanzar una PropertyVetoException , pero solo en realidad enfocarme en otra cosa antes de que JTextComponent pareciera funcionar.

Estoy buscando JTextComponent porque el error ocurrió para mí tanto con JTextField como con JTextArea , aunque no estoy seguro de que otras clases también estén afectadas.