11-Swing

认识swing

GUI简介 Linux--命令式 windows

GUI,图形用户界面。可以将计算机的功能直观的呈现出来。所以GUI需要操作系统和硬件的支持,GUI编程往往要处理移植性问题,Java的GUI编程相对有比较好的的可移植性。

  • 三要素:组件、容器、事件。
    • 组件:具有一定的功能模块,提供了公用的接口以便外部使用,有良好的可复用性;
    • 容器(窗体),是特殊的组件,容器中可以放置其他组件,并通过布局管理器,管理容器中的各组件的位置;
    • 事件:组件触发的动作事件,Java中不同事件由不同监听器处理,组件是事件源,而监听器主要用来监听来自指定事件源产生的动作事件。
  • Java的GUI功能主要集中在awt和swing两个包中。awt是GUI底层包。swing包是高层的封装,更容易移植。swing包中有很多swing组件

Swing简介

  • Swing组件是用java实现的轻量级(light- weight)组件,没有本地代码,不依赖操作系统的支持,其包含AWT可视化组件的替代组件。
  • Swing组件独立于本地窗口系统
  • Swing组件是基于AWT构建的

swing的类层次结构

  • 在javax.swing包中,定义了两种类型的组件:
    • 顶层容器(JFrame,JDialog)
    • 轻量级组件
  • swing组件绝大部分都是AWT的Container类的直接子类和间接子类。所以swing组件大部分也都是容器。
  • 类层次结构图:



Swing组件除了AbstractButton类之外都以J开头

swing组件分类

按功能分:顶层容器

  • JFrame,JDialog, JApplet,JWindow

普通容器(中间容器)

  • JPanel,JScrollPane(滚动窗格),JSplitPane(分割窗体),JTabbedPane,JOptionPane

基本控件(实现人机交互的组件)

  • JButton,JTextField,JLabel,JTextArea,JComboBox。。

swing容器及组件使用

顶层容器

  • JFrame类继承java.awt创建的Frame类(窗体,也是重量容器),所以JFrame类及其子类创建的对象实体,是窗体(也叫swing窗体),也是重量容器。
  • JFrame创建的swing窗体含有一个内容面板的容器,不能直接将组件加到窗体中,应该加到内容面板中。
  • 获取内容面板:可以通过swing窗体调用getContentPane()方法,然后再设置内容面板的布局(默认是BorderLayout布局)
  • 特性:
  1. 默认不可视;
  2. 默认宽高为0;
  3. 不能相互嵌套
  4. 注: 在swing窗体的内容面板中尽量不要既有重量容器又有轻量组件,最好只使用轻量组件.否则可能会出现预想不到的问题。
/**
 * 继承JFrame的子类也是swing窗体,也是重量容器
 * 特性:
 * @author wyn
 *
 */
class MyFrame extends JFrame {
	//创建组件 按钮   文本区
	private JButton button =null;
	private JTextArea text =null;
	//重量级组件
	private JDialog dialog =null;
	//无参
	
	public MyFrame() throws HeadlessException {
		init();
	}
	//初始化组件
	private void init() {
		button = new JButton("轻量级按钮组件");
		text = new JTextArea("轻量文本组件",3,17);
		//dialog = new JDialog(this,"dialog"); //
		//获取swing窗口的内容面板-->是一个容器
		Container con = this.getContentPane();
		con.add(button, BorderLayout.SOUTH); //添加组件
		con.add(text, BorderLayout.CENTER);
		//con.add(dialog, BorderLayout.WEST); //---> 内容面板不能既有轻量组件又有重量容器
	}	
	
	public static void main(String[] args) {
		//创建swing窗体,通过初始化 获取swing内容面板
		MyFrame myframe = new MyFrame();
		JPanel jPanel = new TestJPanel();
		myframe.add(jPanel);
		//设置窗体一些特性步骤:
		myframe.setSize(800, 1000); //宽高
		myframe.setTitle("窗体,重量容器");//标题
		myframe.setBackground(Color.BLUE);//背景可以省略
		myframe.setLocationRelativeTo(null);//默认居中
		myframe.setResizable(false); //设置不可改变大小
		myframe.setVisible(true);//设置可视化
	}
}

中间容器

  • Jpanel,是JComponet的子类,因此JPanel是轻量级组件, 且JPanel可以容纳其它组件;我们称JPanel为中间容器,或者叫面板
  • 特性:
    • 需要加入顶层容器中才可见(JFrame/JDialog)
    • 默认可见
    • 默认布局:Flowlayout;
    • 可以相互嵌套;

基本控件--事件源

  • JButton 生成按钮
    • 构造函数: public JButton(); public JButton(String tag);
    • 设置/获取按钮内容 public void setText(String tag); public String getText();
  • JTextField 生成单行文本框
    • 构造函数 public JTextField(); public JTextField(int cols);
    • 存/取文本框内容public void setText(String tag); public String getText();
  • JTextArea 生成多行文本框
    • 构造函数 public JTextArea (); public JTextArea (int rows, int cols); public JTextArea (String text, int rows, int cols);
    • 存/取文本框内容public void setText(String tag); public String getText();
    • public void append(String str);
  • JLable 生成标签
    • 构造函数 public JLabel(); public JLabel(String tag);
    • 存取public void setText(String tag); public String getText();

