Java – where is the calling event scheduling thread?

I read that all code for constructing swing components and handling events must be run by event dispatch thread I know how to use swingutilities Invoker () method Consider the following code, where GUI initialization is done in the main method itself

public class GridBagLayoutTester extends JPanel implements ActionListener {   
    public GridBagLayoutTester() {
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        JButton button = new JButton("Testing");
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        button.addActionListener(this);
        add(button,gbc);
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("event handler code");
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("GridBagLayoutDemo");
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);    
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(new GridBagLayoutTester(),BorderLayout.CENTER);
        frame.setSize(800,600);
        frame.pack();
        frame.setVisible(true);
        System.out.println("Exiting");
    }   
}

How does this code work? We are building JFrame and calling other methods of the host in the main thread. I don't understand where EDT is here (what code does it execute?) The constructor of gridbaglayouttester class is also called from the main method, which means EDT does not run it

In short

When does American Eastern time begin? (if you start EDT while running this code, how does the JVM start EDT)? > Does the event handler code for the button run on EDT?

Solution

The code works well because you are building the framework in the main thread before EDT has the opportunity to interact with it Technically, you shouldn't do this, but technically you can in this specific case, because you can't interact with JFrame until it becomes visible

The main thing to understand is that swing components are not thread safe This means that they cannot be modified by multiple threads at the same time This is addressed by ensuring that all modifications come from EDT

EDT is a thread dedicated to user interaction Any event generated from the user is always run on the EDT Any user interface updates running on EDT For example, when you call component When repaint(), it can be called from any thread This only requires setting a flag to mark the component as requiring paint, and EDT operates in the next cycle

EDT starts automatically and is closely related to the system implementation It works well within the JVM Usually, it is related to a single thread in the window system that handles user interaction Of course, this is very implementation dependent Well, you don't have to worry about this You just need to know – if you interact with any swing component, execute it on EDT

Again, there is another important thing If you want to process or block external resources for any long time, and you are going to perform this operation in response to user generated events, you must schedule EDT to run in your own thread If you cannot perform this operation, the user interface will be blocked while waiting for a long time for the process to run Good examples are loading from a file, reading from a database, or interacting with a network You can use swingutilities Iseventdispatchthread() method to test whether you are on EDT (which can be used to create neutral methods that can be called from any thread)

The following are two code snippets that I often use when writing swing programming to deal with EDT:

void executeOffEDT() {
  if (SwingUtilities.isEventDispatchThread()) {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        OutsideClass.this.executeOffEDTInternal();
      }
    };
    new Thread(r).start();
  } else {
    this.executeOffEDTInternal();
  }
}

void executeOnEDT() {
  if (SwingUtilities.isEventDispatchThread()) {
    this.executeOnEDTInternal();
  } else {
    Runnable r = new Runnable() {
      @Override
      public void run() {
        OutsideClass.this.executeOnEDTInternal();
      }
    };
    SwingUtilities.invokelater(r);
  }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>