1、Swing概述
Swing是指“被绘制的”用户图形界面类;AWT是指像事件处理这样的窗口工具箱的底层机制。
使用Swing的好处:
- Swing拥有一个丰富、便捷的用户界面元素合集
- Swing对底层平台依赖的很少,因此与平台相关的bug很少
- Swing给予不同平台的用户一致的感觉
2、创建框架
在Java中,顶层窗口被称为框架(frame)。在AWT库中有一个称为Frame的类,用于描述顶层窗口。这个窗口Swing版本名为JFrame,它扩展于Frame类。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。
示例
package com.java01.day05;
import javax.swing.*;
/**
* @author: ju
* @date: 2020-05-08 17:35
*/
public class SimpleFrame extends JFrame {
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
//构造SimpleFrame初始化大小为(300,200)
public SimpleFrame(){
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @author: 橘橘
* @date: 2020-05-08 17:33
*/
public class SimpleFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SimpleFrame simpleFrame = new SimpleFrame();
simpleFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置simpleFrame窗口可见
simpleFrame.setVisible(true);
}
});
}
}
执行结果:
所有的Swing组件必须由事件分派线程进行配置,线程将鼠标点击和按键控制转移到用户接口组件,下面的代码片段就是事件分派线程中的执行代码:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
//执行语句…
}
});
定义一个用户关闭这个框架的响应动作:
simpleFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3、框架定位
- setLocation 和 setBounds 方法用于设置框架的位置
- setIconImage 用于告诉窗口系统在标题栏、任务切换窗口等位置显示哪个图标
- setTitle 用于改变标题栏的文字
- setResizable 利用一个boolean 值确定框架的大小是否允许用户改变
获取屏幕的大小:
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
int height = screenSize.height;
int width = screenSize.width;
对于处理框架的一些提示:
- 如果框架中只包含标准的组件,如按钮和文本框,那么可以调用park方法设置框架的大小。框架被设置为刚好能放下所有组件的大小。同城情况下,将主程序的框架设置为最大,使用sizeFrame.setExtendedState(Frame.MAXIMIZED_BOTH);将框架设置为最大。
- 如果编写一个使用多个显示屏幕的应用程序,应该利用GraphicsEnvironment和GraphicsDevice类获得显示屏幕的大小。
- GraphicsDevice类允许在全屏模式下执行应用程序
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @description:
* @author: ju
* @date: 2020-05-09 13:21
*/
public class SizeFrame extends JFrame {
public SizeFrame(){
//获取屏幕大小
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
int height = screenSize.height;
int width = screenSize.width;
//设置框架大小为屏幕大小长宽各一半
setSize(width/2, height/2);
Image image = new ImageIcon("icon,gif").getImage();
setIconImage(image);
}
}
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @author: ju
* @date: 2020-05-09 13:14
*/
public class SizeFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame sizeFrame = new SizeFrame();
sizeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置simpleFrame窗口可见
sizeFrame.setVisible(true);
}
});
}
}
4、在组件中显示信息
通常情况下,在组件上绘制信息,add添加到框架上,就可以实现在组件中显示信息。绘制一个组件需要定义一个扩展JCompoment的类,并覆盖其中的paintCompoment方法。paintCompoment方法有一个Graphics类的对象参数,这个参数保存着用于绘制图像和文本的设置,例如:设置字体或当前的颜色。在Java中所有的绘制都必须使用Graphics对象,其中包含了绘制图案、图像和文本的方法。无论何种原因,只要窗口需要重新绘图,事件处理器就会通告组件,从而引发执行所有组件的paintCompoment方法。一定不要自己调用paintCompoment方法,这个方法会被自动调用,不要人为的干预这个自动的处理过程。
示例:
1、绘制组件的文本内容,重写paintComponent方法
public void paintComponent(Graphics g){
g.drawString(“Hello World!”, MESSAGE_X, MESSAGE_Y);
}
2、返回组件大小,重写getPreferredSize方法
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
3、添加到框架上,并设置框架大小
public HelloWorldFrame(){
//添加到框架上
add(new HelloWorldComponent());
//如果框架中只包含标准的组件,如按钮和文本框,那么可以调用park方法设置框架的大小
pack();
}
完整代码
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @author: ju
* @date: 2020-05-09 13:59
*/
public class HelloWorldComponent extends JComponent {
private static final int MESSAGE_X = 75;
private static final int MESSAGE_Y = 100;
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
//绘制组件的文本内容
@Override
public void paintComponent(Graphics g){
g.drawString("Hello World!", MESSAGE_X, MESSAGE_Y);
}
//返回组件大小
@Override
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
package com.java01.day05;
import javax.swing.*;
/**
* @author: ju
* @date: 2020-05-09 14:06
*/
public class HelloWorldFrame extends JFrame {
public HelloWorldFrame(){
//添加到框架上
add(new HelloWorldComponent());
//如果框架中只包含标准的组件,如按钮和文本框,那么可以调用park方法设置框架的大小
pack();
}
}
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @author: ju
* @date: 2020-05-09 14:09
*/
public class HelloWorldFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new HelloWorldFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Hello World!");
frame.setVisible(true);
}
});
}
}
执行结果
5、处理2D图形
根据给左上角、宽、高构造一个矩形
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
构造一个椭圆
Ellipse2D ellipse2D = new Ellipse2D.Double();
构造一个圆
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX+ radius , centerY + radius);
示例代码
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
* @author: ju
* @date: 2020-05-09 15:14
*/
public class DrawComponent extends JComponent {
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
@Override
public void paintComponent(Graphics g){
//声明一个Graphics2D对象
Graphics2D g2 = (Graphics2D) g;
//左上角坐标
double leftX = 100;
double topY = 100;
//宽、高
double width = 200;
double height = 150;
//根据给左上角、宽、高构造一个矩形
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
g2.draw(rect);
//构造一个椭圆
Ellipse2D ellipse2D = new Ellipse2D.Double();
ellipse2D.setFrame(rect);
g2.draw(ellipse2D);
g2.draw(new Line2D.Double(leftX, topY, leftX+width, topY+height));
double centerX = rect.getCenterX();
double centerY = rect.getCenterY();
double radius = 150;
//构造一个圆
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX+ radius , centerY + radius);
g2.draw(circle);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
public class DrawFrame extends JFrame {
public DrawFrame(){
add(new DrawComponent());
pack();
}
}
测试
public class DrawFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
DrawFrame drawFrame = new DrawFrame();
drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawFrame.setTitle("draw");
drawFrame.setVisible(true);
}
});
}
}
执行结果
6、使用颜色
使用Graphics2D类的setPaint方法可以为图形环境上的所有后续的绘制操作选择颜色;只需要将draw替换为fill就可以用一种颜色填充一个封闭图形的内部。
要想设置背景颜色,就需要使用Component类中的setBackground方法。
另外还有一个setForeground方法,它是用来设定在组件上绘制时使用的默认颜色。
示例代码
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
* @author: ju
* @date: 2020-05-09 15:14
*/
public class DrawComponent extends JComponent {
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
@Override
public void paintComponent(Graphics g){
//声明一个Graphics2D对象
Graphics2D g2 = (Graphics2D) g;
//左上角坐标
double leftX = 100;
double topY = 100;
//宽、高
double width = 200;
double height = 150;
//根据给左上角、宽、高构造一个矩形
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
//构造一个椭圆
Ellipse2D ellipse2D = new Ellipse2D.Double();
ellipse2D.setFrame(rect);
g2.draw(ellipse2D);
g2.setPaint(Color.YELLOW);
g2.fill(ellipse2D);
g2.setPaint(Color.BLUE);
g2.draw(new Line2D.Double(leftX, topY, leftX+width, topY+height));;
double centerX = rect.getCenterX();
double centerY = rect.getCenterY();
double radius = 150;
g2.draw(rect);
g2.setPaint(Color.RED);
g2.drawString("waining", 100, 100);
//构造一个圆
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX+ radius , centerY + radius);
g2.draw(circle);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
执行结果
7、文本使用特殊字体
可以通过字体名指定一种字体。可以调用GraphicsEnvironment.getLocalGraphicsEnvironment()获取计算机的所有字体:
public class ListFonts {
public static void main(String[] args){
String[] names = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for (String name : names){
System.out.println(name);
}
}
}
输出结果:
Agency FB
Algerian
Arial
Arial Black
Arial Narrow
Arial Rounded MT Bold
…
示例代码
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
* @description:
* @author: ju
* @date: 2020-05-11 14:22
*/
public class FontComponent extends JComponent {
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
@Override
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
String message = "Hello World!";
//设置字体
Font f = new Font("Serif", Font.BOLD, 36);
g2.setFont(f);
//获取字体信息
FontRenderContext fontRenderContext = g2.getFontRenderContext();
//获取字符串整体矩形信息
Rectangle2D stringBounds = f.getStringBounds(message, fontRenderContext);
double x = (getWidth() - stringBounds.getWidth())/2;
double y = (getHeight() - stringBounds.getHeight())/2;
double ascent = - stringBounds.getY();
double baseY = y + ascent;
g2.drawString(message, (int)x, (int)baseY);
g2.setPaint(Color.RED);
g2.draw(new Line2D.Double(x, baseY , x + stringBounds.getWidth(), baseY));
Rectangle2D rect = new Rectangle2D.Double(x, y , stringBounds.getWidth(), stringBounds.getHeight());
g2.draw(rect);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
public class FontFrame extends JFrame {
public FontFrame(){
add(new FontComponent());
pack();
}
}
测试
public class FontFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame fontFrame = new FontFrame();
fontFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fontFrame.setTitle("font");
fontFrame.setVisible(true);
}
});
}
}
执行结果
8、显示图像
我们可以使用Graphics的drawImage方法将图像显示出来
示例代码
package com.java01.day05;
import javax.swing.*;
import java.awt.*;
/**
* @description:
* @author: ju
* @date: 2020-05-11 14:45
*/
public class ImageComponent extends JComponent {
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
private Image image;
public ImageComponent(){
image = new ImageIcon("13eeb97f87e220fd7c04bbf65e104635_t.gif").getImage();
}
@Override
public void paintComponent(Graphics g){
if (image == null){
return;
}
int width = image.getWidth(this);
int height = image.getHeight(this);
g.drawImage(image, 0, 0, null);
for (int i = 0; i* width <= getWidth(); i++){
for (int j = 0; j*height <= getHeight(); j++){
if (i + j > 0){
g.copyArea(0, 0, width, height, i*width, i*height);
}
}
}
}
@Override
public Dimension getPreferredSize(){
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
public class ImageFrame extends JFrame {
public ImageFrame(){
add(new ImageComponent());
pack();
}
}
测试
public class SizeFrameTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame sizeFrame = new SizeFrame();
sizeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置simpleFrame窗口可见
sizeFrame.setVisible(true);
}
});
}
}
执行结果