本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

JRuby 和 Swing 事件调度线程

发布于2023-09-25 20:21     阅读(950)     评论(0)     点赞(27)     收藏(2)


Java Swing 教程使用 SwingUtilities.invokeLater 创建 GUI(如此处这里解释了为什么这样做- 大多数 Swing 对象都不是线程安全的。另一方面,我见过的大多数 JRuby Swing 示例只是设置脚本中可见的顶部框架(就像这里- 存档中的“guis”目录)。

问题是,在 JRuby 脚本中创建应用程序顶部框架时,我是否应该遵循使用 SwingUtilities.invokeLater() 的 Java 模式?

我有两个 JRuby 脚本,一个使用 SwingUtilities.invokeLater(),另一个不使用:

java_import javax.swing.JFrame
java_import javax.swing.SwingUtilities
java_import java.awt.Dimension
java_import javax.swing.JButton
JavaThread = java.lang.Thread

class TopFrame < JFrame

  def initialize
    super
    init_components()

    pack()
    set_visible(true)

    puts '----------------------------------------'
    puts 'In JFrame constructor:'
    puts "Thread name: #{JavaThread.current_thread.name}"
    puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
    JavaThread.current_thread.thread_group.list

  end

  def init_components()

    set_default_close_operation(JFrame::EXIT_ON_CLOSE)
    set_preferred_size(Dimension.new(400, 300))

    button = JButton.new('Button')
    button.add_action_listener do |event|
      puts '----------------------------------------'
      puts 'In action listener:'
      puts "Thread name: #{JavaThread.current_thread.name}"
      puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
      JavaThread.current_thread.thread_group.list
    end

    get_content_pane.add(button)

  end

end

puts '----------------------------------------'
puts 'Before SwingUtilties.invokeLater():'
puts "Thread name: #{JavaThread.current_thread.name}"
puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
JavaThread.current_thread.thread_group.list

SwingUtilities.invoke_later do
  TopFrame.new
end

puts '----------------------------------------'
puts 'After SwingUtilities.invokeLater():'
puts "Thread name: #{JavaThread.current_thread.name}"
puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
JavaThread.current_thread.thread_group.list

输出是:

----------------------------------------
Before SwingUtilties.invokeLater():
Thread name: main
Is event dispatch thread: false
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Ruby-0-JIT-1,1,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]
----------------------------------------
After SwingUtilities.invokeLater():
Thread name: main
Is event dispatch thread: false
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Ruby-0-JIT-1,1,main]
    Thread[AWT-EventQueue-0,6,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]
----------------------------------------
In JFrame constructor:
Thread name: AWT-EventQueue-0
Is event dispatch thread: true
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[AWT-EventQueue-0,6,main]
    Thread[DestroyJavaVM,5,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]
----------------------------------------
In action listener:
Thread name: AWT-EventQueue-0
Is event dispatch thread: true
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[AWT-EventQueue-0,6,main]
    Thread[DestroyJavaVM,5,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]

在调用 SwingUtilities.invokeLater() 之前,EDT 不存在。在 SwingUtilities.invokeLater() 之后,EDT 存在,并且与当前线程不同。在 JFrame 构造函数和 JButton 操作事件侦听器中,EDT 是当前线程。

另一个脚本不使用 SwingUtilities.invokeLater():

java_import javax.swing.JFrame
java_import javax.swing.SwingUtilities
java_import java.awt.Dimension
java_import javax.swing.JButton
JavaThread = java.lang.Thread

puts '----------------------------------------'
puts 'Before JFrame.new():'
puts "Thread name: #{JavaThread.current_thread.name}"
puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
JavaThread.current_thread.thread_group.list

frame = JFrame.new()

frame.set_default_close_operation(JFrame::EXIT_ON_CLOSE)
frame.set_preferred_size(Dimension.new(400, 300))

button = JButton.new('Button')
button.add_action_listener do |event|
  puts '----------------------------------------'
  puts 'In action listener:'
  puts "Thread name: #{JavaThread.current_thread.name}"
  puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
  JavaThread.current_thread.thread_group.list
end

frame.get_content_pane.add(button)
frame.pack()

puts '----------------------------------------'
puts 'Before JFrame.setVisible():'
puts "Thread name: #{JavaThread.current_thread.name}"
puts "Is event dispatch thread: #{SwingUtilities.event_dispatch_thread?}"
JavaThread.current_thread.thread_group.list

frame.set_visible(true)

输出是:

----------------------------------------
Before JFrame.new():
Thread name: main
Is event dispatch thread: false
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Ruby-0-JIT-1,1,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]
----------------------------------------
Before JFrame.setVisible():
Thread name: main
Is event dispatch thread: false
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Ruby-0-JIT-1,1,main]
    Thread[AWT-EventQueue-0,6,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]
----------------------------------------
In action listener:
Thread name: AWT-EventQueue-0
Is event dispatch thread: true
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[AWT-EventQueue-0,6,main]
    Thread[DestroyJavaVM,5,main]
    java.lang.ThreadGroup[name=Ruby Threads#11483240,maxpri=10]

EDT是在JFrame构造函数之后创建的,不是当前线程。在 JButton 事件监听器中,EDT 是当前线程。


解决方案


consider JRuby as any other JVM language ... with no special care for Swing/AWT conventions built-in - only a "new" syntax for writing a Swing GUI. as such do care about EDT just like you would in Java.



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:http://www.javaheidong.com/blog/article/677411/295f5fb9a52f90046546/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

27 0
收藏该文
已收藏

评论内容:(最多支持255个字符)