Java Swing学习笔记(1)
1. Hello World与程序详解
1.1 Hello World程序代码
参考:http://www.runoob.com/w3cnote/java-swing-demo-intro.html
package com.company;
import javax.swing.*;
public class Main {
private static void createAndShowGUI() {
// 确保一个漂亮的外观风格
JFrame.setDefaultLookAndFeelDecorated(true);
// 创建及设置窗口
JFrame frame = new JFrame("HelloWorldSwing"); //窗口标题
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 添加 "Hello World" 标签
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
// 显示窗口
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
执行效果:
1.2 代码详解
首先看函数createAndShowGUI()
,这个函数用于设置和显示UI。
这个函数的调用是新建了一个Runnable对象,并使用了invokeLater方法来进行调用。
Swing是线程不安全的,因此涉及到UI操作的代码,都需要使用javax.swing.SwingUtilities.invokeLater()
来在事件分发线程里执行。(类比Android中只能在主线程里对UI进行更新)
接下来看函数内部。
JFrame.setDefaultLookAndFeelDecorated(true);
本代码用于设置UI窗口的界面效果。
如果改成false则会出现这样的界面:
JFrame frame = new JFrame("HelloWorldSwing"); //窗口标题
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
这两行代码新建了一个窗体,并设置了窗体关闭的行为。
新建一个JFrame对象时,其构造函数传入的字符串为窗体的标题。
setDefaultCloseOperation()
方法是设置该窗体关闭时的行为。
在JFrame类里,有4个相关的常量:
/**
* The do-nothing default window close operation.
*/
public static final int DO_NOTHING_ON_CLOSE = 0;
/**
* The hide-window default window close operation
*/
public static final int HIDE_ON_CLOSE = 1;
/**
* The dispose-window default window close operation.
* <p>
* <b>Note</b>: When the last displayable window
* within the Java virtual machine (VM) is disposed of, the VM may
* terminate. See <a href="../../java/awt/doc-files/AWTThreadIssues.html">
* AWT Threading Issues</a> for more information.
* @see java.awt.Window#dispose()
* @see JInternalFrame#dispose()
*/
public static final int DISPOSE_ON_CLOSE = 2;
/**
* The exit application default window close operation. Attempting
* to set this on Windows that support this, such as
* <code>JFrame</code>, may throw a <code>SecurityException</code> based
* on the <code>SecurityManager</code>.
* It is recommended you only use this in an application.
*
* @since 1.4
* @see JFrame#setDefaultCloseOperation
*/
public static final int EXIT_ON_CLOSE = 3;
这四个常量的效果如下:
DO_NOTHING_ON_CLOSE
:窗口无法关闭。
HIDE_ON_CLOSE
:窗口消失,但是没有正式退出(只是隐藏窗口)。在Java IDE的Run窗口中看不到退出的显示,在任务管理器(或Tasklist)中能够看到Java.exe在运行。
DISPOSE_ON_CLOSE
:窗口隐藏并释放,如果应用程序中还存在未释放的窗口,应用程序继续运行。此时释放了窗口占用的资源(一般用于多窗口应用程序?)。若不存在(即释放了最后一个窗口),应用程序退出。
EXIT_ON_CLOSE
:使用System.exit(0)
函数,退出整个程序。
相关的代码在JFrame.java里的processWindowEvent()
函数里。
protected void processWindowEvent(final WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
switch (defaultCloseOperation) {
case HIDE_ON_CLOSE:
setVisible(false);
break;
case DISPOSE_ON_CLOSE:
dispose();
break;
case EXIT_ON_CLOSE:
// This needs to match the checkExit call in
// setDefaultCloseOperation
System.exit(0);
break;
case DO_NOTHING_ON_CLOSE:
default:
}
}
}
接下来是动态添加控件和标签:
// 添加 "Hello World" 标签
JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
显示窗口相关代码:
// 显示窗口
frame.pack();
frame.setVisible(true);
pack()
方法用于设置窗体能正好显示所有控件。
setVisible()
方法设置窗体可见性。
最后再来看main()函数。
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
将涉及UI的操作用Runnable包装,并用invokeLater()
方法交给时间分发线程执行。
和该方法相对的是invokeAndWait()
方法。
两者的区别是:
invokeLater()
方法不会等待事件执行完毕,即返回时可能事件并未执行。
invokeAndWait()
方法会等待事件执行完毕后返回,可能会带来线程安全的问题。不推荐使用。
2. 使用IntelliJ IDEA的GUI绘制工具绘制UI
新建项目,File —— New —— GUI Form,弹出窗口如下:
输入欲新建的窗体名字,选择Create bound class创建关联类,确定,就进入了窗体编辑页面。
编辑好窗体如图:
回到java文件中,按Alt+Insert,弹出Generate菜单,选择Form main()生成Main函数。
如图(注意,这些代码应该放在事件分发线程里执行)
设置好主类,运行即可看到效果: