使用Swing的GUI编程

Swing

AWT概述

  • AWT:抽象窗口工具包,提供了一套与本地图形界面进行交互的接口,是Java提供的用来建立和设置Java的图形用户界面的基本工具
  • Swing以AWT为基础的,尽管Swing消除了AWT固有的大量限制,但Swing不是用来代替AWT的。Swing使用了与AWT相同的事件处理机制;所以使用Swing需要对AWT以及事件处理有一个基本了解

两个关键的Swing特性

  • 轻量级组件
  • 可插入外观

Swing包含的内容

  • 容器
  • 组件
  • 可改变的外观
  • Java2D图形绘制

Swing容器

容器类型

  • 顶层容器(重量级)

    • JFrame
    • JApplet
    • JDialog
    • JWindow
    • 继承自Component和Container

    注意:每个应用程序至少有一个顶层容器,也就是我们说的窗口

  • 中间容器

    • JPanel
    • JScrollPane
    • JSplitPane
    • 继承自JComponent

顶层容器JFrame窗体的层次结构

  • JFrame窗体的底层是RootPane(javax.swing.JRootPane)
    • RootPane包含GlassPane和LayeredPane

GlassPane

  • 是一个透明面板,主要功能是捕获JFrame上的任何事件
  • JGlassPane的默认值是不可看见的,不过可以设为看见的(visible)

LayeredPane

  • 是一个可以重叠组件的面板,本身就是一个容器
  • ContentPane是LayeredPane中的一层,一般视为最底层,也是最常用,最重要的容器。通常我们会将组件放在ContentPane上,而不会加在LayeredPane上

示例:

import javax.swing.JFrame;

public class FirstSwingDemo {

	public static void main(String[] args) {
		JFrame jf = new JFrame("第一个Swing窗口");//创建一个Java预定义的窗体
        /*方法1:setSize(int newWidth, newHeight)*/
		jf.setSize(400,480);//设置窗体的大小
        
        /*方法2:setSize(Dimension newSize)*/
        Dimension d = new Dimension(100,100);
        jf.setSize(d);
        
		jf.setVisible(true);//设置窗体是否可见
	}
}

JFrame窗口参数

方法 描述
setSize(int newWidth, int newHeight) / setSize(Dimension newSize) 设置窗体大小
setVisible(boolean visibleFlag) 设置窗体是否可见
setTitle(String newTitle) 设置窗体标题

面板(JPanel)

  • JPanel类是Java GUI工具包Swing中的面板容器类,是一种轻量级的容器
  • 可以加入到JFrame窗体中,自身可以嵌套使用,主要功能是对窗体中的组件进行组织
  • 其他Swing组件可以通过调用add()方法添加到面板容器对象中
  • 一旦添加,就可以使用Component类定义的setLoacation()、setSize()、setBounds()方法手动布局和调整
  • JPanel默认布局是FlowLayout(流布局),如果需要手动布局,需要使用setLayout()方法修改布局方式

示例(给窗体添加一个面板)

import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class FirstSwingDemo {

	public static void main(String[] args) {
		JFrame jf = new JFrame("第一个Swing窗口");//创建一个Java预定义的窗体
		jf.setSize(400,480);//设置窗体的大小
		jf.setVisible(true);//设置窗体是否可见
		
		JPanel jp = new JPanel();//创建一个面板容器对象
		Container container = jf.getContentPane();//将JPanel对象添加到父容器中
		container.setLayout(null);//设置布局
		container.add(jp);//添加组件
		
		/**
		 * 设置布局和大小
		 */
		jp.setSize(100,100);
		jp.setLocation(50,50);
		/**
		 * 设置背景色
		 */
		jp.setBackground(Color.black);
	}
}

Swing GUI组件

标签(JLabel)

  • JLabel是最容易使用的Swing组件,用来创建标签
  • 最常用的构造方法是:
    • JLabel(String str):str用于标签的文本
    • JLabel(Icon icon):icon用于标签的图标;获取图标最容易的方式是使用ImageIcon类,它实现了Icon,所以可以将ImageIcon类型的对象作为参数传递给JLabel构造方法的Icon参数
		JLabel jl = new JLabel("第一个标签");
		jf.getContentPane().add(jl,BorderLayout.CENTER);

		//显示图片
		JLabel jl = new JLabel(new ImageIcon("icon.jpg"));
		jf.getContentPane().add(jl);

文本输入框(JTextField)

  • Swing的文本组件,通过它可以编辑一行文本,也可以响应用户交互事件