通用方法

所有swing组件都具有设置图标颜色字体大小边框的功能:

  • setIcon(Icon icon); //设置其上显示的图标.
  • setBackground(Color c); //设置背景色.
  • setForeground(Color c); //设置其上文字颜色.
  • setFont(Font font); //设置字体.
  • setPreferredSize(Dimension ds); //设置大小.
  • setBorder(Border bd); //设置边框.
  • setEnable(boolean b); //是否可用.
  • setEditable(boolean b); //是否可编辑
  • 相关类如下:
    • Icon / ImageIcon //图标相关类
      • Icon icon1=new ImageIcon(“图片路径”);
    • Color //颜色相关类
      • Color color1=new Color(255,0,0); //红色
    • Font //字体相关类
      • Font font1=new Font(“隶书”, Font.BOLD,16);
    • Dimension //大小相关类
      • Dimension dim1=new Dimension(宽,高);

绘制图像

需要继承中间容器JPanel,并且重写容器的paint() 方法以实现绘制背景图像

/**
 * 1.JPanel中间空间面板,只能存在于重量容器中,相当于画纸放于画板中作画;
 * 需要重写JPanel中paint() 用于绘制图像
 * @author wyn
 *
 */
public class DemoJPanel extends JPanel{
	//图像中的音频\图片\文本等素材 都属于静态资源,加载一次后会存于缓存中,无须在重新加载,根据特性可声明为静态的 并在静态块中进行初始值
	private static BufferedImage background = null; //缓存图片
	static {
		try {
			background = ImageIO.read(new File("img/bg3.jpg"));
            //通过IO流的获取图片路径
		} catch (IOException e) {
			System.out.println("图片找不到..");//添加异常信息
			e.printStackTrace();
		} 
	}
	@Override
	public void paint(Graphics g) { //Graphics画笔工具类
		//super.paint(g);
		g.drawImage(background, 0, 0, null);
		g.drawLine(16, 10, 16, 120); //直线,两点一线
		g.drawRect(255, 5, 50, 50);//绘制矩形
		g.setColor(Color.RED);	//填充颜色,调用该方法之后的绘制出来的图形都为这个颜色
		g.fillRect(200, 5, 50, 50);//绘制填充的矩形
		g.drawArc(160, 160, 100, 100, 0, 300); //0°以三点钟方向开始绘制到300°截至的圆
		g.setFont(new Font("思源黑体", Font.BOLD, 20));	//绘制字符串
		g.drawString("游戏结束....",155, 160);
	}
	
	public static void main(String[] args) {
		MyFrame myframe = new MyFrame();
		DemoJPanel djpanel = new DemoJPanel();
		//添加 面板到容器中
		myframe.add(djpanel);
		//设置窗体一些特性步骤:
		myframe.setSize(800, 1000); //宽高
		myframe.setTitle("窗体,重量容器");//标题
		myframe.setBackground(Color.BLUE);//背景可以省略
		myframe.setLocationRelativeTo(null);//默认居中
//		myframe.setResizable(false); //设置不可改变大小
		myframe.setVisible(true);//设置可视化
	}
}

总结:

  • 工具类Graphics
  • 在背景图片上再绘制图片
  • 绘制字符串等功能
  • 音频、图片等都属于静态资源,可以在类中定义静态变量,并在静态块中赋予他们初始值,以便类加载时就能首先将静态资源先缓存起来,之后功能调用和使用可以优化系统的加载
  • 画纸JPanel 必须存在于 画板JFrame中,才能使用;而组件则在画纸中使用。
  • 画板JFrame若不设置的话则默认不可见,所以当新建JFrame对象实体需要进行设置。

事件处理模型

正常情况,组件(事件源)都不处理自己的事件,而是将事件处理委托给外部实体(监听器),这种事件处理模型称为 事件的授权处理模型。不同的事件可以交由不同类型的监听器去处理
事件处理过程,涉及三类对象:

  • Event -事件,用户对界面操作在java语言上的描述,以类的形式出现,例如键盘操作对应的事件类是KeyEvent。
  • Event Source -事件源,事件发生的场所,通常就是各个组件,例如按钮JButton。
  • Event handler -事件处理者,接收事件对象并对其进行处理

事件处理过程,涉及三种角色:

  • 事件源
  • 监听器
  • 处理事件的接口(适配器)

实现事件处理步骤:

  • 找到事件源(按钮、文本框等组件)
  • 创建监听器对象(需要实现相应接口的类) -->或者说实现监听器的适配器(抽象类)
  • 为事件源注册监听器对象 --> 事件源(组件).add...Listener(适配器)

