Java GUI 编程入门






4.71/5 (23投票s)
本文旨在引导初学者进入 Java GUI 编程的世界
引言
本文面向对 Java GUI 编程经验很少或没有经验的人。因此,本文将重点介绍从框架到内容面板面板的层次树结构。主要重点将放在按钮部件(.NET 中的控件)以及用于处理该事件监听器的相应方法上。任何 .NET 程序员都会发现这些概念非常相似,只是在某些情况下,编码风格需要更多的文本,并且使用的术语有所不同。在 www.java.com 和 Sun 的 J2EE SDK 5.0 安装 Sun 的 Java Runtime 后,在命令行中编译此代码的一种快速简便的方法是转到默认目录:c:\Sun\SDK\JDK\bin> 键入 con > somecode.java Ctrl-Z 然后编译。要设置您的路径:set PATH=%PATH%;.;C:\Sun\SDK\JDK\bin。
Java GUI 编程涉及两个包:最初的抽象窗口工具包 (AWT) 和较新的 Swing 工具包。Swing 组件带有前缀 J,以区别于原始的 AWT 组件(例如,JFrame
而不是 Frame
)。要在您的项目中包含 Swing 组件和方法,您必须导入 java.awt.*、java.awt.event.* 和 javax.swing.* 包。可显示的框架是顶层容器,例如 JFrame
、JWindows
、JDialog
和 JApplet
,它们与操作系统的窗口管理器交互。非显示内容面板是中间容器,例如 JPanel
、JOptionsPane
、JScrollPane
和 JSplitPane
。因此,容器是用于保存和分组其他部件(如文本框、复选框、单选按钮等)的小部件或 GUI 控件。.NET 中的主 UI,称为 Windows Form,包含拖放到控件表面上的控件。每个 GUI 都是从一个用于显示内容的窗口开始的。在 Swing 中,有三种类型的窗口:Applet、Dialog 和 Frame。这些接口与窗口管理器交互。在 swing 中,frame
对象被称为 JFrame
。JFrame
被认为是顶层容器。这些也被称为可显示框架。非显示内容面板是中间容器,例如 JPanel
、JScrollPane
、JLayeredPane
、JSplitPane
和 JTabbedPane
,它们在使用多个控件时组织布局结构。简单来说,内容面板是放置文本字段和其他部件的地方,因此要添加和显示 GUI 控件,我们需要指定它要添加到的内容面板。然后,内容面板位于包含层次结构的顶部,在这个类似树的层次结构中有一个顶层容器(在我们的例子中是 JFrame
)。沿着树往下看,我们会找到其他顶层容器,如 JPanel
来容纳组件。以下是生成一个简单的 frame
以供构建的代码
import java.awt.*;
import java.awt.event.*;
import javax.swing.*; //notice javax
public class Frame1 extends JFrame
{
JPanel pane = new JPanel();
Frame1() // the frame constructor method
{
super("My Simple Frame"); setBounds(100,100,300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane); // add the panel to frame
// customize panel here
// pane.add(someWidget);
setVisible(true); // display this frame
}
public static void main(String args[]) {new Frame1();}
}
如果您从未编译过 Java 代码,那么请考虑使用此基本代码来显示编译和解释过程。由于 .NET 编译器发出 IL 代码和元数据,其中元数据表由 CLR 读取以验证类型安全(即,将正确的数据类型传递给正确的方法),JIT 编译器将 IL 代码转换为本机代码以供执行。与 Java 虚拟机不同,没有解释。Java 平台由 API(用于程序的已编译库的集合)和 JVM(类似于 CLR)定义。Java 源代码文件被编译成字节码,其中生成一个充当运行时执行蓝图的类文件。这是一个例子
import java.util.*;
public class Sys {
public static void main(String[] args) {
System.out.println
(“This is a string passed to the print line method of the System class”);
}
}
c:\Sun\SDK\jdk\bin>javac.exe Sys.java // the javac.exe compiler
// compiles the source code
c:\Sun\SDK\jdk\bin>java.exe Sys // the java.exe interprets the byte code file
// (in the same directory where the class file is.
这是一个传递给 System 类 print line 方法的字符串。
这是显示带有按钮的 GUI 的代码。
但是,当按下按钮时,它什么也不做
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame2 extends JFrame
{
JPanel pane = new JPanel();
JButton pressme = new JButton("Press Me");
Frame2() // the frame constructor
{
super("JPrompt Demo"); setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane); // JPanel containers default to FlowLayout
pressme.setMnemonic('P'); // associate hotkey to button
pane.add(pressme); pressme.requestFocus();
setVisible(true); // make frame visible
}
public static void main(String args[]) {new Frame2();}
}
C:\...\bin>Javac.exe Frame2.java
C:\...\bin>Java.exe Frame2
Java GUI 是基于事件的,因为它们响应标准输入设备,如按键、鼠标点击、单选按钮等。以下是按钮按下的输出
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame3 extends JFrame implements ActionListener
{
JLabel answer = new JLabel("");
JPanel pane = new JPanel(); // create pane object
JButton pressme = new JButton("Press Me");
Frame3() // the constructor
{
super("Event Handler Demo"); setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane); pressme.setMnemonic('P'); // associate hotkey
pressme.addActionListener(this); // register button listener
pane.add(answer); pane.add(pressme); pressme.requestFocus();
setVisible(true); // make frame visible
}
// here is the basic event handler
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if (source == pressme)
{
answer.setText("Button pressed!");
JOptionPane.showMessageDialog(null,"I hear you!","Message Dialog",
JOptionPane.PLAIN_MESSAGE); setVisible(true); // show something
}
}
public static void main(String args[]) {new Frame3();}
}
在上面的例子中添加一个基本的按钮按下事件处理程序的第一步是导入 awt.event.*,它包含所有事件类。接下来,将短语 implements ActionListener
添加到类头中以使用 interface
。使用 addActionListener(this)
方法为每个按钮部件注册事件监听器。保留字 this
表示需要的(由 implements ActionListener
)处理程序方法,称为 actionPerformed()
将包含在当前类中。例如,考虑这个更生动的例子
import javax.swing.*;
import java.awt.Color;
public class ButtonDemo{
public JPanel createContentPane (){
// We create a bottom JPanel to place everything on.
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
// Creation of a Panel to contain the title labels
JPanel titlePanel = new JPanel();
titlePanel.setLayout(null);
titlePanel.setLocation(10, 0);
titlePanel.setSize(250, 30);
totalGUI.add(titlePanel);
JLabel redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(100, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
titlePanel.add(redLabel);
JLabel blueLabel = new JLabel("Blue Team");
blueLabel.setLocation(120, 0);
blueLabel.setSize(100, 30);
blueLabel.setHorizontalAlignment(0);
blueLabel.setForeground(Color.blue);
titlePanel.add(blueLabel);
// Creation of a Panel to contain the score labels.
JPanel scorePanel = new JPanel();
scorePanel.setLayout(null);
scorePanel.setLocation(10, 40);
scorePanel.setSize(250, 30);
totalGUI.add(scorePanel);
JLabel redScore = new JLabel("0");
redScore.setLocation(0, 0);
redScore.setSize(100, 30);
redScore.setHorizontalAlignment(0);
scorePanel.add(redScore);
JLabel blueScore = new JLabel("0");
blueScore.setLocation(120, 0);
blueScore.setSize(100, 30);
blueScore.setHorizontalAlignment(0);
scorePanel.add(blueScore);
// Creation of a label to contain all the JButtons.
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 80);
buttonPanel.setSize(250, 70);
totalGUI.add(buttonPanel);
// We create a button and manipulate it using the syntax we have
// used before.
JButton redButton = new JButton("Red Score!");
redButton.setLocation(0, 0);
redButton.setSize(100, 30);
buttonPanel.add(redButton);
JButton blueButton = new JButton("Blue Score!");
blueButton.setLocation(120, 0);
blueButton.setSize(100, 30);
buttonPanel.add(blueButton);
JButton resetButton = new JButton("Reset Score");
resetButton.setLocation(0, 40);
resetButton.setSize(220, 30);
buttonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
//Create and set up the content pane.
ButtonExample demo = new ButtonExample();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 190);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
输出
当按下按钮时,不会发生任何事情,因为需要事件监听器
import javax.swing.*;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ButtonDemo_Extended implements ActionListener{
// Definition of global values and items that are part of the GUI.
int redScoreAmount = 0;
int blueScoreAmount = 0;
JPanel titlePanel, scorePanel, buttonPanel;
JLabel redLabel, blueLabel, redScore, blueScore;
JButton redButton, blueButton, resetButton;
public JPanel createContentPane (){
// We create a bottom JPanel to place everything on.
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
// Creation of a Panel to contain the title labels
titlePanel = new JPanel();
titlePanel.setLayout(null);
titlePanel.setLocation(10, 0);
titlePanel.setSize(250, 30);
totalGUI.add(titlePanel);
redLabel = new JLabel("Red Team");
redLabel.setLocation(0, 0);
redLabel.setSize(120, 30);
redLabel.setHorizontalAlignment(0);
redLabel.setForeground(Color.red);
titlePanel.add(redLabel);
blueLabel = new JLabel("Blue Team");
blueLabel.setLocation(130, 0);
blueLabel.setSize(120, 30);
blueLabel.setHorizontalAlignment(0);
blueLabel.setForeground(Color.blue);
titlePanel.add(blueLabel);
// Creation of a Panel to contain the score labels.
scorePanel = new JPanel();
scorePanel.setLayout(null);
scorePanel.setLocation(10, 40);
scorePanel.setSize(260, 30);
totalGUI.add(scorePanel);
redScore = new JLabel(""+redScoreAmount);
redScore.setLocation(0, 0);
redScore.setSize(120, 30);
redScore.setHorizontalAlignment(0);
scorePanel.add(redScore);
blueScore = new JLabel(""+blueScoreAmount);
blueScore.setLocation(130, 0);
blueScore.setSize(120, 30);
blueScore.setHorizontalAlignment(0);
scorePanel.add(blueScore);
// Creation of a Panel to contain all the JButtons.
buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 80);
buttonPanel.setSize(260, 70);
totalGUI.add(buttonPanel);
// We create a button and manipulate it using the syntax we have
// used before. Now each button has an ActionListener which posts
// its action out when the button is pressed.
redButton = new JButton("Red Score!");
redButton.setLocation(0, 0);
redButton.setSize(120, 30);
redButton.addActionListener(this);
buttonPanel.add(redButton);
blueButton = new JButton("Blue Score!");
blueButton.setLocation(130, 0);
blueButton.setSize(120, 30);
blueButton.addActionListener(this);
buttonPanel.add(blueButton);
resetButton = new JButton("Reset Score");
resetButton.setLocation(0, 40);
resetButton.setSize(250, 30);
resetButton.addActionListener(this);
buttonPanel.add(resetButton);
totalGUI.setOpaque(true);
return totalGUI;
}
// This is the new ActionPerformed Method.
// It catches any events with an ActionListener attached.
// Using an if statement, we can determine which button was pressed
// and change the appropriate values in our GUI.
public void actionPerformed(ActionEvent e) {
if(e.getSource() == redButton)
{
redScoreAmount = redScoreAmount + 1;
redScore.setText(""+redScoreAmount);
}
else if(e.getSource() == blueButton)
{
blueScoreAmount = blueScoreAmount + 1;
blueScore.setText(""+blueScoreAmount);
}
else if(e.getSource() == resetButton)
{
redScoreAmount = 0;
blueScoreAmount = 0;
redScore.setText(""+redScoreAmount);
blueScore.setText(""+blueScoreAmount);
}
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JButton Scores! [=]");
//Create and set up the content pane.
ButtonDemo_Extended demo = new ButtonDemo_Extended();
frame.setContentPane(demo.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(280, 190);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
建议阅读
- 在 http://www.macs.hw.ac.uk 的指导手册
- JR 的教育页面,网址为 http://home.cogeco.ca
历史
- 2009 年 2 月 20 日:初始帖子