swing开始使用摇摆


备注

Swing已被JavaFX取代 。 Oracle通常建议使用JavaFX开发新的应用程序。仍然:在可预见的未来,Java将支持Swing。 JavaFX还与Swing很好地集成,以便顺利过渡应用程序。

强烈建议在事件调度线程上使用大部分Swing组件。很容易忘记将GUI设置捆绑到invokeLater调用中。从Java文档:

Swing事件处理代码在称为事件派发线程的特殊线程上运行。大多数调用Swing方法的代码也在这个线程上运行。这是必要的,因为大多数Swing对象方法都不是“线程安全的”:从多个线程调用它们会冒线程干扰或内存一致性错误。一些Swing组件方法在API规范中标记为“线程安全”;这些可以从任何线程安全地调用。必须从事件派发线程调用所有其他Swing组件方法。忽略此规则的程序可能在大多数情况下正常运行,但会遇到难以重现的不可预测的错误。

此外,除非有很好的理由, 始终确保你叫setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)否则你有可能会要处理内存泄漏,如果你忘了销毁JVM。

“你好,世界!”在兼容性的窗口标题上

使用java.lang.Runnable 我们创建了“Hello World!” Java用户可以使用的示例,其版本可以追溯到1.2版本:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Main {
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run(){
                JFrame frame = new JFrame("Hello World!");
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setSize(200, 100);
                frame.setVisible(true);
            }
        });
    }
}
 

“你好,世界!”与lambda的窗口标题

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Hello World!");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setSize(200, 100);
            frame.setVisible(true);
        });
    }
}
 

main 方法内:
在第一行调用SwingUtilities.invokeLater ,并将一个带有code () -> {...} 块的lambda表达式传递给它。这将执行EDT上传递的lambda表达式,它是Event Dispatch Thread的缩写,而不是主线程。这是必要的,因为在lambda表达式的代码块中,将创建和更新Swing组件。

在lambda表达式的代码块内:
在第一行,使用new JFrame("Hello World!") 创建一个名为frame 的新JFrame 实例。这将创建一个带有“Hello World!”的窗口实例。在它的标题。然后在第二行, frame 被配置为EXIT_ON_CLOSE 。否则窗口将被关闭,但程序的执行将保持活动状态。第三行使用setSize 方法将frame 实例配置为宽度为200像素,高度为100像素。到目前为止,执行都不会显示任何内容。只有在第四行调用setVisible(true) 后, frame 实例才会配置为出现在屏幕上。

用按钮递增

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

/**
 * A very simple Swing example.
 */
public class SwingExample {
    /**
     * The number of times the user has clicked the button.
     */
    private long clickCount;
    
    /**
     * The main method: starting point of this application.
     *
     * @param arguments the unused command-line arguments.
     */
    public static void main(final String[] arguments) {
        new SwingExample().run();
    }

    /**
     * Schedule a job for the event-dispatching thread: create and show this
     * application's GUI.
     */
    private void run() {
        SwingUtilities.invokeLater(this::createAndShowGui);
    }
    
    /**
     * Create the simple GUI for this application and make it visible.
     */
    private void createAndShowGui() {
        // Create the frame and make sure the application exits when the user closes
        // the frame.
        JFrame mainFrame = new JFrame("Counter");
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        // Add a simple button and label.
        JPanel panel = new JPanel();
        JButton button = new JButton("Click me!");
        JLabel label = new JLabel("Click count: " + clickCount);
        panel.add(button);
        panel.add(label);
        mainFrame.getContentPane().add(panel);
        
        // Add an action listener to the button to increment the count displayed by
        // the label.
        button.addActionListener(actionEvent -> {
            clickCount++;
            label.setText("Click count: " + clickCount);
        });
        
        // Size the frame.
        mainFrame.setBounds(80, 60, 400, 300);
        //Center on screen
        mainFrame.setLocationRelativeTo(null);
        //Display frame
        mainFrame.setVisible(true);
    }
}
 

结果

标有“Click me!”的按钮按下点击次数将增加1:

运行程序