事件实现方式(适配器Adapter)
在java事件处理中,当处理事件的接口中多于一个方法时,系统就会提供相应的实现类(这个是抽象的),这样的实现类我们称为适配器类

  • 用内部类实现事件处理
    • 一般监视器类我们可以内部类或匿名类实现.
  • 用外部类实现事件处理

鼠标事件处理

Java种有两个不同接口处理:

  • MouseListener 可处理事件(MouseEvent):--> 对应适配器 MouseAdapter
    • 单击鼠标按键(按下并释放) --> mouseClicked
    • 鼠标光标进入组件几何图形 --> mouseEntered
    • 鼠标光标离开组件几何图形 --> mouseExited
  • MouseMotionListener可处理事件(MouseEvent):--> 对应适配器 MouseMotionAdapter
    • 鼠标按键在组件上按下并拖动 --> mouseDragged
    • 光标移动到组件上 但无按键按下 --> mouseMoved
    • 可用此事件是实现 画板能动
      • int getClickCount(); //返回鼠标单击次数
      • Point getPoint(); //返回事件相对于源组件的x,y坐标
      • int getX(); /int getY(); //获取x或y的坐标
      • void translatePoint(int x, int y); //将事件的坐标平移到新位置,其中x,y为原坐标的偏移量。

定时任务组件

  • javax.swing.Timer //在指定延迟之后激发一个或多个操作事件,实现定时功能。
    • void start(); //
    • void stop(); //停止Timercancel();
  • java.util.Timer配合TimerTake使用,实现定时功能
    • schedule(TimerTask task, Date time); //安排在指定的时间执行指定的任务
    • schedule(TimerTask task, long delay); //安排在指定延迟后执行指定的任务
    • schedule(TimerTask task, Date firstTime, long period) //排指定的任务在指定的时间开始进行重复的固定延迟执行。
public class TestEvent {
	static int i=0;
	public static void main(String[] args) {
		int delay =1000;
		//为事件注册监听器,适配该监听器(用内部类实现)
		ActionListener taskPerformer = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) { //事件
				System.out.println(i++);
			}
		};
		new Timer(delay, taskPerformer).start();//start()启动Timer
		System.out.println("----java.util.TimerTask----");
		MyTask myTask = new MyTask();
		java.util.Timer timer = new java.util.Timer();
		timer.schedule(myTask, 10000,10000); //定时10秒以后执行mytask这个任务,执行完以后,每个10s再执行任务
	}
}


class MyTask extends java.util.TimerTask {
	public void run() { 
		System.out.println("--------");
	}
}

备课要求:

  1. 和项目结合-- 飞机大战
  2. 基础语法的一个结合应用
  3. 结合面向对象的特性 结合应用
  4. 录屏学习:
    1. src放源程序 src评级创建一个folder文件img-放素材
    2. 介绍swing的相关类层次-Java开发窗体的相关包引入swing包下的相关类
      • swing包是基于及优化了awt包中的相关类
    3. 创建窗体
      • 画板 --> JFrame
        1. 默认不可视
        2. 宽高为0
        3. JFrame之间不能相互嵌套
      • 画纸 --> JPanel
      • 通过画笔绘制图形--> 图片\文本框\按钮...
  5. 例子1:
   /**
    * Swing: Java开发窗体的相关包是引用了 swing包下的相关类,
    *      swing包是基于和优化了awt(抽象窗口工具包)中的相关类
    * 创建窗体的步骤:
    * 1.画板 -- JFrame
    * 2.画纸 -- JPanel
    * 3.通过画笔画出的相关图形 --图片\文本框\按钮
    */
   public class TestJFrame {
       //测试:1.画板 -- JFrame
       public static void main(String[] args) throws InterruptedException {
           //直接运行无法看到,主要是:
           /*
           1.jframe不可视;
           2.宽高为0;
           3.jframe不可嵌套
            */
           JFrame jframe = new JFrame();
           //1.设置宽高
           jframe.setSize(300, 400);
           //2.设置标题
           jframe.setTitle("飞机大战");
           //3.设置居中,根据整体的中点来设置,如果和'设置宽高'的步骤对换会无法居中
           jframe.setLocationRelativeTo(null);//位置相对于 null,默认居中
           //窗体打开时程序正在运行,但是直接x掉窗体,程序并没有停止运行,需要加上
           //4.设置窗体关闭模式
           //(在JFrame定义):使用System exit方法退出exit程序。 仅在应用程序中使用。
           jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//默认关闭操作
           //5.设置窗口固定大小,通过鼠标无法调整窗体大小 -->
           //设置窗体无法重置大小
           jframe.setResizable(false);
   
           //设置可视--最后一步设置,不然可能导致其他组件看不到;
           jframe.setVisible(true);
           //发现运行在桌面左上方,可以设置每次运行时居中,加上第3步
           //Thread.currentThread().sleep(10000); //延时10s
           //System.exit(3);
       }
   }