示例:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class FirstSwingDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("第一个Swing窗口");//创建一个Java预定义的窗体
		Dimension d = new Dimension(400,200);
		frame.setSize(d);
		
		/**
		 * 添加一个用于显示的标签
		 */
		JLabel label = new JLabel();
		label.setPreferredSize(new Dimension(d.width,60));
		frame.getContentPane().add(label,BorderLayout.NORTH);
		
		/**
		 * 添加文本输入框
		 */
		JTextField text = new JTextField();
		text.setPreferredSize(new Dimension(d.width,60));
		
		/**
		 * 添加文本输入框Enter事件
		 */
		text.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				label.setText(text.getText());
			}
		});
		frame.getContentPane().add(text,BorderLayout.CENTER);
		frame.setVisible(true);
	}

}

按钮(JButton)

  • JButton
  • JToggleButton
  • JCheckBox
  • JRadioButton

以上这些都是AbstractButton的子类,包含了许多用于控制按钮行为的方法。如下:

  • void setDisableIcon(Icon di)
  • void setPressedIcon(Icon pi)
  • void setSelectedIcon(Icon si)
  • void setRolloverIcon(Icon ri)

通过以下方法可以获取和修改关联的文本内容:

  • String getText()
  • void setText(String str)

示例:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class SecondSwingDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("这是按钮的练习");
		Dimension d = new Dimension(400,200);
		frame.setSize(d);
		
		JLabel label = new JLabel();
		label.setPreferredSize(new Dimension(d.width,60));
		frame.getContentPane().add(label,BorderLayout.NORTH);
		
		/**
		 * 添加按钮
		 */
		JButton button = new JButton("按钮");
		button.setPreferredSize(new Dimension(d.width,60));
		button.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				label.setText("测试一下按钮");
				
			}
		});
		frame.getContentPane().add(button,BorderLayout.SOUTH);//在窗体中增加按钮
		frame.setVisible(true);//显示窗体
	}

}

组合框(JComboBox)

  • Swing通过JComboBox类来提供组合框(文本域与下拉列表组合)
  • 组合框通常显示一个条目,但也可以显示一个允许用户从中选择不同条目的下拉列表
  • 还可以创建允许用户在文本域中输入选项的组合框
  • 从JDK7开始,JComboBox设计成泛型类:class JComboBox
  • 可以通过addItem()方法添加到下拉列表中
  • 可以通过setSelectedItem()方法设置当前被选中的条目
  • 通过getSelectedItem()方法获取当前被选中的条目

示例:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JFrame;

public class ThirdSwingDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("这是组合框的测试");
		Dimension d = new Dimension(400,200);
		frame.setSize(d);
		frame.setLayout(null);
		ArrayList<String> cars = new ArrayList<>();
		cars.add("哈弗");
		cars.add("吉利");
		cars.add("大众");
		cars.add("本田");
		cars.add("长安");
		
		/**
		 * 创建下拉菜单
		 */
		JComboBox<String> box = new JComboBox<>();
		box.setBounds(d.width/2-100,d.height/2-60,200,60);
		
		/**
		 * 添加下拉菜单内容
		 */
		for(String brands : cars) {
			box.addItem(brands);
		}
		
		box.setSelectedItem(cars.get(4));//设置当前选中的选项
		frame.getContentPane().add(box,BorderLayout.CENTER);
		frame.setVisible(true);
	}

}

布局管理器(LayoutManager)

BorderLayout类

  • 布置容器的边框布局管理器
  • 可以对容器组件进行安排,并调整其大小,使其符合五个区域:东、南、西、北、中
  • 每个区域只能包含一个组件

边框布局示例:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;

public class FourthSwingDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("BorderLayout示例");
		Dimension d = new Dimension(400,200);
		frame.setSize(d);
		BorderLayout layout = new BorderLayout();
		Container panel = frame.getContentPane();
		panel.setLayout(layout);
		Font font = new Font("黑体",Font.BOLD,24);
		JButton north = new JButton("北");
		north.setFont(font);
		panel.add(north,BorderLayout.NORTH);
		
		JButton south = new JButton("南");
		south.setFont(font);
		panel.add(south,BorderLayout.SOUTH);
		
		JButton west = new JButton("西");
		west.setFont(font);
		panel.add(west,BorderLayout.WEST);
		
		JButton east = new JButton("东");
		east.setFont(font);
		panel.add(east,BorderLayout.EAST);
		
		JButton center = new JButton("中");
		center.setFont(font);
		panel.add(center,BorderLayout.CENTER);
		
		frame.setVisible(true);
		
	}

}

