Priority work in Java. (Does the object instantiate and run before the GUI is updated?)

I want the GUI to change the button title from "Go" to "Working ..." before the object is created and actually does the job. When done, I want the button name to switch to Go.

Here is the code:

private class convert implements ActionListener { public void actionPerformed(ActionEvent e) { JButton button = (JButton)e.getSource(); button.setText("Working..."); button.setEnabled(false); anObject name = new AnObject(); boolean result = name.methodName(chooser.getSelectedFile(),encoding); // A bunch of stuff was here but irrelevant to the question, // so it was removed to save room. button.setEnabled(true); button.setText("Go"); } 

What actually happens in practice, a name is created, a methodName is created, and the THEN button is updated on the screen, even though I told the virtual machine to change the name of the button first.

My working theory, given that I did not make this program a thread, this has something to do with operational priority or internal threading of the JVM, or something like that.

Any suggestions?

+6
source share
3 answers

I know that you have already made a decision, but since you are faced with the "frozen gui" syndrome, you definitely have a thread problem and invokeLater will not solve your problem. As noted above, extraneon, you need SwingWorker or some kind of background thread to solve this problem. In addition, I believe this is a good example of using AbstractAction, not an ActionListener. For instance:

 import java.awt.Dimension; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class Convert extends AbstractAction { private static final long SLEEP_TIME = 3000; // 3 seconds private String enabledText; private String disabledText; public Convert(String enabledText, String disabledText) { super(enabledText); this.enabledText = enabledText; this.disabledText = disabledText; } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (!(source instanceof JButton)) { return; } final JButton button = (JButton) source; setButtonEnabled(button, false); new SwingWorker<Void, Void>() { @Override protected Void doInBackground() throws Exception { // TODO: long-running code goes here. // Emulated by Thread.sleep(...) Thread.sleep(SLEEP_TIME); return null; } @Override protected void done() { setButtonEnabled(button, true); } }.execute(); } public void setButtonEnabled(JButton button, boolean enabled) { if (enabled) { button.setText(enabledText); button.setEnabled(true); } else { button.setText(disabledText); button.setEnabled(false); } } private static void createAndShowUI() { JFrame frame = new JFrame("Convert"); frame.getContentPane().add(new ConvertGui()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } @SuppressWarnings("serial") class ConvertGui extends JPanel { public ConvertGui() { add(new JButton(new Convert("GO", "Working..."))); } @Override public Dimension getPreferredSize() { return new Dimension(300, 200); } } 
+11
source

The ActionPerformed callback occurs in the event stream, and normally nothing in the GUI will be updated until it returns. If you want to update gui, do something and then update it again, you will need to update gui and create a stream and return. Then the thread will have to perform this action, and then execute SwingUtilities.invokeLater to update the gui.

+7
source

Try SwingUtilities.invokeLater () .

 private class convert implements ActionListener { public void actionPerformed(ActionEvent e) { final JButton button = (JButton)e.getSource(); button.setText("Working..."); button.setEnabled(false); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { anObject name = new AnObject(); boolean result = name.methodName(chooser.getSelectedFile(),encoding); // A bunch of stuff was here but irrelevant to the question, // so it was removed to save room. button.setEnabled(true); button.setText("Convert"); } }); } 
+5
source

Source: https://habr.com/ru/post/893447/


All Articles