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);
            }
        });
    }
}

执行结果:

java和javaFX匹配 javaswing和javafx的优缺点_ide

所有的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);
            }
        });
    }
}

执行结果

java和javaFX匹配 javaswing和javafx的优缺点_java和javaFX匹配_02

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);
            }
        });

    }
}

执行结果

java和javaFX匹配 javaswing和javafx的优缺点_java_03

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);
    }
}

执行结果

java和javaFX匹配 javaswing和javafx的优缺点_ide_04

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);
            }
        });
    }
}

执行结果

java和javaFX匹配 javaswing和javafx的优缺点_ide_05

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);
            }
        });
    }
}

执行结果

java和javaFX匹配 javaswing和javafx的优缺点_ide_06