java – 调用事件调度线程在哪里?
我读到构造Swing组件和处理事件的所有代码必须由Event Dispatch Thread运行.我了解如何通过使用SwingUtilities.invokeLater()方法来实现.考虑以下代码,其中GUI初始化在main方法本身完成
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"); } } 这段代码如何正常工作?我们正在构建JFrame并在主线程中调用主机的其他方法.我不明白这里EDT在哪里(它执行什么代码?). GridBagLayoutTester类的构造函数也是从main方法调用的,这意味着EDT没有运行它. 简而言之 美国东部时间是什么时候开始? (如果在运行此代码的同时启动EDT时,JVM是如何启动EDT的)? 解决方法
代码的工作原理很好,因为您正在构建主线程中的框架,在EDT有机会与之进行交互之前.在技??术上,你不应该这样做,但技术上你可以在这种具体情况下,因为你不能与JFrame交互,直到它变得可见.
要了解的主要方面是Swing组件不是线程安全的.这意味着它们不能同时被多个线程修改.这通过确保所有修改来自EDT来解决. EDT是一个致力于用户交互的线程.从用户生成的任何事件总是在EDT上运行.任何在EDT上运行的用户界面更新.例如,当您调用Component.repaint()时,可以从任何线程调用.这只需要设置一个标志,将组件标记为需要油漆,而EDT在下一个循环中进行操作. EDT自动启动,并且与系统实现相当紧密.它在JVM内处理得很好.通常,它与处理用户交互的窗口系统中的单个线程相关.当然,这是非常依赖于实现.好的是,你不用担心这个.您只需要知道 – 如果您与任何Swing组件交互,请在EDT上执行. 同样,还有另外一件事情很重要.如果您要对外部资源进行任何长时间处理或阻塞,并且您将要响应用户生成的事件来执行此操作,则必须安排在自己的线程中运行EDT.如果您无法执行此操作,则会在等待长时间处理运行时导致用户界面被阻止.优秀的示例是从文件加载,从数据库读取,或与网络交互.您可以使用SwingUtilities.isEventDispatchThread()方法来测试您是否在EDT上(可用于创建可以从任何线程调用的中性方法). 下面是两个代码片段,我在编写处理EDT的Swing编程时经常使用: 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); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – Eclipse – 尝试基于WSDL文件创建Web Se
- Java break语句详解
- No converter found capable of converting from
- json字符串与Object、List、Map的互转工具类
- 去除ArrayList集合中重复字符串元素方式_思路:创
- 为什么在Java中这是可能的:this.getClass().get
- java – 使用Eclipse创建Scala项目,sbteclipse
- springcloud 熔断器Hystrix的具体使用
- java – 在本地模式下运行storm-starter拓扑时出
- Java concurrency线程池之Callable和Future_动力