咱们学校的Java教学中需要掌握一些Swing的基础操作,虽然Swing已经没人用了。。。
但既然要学,就要学好,毕竟技多不压身,还能拿个好成绩。
本文总结自《Java核心技术 卷Ⅰ》第十章,实现了一些简单的基础操作——显示窗体,改变窗体属性,画图,对用户点击进行响应等等。
源码都给上了,如果你的复习时间紧张,不妨简单看看。
抽象窗口工具包 (Abstract Window Toolkit, AWT) ->Swing用户界面库 ->JavaFX。
AWT:
将处理用户界面元素的任务委托给目标平台上的原生GUI工具包。
Swing:
底层窗口系统只需显示一个空白窗口,将用户界面元素绘制在空白的窗口上。
JavaFx:
JFrame作为其他组件的画布,它的修饰部件是由用户的窗口系统绘制的,而不是Swing绘制。
创建一个最简单的可见窗体:
package simpleFrame;
import java.awt.*;
import javax.swing.*; //java的拓展包
public class SimpleFrameTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(()-> // 事件分派线程(event dispatch thread)
{
var frame = new SimpleFrame(); // 构造一个Simple Frame对象
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//定义用户点击关闭时退出。
frame.setVisible(true);//将窗体显示出来
});
} //主程序已经结束,事件分派线程仍会保持激活状态
}
class SimpleFrame extends JFrame //拓展于JFrame
{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public SimpleFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
代码解释:
窗体外观的改变:
JFrame类本身只定义了若干个改变窗体外观的方法,但由于其超类众多,因此拥有非常丰富的设置窗体属性的方法。以下列出几项:
虽然可以将内容直接绘制在窗体中,但一般不这么做。正确的做法是:将一个组件添加到窗体上,再在组件上绘制信息。
只要窗口需要重新绘制,事件处理器会通知组件从而引发执行所有组件的paintComponent方法,不要自己调用该方法! 否则可能会对这个自动处理过程造成破坏。
1.在窗体中显示一个组件,并在组件上绘制一条文本信息:
package notHelloWorld;
import javax.swing.*;
import java.awt.*;
public class NotHelloWorld
{
public static void main(String args[])
{
EventQueue.invokeLater(()->
{
var frame = new NotHelloWorldFrame();
frame.setTitle("Not a Hello World");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class NotHelloWorldFrame extends JFrame
{
public NotHelloWorldFrame()
{
add(new NotHelloWorldComponent());//添加一个组件至窗体中
pack();//使用组件的首选大小,首先大小在getPreferredSize中定义
}
}
class NotHelloWorldComponent extends JComponent
{
public static final int MESSAGE_X = 75;
public static final int MESSAGE_Y = 100;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public void paintComponent(Graphics g) //覆盖此方法来绘制内容
{
g.drawString("Not a Hello World program!", MESSAGE_X, MESSAGE_Y);
}
public Dimension getPreferredSize() //设置组件的首选大小
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
代码解释:
总结 ,在窗体中显示信息三大步骤:
2.绘制2D图形:
Graphics类:绘制直线,矩形,椭圆等,功能有限。
Java 2D库的图形类:它是Graphics类的一个子类,功能更加丰富,除了一些基本图形外,还可以绘制圆弧、二次曲线、三次曲线等等,这里我们重点介绍Java 2D库的图形类。
绘制图形的步骤:
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*; //包含了众多实现了shape接口的类,如Ellipse2D等等
public class DrawTest {
public static void main(String[] args)
{
EventQueue.invokeLater(()-> //事件分派线程
{
var frame = new DrawFrame();
frame.setTitle("DrawTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(300, 300, 800, 800);
frame.setVisible(true);
});
}
}
class DrawFrame extends JFrame //创建一个窗体
{
public DrawFrame()
{
add(new DrawComponent());//将组件添加至窗体中
pack(); //使用组件的默认大小
}
}
class DrawComponent extends JComponent // 定义组件完成所需任务
{
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
public void paintComponent(Graphics g) //必须覆盖的方法
{
var g2 = (Graphics2D) g;//Graphics2D是Graphics的子类,可以直接强制类型转换
double leftX = 100;
double topY = 100;
double width = 200;
double height = 150;
var rect = new Rectangle2D.Double(leftX, topY, width,height);//绘制一个长方形,参数有:左上角坐标,宽,高
g2.draw(rect);
var ellipse = new Ellipse2D.Double();
ellipse.setFrame(rect);//以一个长方形为外接矩形绘制一个椭圆
g2.draw(ellipse);
var line = new Line2D.Double(leftX, topY, leftX + width, topY + height);//绘制一条线段,参数有:起点坐标,终点坐标
g2.draw(line);
double centerX = rect.getCenterX();
double centerY = rect.getCenterY();
double radius = 150;
var circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX + radius, centerY + radius);//通过中点坐标和四角坐标之一绘制图像
g2.draw(circle);
}
public Dimension getPerredSize() //覆盖以确定组件的默认大小
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
几个补充说明:
任何支持GUI的操作环境都需要和用户进行互动,换一种说法,操作环境必须要不断地监视按键与鼠标点击的事件。
若有相关事件的发生,操作环境会将其报告给程序,程序在做出相应的动作。
先解释以下几个名词:
具体操作过程如下:
package button;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ButtonFrame extends JFrame{
private JPanel buttonPanel;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ButtonFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
//1.生成事件源
var yellowButton = new JButton("Yellow");
var blueButton = new JButton("Blue");
var redButton = new JButton("Red");
//2.生成一个面板
buttonPanel = new JPanel();
//3.将事件源添加至面板当中
buttonPanel.add(yellowButton);
buttonPanel.add(blueButton);
buttonPanel.add(redButton);
//4.将面板添加到窗体当中
add(buttonPanel);
//6.生成一个监听器类 ColorAction(定义在下面)
var yellowAction = new ColorAction(Color.YELLOW);
var blueAction = new ColorAction(Color.BLUE);
var redAction = new ColorAction(Color.RED);
//7.将监听器添加到事件源中
yellowButton.addActionListener(yellowAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}
//5.定义一个监听器类,其中覆盖了actionPerformed方法
private class ColorAction implements ActionListener
{
private Color backgroundColor;
public ColorAction(Color c)
{
backgroundColor = c;
}
//必须具有参数ActionEvent
public void actionPerformed(ActionEvent event)
{
buttonPanel.setBackground(backgroundColor);
}
}
public static void main(String[] args)
{
EventQueue.invokeLater(()->
{
var buttonFrame = new ButtonFrame();
buttonFrame.setVisible(true);
});
}
}
注意:
Over. Thanks for watching.