FlowLayout类

  • 布置容器的流布局管理器

  • 具有指定的对齐方式以及指定的水平和垂直间隙

  • align参数的值必须为以下的值之一:

    FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING、FlowLayout.TRAILING

流布局示例:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FlowLayoutDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("FlowLayout示例");
		Dimension d = new Dimension(1280,1080);
		frame.setSize(d);
		JPanel panel = new JPanel();
		panel.setBackground(new Color(200,200,200));
		FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
		panel.setLayout(layout);
		frame.getContentPane().add(panel,BorderLayout.CENTER);
		
		for(int i = 0; i < 2; i++) {
			ImageIcon icon = new ImageIcon("myfinder.png");
			JLabel label = new JLabel(icon);
			label.setPreferredSize(new Dimension(
					icon.getIconWidth(),icon.getIconHeight()));
			panel.add(label);
		}
		JButton button = new JButton("窗体减半");
		button.setFont(new Font("微软雅黑",Font.PLAIN,24));
		button.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				panel.setSize(new Dimension(
						panel.getWidth()/2,panel.getHeight()));
				panel.doLayout();
			}
		});
		panel.add(button);
		frame.setVisible(true);
	}

}

GridLayout类

  • 布置容器的网格布局管理器
  • 将容器划分成网络,组件可以按行和列排列
  • 在网格布局管理器中,每一个组件的大小相同
  • 网格中空格个数由网格行数和列数决定
  • 组件从网格的左上角开始,从左往右,从上往下的顺序加入到网格中
  • 每一个组件都会填满整个网格,改变窗体大小,组件大小也会随之改变

GridLayout示例:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GridLayoutDemo {

	public static void main(String[] args) {
		JFrame frame = new JFrame("FlowLayout示例");
		Dimension d = new Dimension(680,500);
		frame.setSize(d);
		
		JPanel gridPanel = new JPanel();
		int rowMax = 5;
		int colMax = 4;
		gridPanel.setLayout(new GridLayout(rowMax,colMax));
		frame.getContentPane().add(gridPanel);
		String[][] signal = {
				{"(",")","%","C"},
				{"1","2","3","+"},
				{"4","5","6","-"},
				{"7","8","9","*"},
				{"0",".","=","/"}
		};
		
		for (int i = 0; i < rowMax; i++) {
			for(int j = 0; j < colMax; j++) {
				JButton button = new JButton();
				button.setFont(new Font("微软雅黑",Font.BOLD,54));
				button.setText(signal[i][j]);
				gridPanel.add(button);
			}
		}
		frame.setVisible(true);
	}

}

在Swing中绘图

组件绘制

渐变色面板示例:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class GradientPanel extends JPanel{
	
	public GradientPanel(BorderLayout borderLayout) {
		super(borderLayout);
	}

	@ Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if(!isOpaque()) {
			return;
		}
		int width = this.getWidth();
		int height = this.getHeight();
		Graphics2D g2 = (Graphics2D)g;
		GradientPaint grandientPaint = new GradientPaint(
				width/4,
				height/4,
				Color.red,
				width,
				height,
				Color.blue,
				false);
		g2.setPaint(grandientPaint);
		g2.fillRect(0, 0, width, height);
	}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame("渐变色面板示例");
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.setSize(500,400);
		
		GradientPanel grandientPanel = new GradientPanel(new BorderLayout());
		frame.getContentPane().add(grandientPanel);
		frame.setVisible(true);
	}

}

基本图形绘制

  • 常见的图形绘制方法:

    • 绘制直线:drawLine()
    • 绘制矩形:drawRect()
    • 绘制椭圆:drawOval()
    • 绘制弧形:drawArc()
    • 绘制多边形:drawPolygon()

    示例:

    @ Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		g.setColor(Color.red);
    		g.drawLine(0, //起点横坐标
    		this.getHeight, //起点纵坐标
    		this.getWidth, //终点横坐标
    		this.getHeight/2);//终点纵坐标
    	}
    
  • 常见的图形填充方法:

    • 填充矩形:fillRect()
    • 填充椭圆:fillOval()
    • 填充扇形:fillArc()
    • 填充多边形:fillPolygon()

    示例:

    @ Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		g.setColor(Color.red);
    		g.fillArc(this.getWeight/2-100, //圆心横坐标
    		this.getHeight/2-100,//圆心纵坐标
             200, 200, //圆的直径
             0,  360);//起始弧度,终止弧度
    	}
    
posted @ 2020-02-21 23:57  笔架山Code  阅读(335)  评论(0编辑  收藏  举报