我试图准确理解 JButton 对象的工作原理。
我创建了下面扩展 JFrame 的 SampleFrame 对象。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SampleFrame extends JFrame implements ActionListener{
SampleFrame() {
JButton button = new JButton("Hello");
add(button);
button.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Hello");
}
public static void main(String[] args) {
new SampleFrame().setVisible(true);
}
}
我知道
add(button)
正在将 JButton 对象添加到 JFrame,而 button.AddActionLister(this)
正在将 SampleFrame 对象添加到该事件的一组侦听器,因此每次按下按钮时都会调用其 actionPerformed
方法。我不明白的是这个方法actionPerformed
到底是如何被调用的?这是被调用的某个线程吗?抱歉,如果这听起来太天真,我对 Java(和线程)不太熟悉。
不确定这是否与此有关,但是当我关闭框架时,代码仍然显示为在控制台中运行。这向我表明存在某种并行运行的“while 循环”。
让我们重写您的示例代码,以符合通常的 Swing 应用程序方法,如 Oracle 免费提供的 Swing 教程
中的
HelloWorldSwing
类所示。
public class OneButtonSwingApp
{
/**
* Create & show GUI. For thread safety, invoke from the event-dispatching thread.
*/
private static void createAndShowGUI ( )
{
// Create and set up the window.
JFrame frame = new JFrame( "One Button Example" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// Widgets
JLabel timeLabel = new JLabel( "Now: " + Instant.now( ) );
JButton tellTimeButton = new JButton( "Tell time" );
// Behavior
tellTimeButton.addActionListener( ( ActionEvent actionEvent ) -> { timeLabel.setText( "Now: " + Instant.now( ) ); } );
// Arrange
frame.setLayout( new FlowLayout( ) );
frame.getContentPane( ).add( timeLabel );
frame.getContentPane( ).add( tellTimeButton );
// Display the window.
frame.pack( );
frame.setVisible( true );
}
public static void main ( String[] args )
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(
new Runnable( )
{
public void run ( )
{
createAndShowGUI( );
}
} );
}
}
每个 Java 应用程序都在线程中启动以执行
main
方法。
Swing 应用程序有一个附加线程。该线程专用于运行 GUI。请参阅 Oracle 教程:事件调度线程。
在我们的代码中,我们使用
SwingUtilities.invokeLater
来执行其他事件调度线程的一些代码。 我们向该方法传递一个实现 Runnable
接口的匿名类的对象。需要实现run
方法来履行Runnable
的合同。
在现代 Java 中,我们可以使用
方法引用来简化
main
方法。
public static void main ( String[] args )
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater( OneButtonSwingApp :: createAndShowGUI );
}