while unity loop for java loops user-interface while-loop freeze

java - loop - unity 3d for each



La GUI se congela durante While Loop en Java (1)

http://i.stack.imgur.com/XvHm5.png

Cuando hago clic en el botón Activar, debería comenzar a enviar correos no deseados 1 a través de JTextField. En su lugar, toda la GUI se congela, incluido el botón de cerrar. Estoy usando un ciclo while que se detendrá cuando vuelva a hacer clic en el jButton. Como el jButton está congelado, no puedo detener este programa. He leído que Threads y Multithreading ayudarían, pero todos los tutoriales son demasiado complejos para que los pueda entender. Dicen que coloquen el bucle y la GUI en diferentes hilos. Quiero entender esto para arreglar otro programa en el que estoy trabajando, que es mucho más complejo. Es por eso que hice un simple ejemplo para mostrar mi problema.

http://i.stack.imgur.com/tbNAF.png

Así es como muestra el programa. (El jTextField ni siquiera está actualizado. Lo que estoy preguntando es si alguien sabe cómo arreglar esto, ya sea que use hilos o no. Mi código para este programa está a continuación.

public class whileLoop extends javax.swing.JFrame { public whileLoop() { initComponents(); } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jPanel1 = new javax.swing.JPanel(); jTextField1 = new javax.swing.JTextField(); jToggleButton1 = new javax.swing.JToggleButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jToggleButton1.setText("On"); jToggleButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jToggleButton1ActionPerformed(evt); } }); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jToggleButton1) .addGap(18, 18, 18) .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jToggleButton1)) .addContainerGap(12, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pack(); }// </editor-fold> private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) { if (jToggleButton1.isSelected()) { jToggleButton1.setText("Off"); while (jToggleButton1.isSelected()) { jTextField1.setText(jTextField1.getText() + "1"); } } else { jToggleButton1.setText("On"); } } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new whileLoop().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JPanel jPanel1; private javax.swing.JTextField jTextField1; private javax.swing.JToggleButton jToggleButton1; // End of variables declaration

}

El área principal del código es:

private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) { if (jToggleButton1.isSelected()) { jToggleButton1.setText("Off"); while (jToggleButton1.isSelected()) { jTextField1.setText(jTextField1.getText() + "1"); } } else { jToggleButton1.setText("On"); } }


Tienes un ciclo infinito. El estado del botón de alternar nunca cambia después de establecerse en verdadero.

La IU de Java (y toda la IU con la que he trabajado) está impulsada por un único hilo. La entrada del usuario se retroalimenta en este único hilo. La representación también se realiza en este único hilo.

La razón por la que el campo de texto nunca se actualiza es que el subproceso de UI nunca volverá a mostrar la pantalla, ya que está inmovilizado en su ciclo infinito.

Sí, necesita poner este código en un hilo separado, y comenzarlo cuando se seleccione el botón de alternar. Luego, debe actualizar el campo de texto de este hilo por separado. Mire en SwingWorker .