你知道界面编程吗?一文带你了解界面编程【Java养成】

Java学习打卡:第十一天

Java学习(打卡第十一天)


学习内容

JavaI/O总结,Java界面框架


内容管理

在正式的内容前,我先插一句,不管是之前介绍容器类还是介绍I/O,我们都只是分享了基本的框架,还有一点提示的是,Java技术日新月异,我们一定要不断学习最新的Java知识,还有就是逐渐完善各个模块的知识,像我们的I/O还有很多没有分享,比如我们的PipedInputStream 管道流主要运用于线程中,以后我会逐步完善各模块的内容,现在主要是对Java各部分有各基本的认识,实践就可以让我们掌握更多的细节,当有些基本的东西出错之后你就对其印象深刻了

java I/O的总结

  • 我们要知道所有的io类都可能抛出异常,就是IOException,我们要使用try catch 或者thows来处理异常
  • 我们在应用过程中,应该先尽可能使用Reader和Writer,一旦无法成功编译我们就才会发现非使用byte-oriented程序库不可,就要使用字节流【比如java.util.zip程序库就是面向的字节流而不是字符流】
  • 还有就是要灵活运用BufferedReader和PrintWriter实现控制台读写程序,按行读写程序文本

还有就是我们的异常类有很多,我们字节编写文件输入输出时我们也可以自己定义子类来继承Exception类,然后我们在操作时就可以catch这个异常

java界面编程

Java的应用程序界面编程主要涉及AWT(Abstract Window Toolkit)和Swing两打类库,Swing时AWT的扩展和功能的加强

  • java.awt-------AWT compoments 抽象窗口组件

    • 使用本地窗口组件,调用操作系统的内部API,支持各个操作系统平台所提供的窗口组件的集合
  • javax.swing --------------- Swing compoments 决定性组件

    • 创建了一个新的框架使用模拟窗口组件来代替本地窗口组件,丰富了窗口组件,在不同的平台上表现一致,有能力提供本地窗口系统不支持的其他特性local window,但是本地创建组件也还在使用
Swing Compoments(widgets) and Container

我们把Java界面编程的所有组件分成两个类,一个是容器,另一个就是原子组件

Compoment类是所有界面组件类的祖先,用来表示一个图形组件

A container is special type of compoment that is used to organize ,manage and present other compoments. But a compoment is not necessary a container.

就是说容器本身也是组件,container 和 compoment具有一对多的关联关系,就是一个容器中可以管理多个原子组件,同时也可以管理容器。

Since a container can contain compoments, and a container is a compoment, then a container may contain other containers.

而容器又分为顶级容器和中极容器,顶级容器包含了一些中极容器,每个中极容器就包含中极容器和原子组件;原子组件就是我们所可以看见的可视化图元,比如我们的界面上的log in ,log out,还有就是我们可以看到的那些程序框,而一些中极容器时不可见的,它们知识负责管理这些原子组件,比如这些组件在界面上如何摆放,实现界面管理

Swing widgets 分类and JFrame

These are three board types of Swing widgets(javax.swing,*)

  • atomic widgets(or compoments) 原子组件
    • 原子组件已经是最小的可视化图元,An atomic widget is one that corresponds(符合) to a basic GUI feature such as a button or label(标签) 就是原子组件就是一个符合基本的GUL特点的物件就像按钮和标签,原子组件又分为两类,A set of frequently used atomic widgets includes
      • Atomic widgets for user input with the mouse:[JButton; JcheckBox;JComboBox;JRadioButton;JList;Jslider;Jtree]这些都是界面上我们用鼠标操作的组件
      • 不可编辑信息的显示:向用户展示不可编辑信息的组件,比如我们的密码标签;JLable;JProgressMonitor; 为组件设置对用户有帮助的信息 Tool tips ------- The JCompoment 其中的方法method setToolTipTest(“String”) sets up a small text label(标签) that appears briefly, to inform the user ,when the mouse curror(光标) lingers over(在-- 徘徊) a widget’s window.(组件窗口)
      • 可编辑信息的显示: 向用户显示能被编辑的格式化信息的组件:biru JColorChooser,JFileChoose,JFileChooser,JTable(excel形式的表格) , JTextArea,JTextFiled
  • intermediate containers 中级容器 ----- 中级容器可以组织和管理上面所有的原子组件,进行界面布局
    • 用于容纳界面元素,以便在布局管理器的设置下可以容纳更多的容器,实现容器的嵌套
      • 比如JPanel, JScrollPane,JtabedPane,JToolBar;JLayeredPane; JDesktopPane;JInternalFrame; JRootPane;自身嵌套
  • top-level container 顶级容器 — A top-level container holds intermediate container and atomic widges,顶级容器是界面的最外层,是不能被其他的所包含
    • A GUI application usually has a top-level widget that contains and manages other widgets in the programm
      • JFrame for general use 在构建桌面应用程序时,通常创建一个JFrame来容纳所需的组件,以提供期望的GUI外观和功能
      • JDialog for creating pop-up dialog boxes 对话框
      • JWindow
如何搭建一个界面程序(步骤)

In a typical GUI application ,the main method performs these steps

1 Create a top-level container,usually a JFrame 首先我们通常创建一个顶级容器JFrame

2 Compose the GUI by adding widgets(intermediate containers and atomic widgets) to containers in a desired layout 接下来我们按照要求就要在这个顶级容器上进行页面布局,摆放中级容器和原子组件

3Set up and register event handlers(listeners) to respond to user interaction.接下来就是给界面上的组件注册建立一些事件用于和用户交互,这和Unity 是类似的

4Display the GUI and return 运行程序显示界面

JFrame

JFrame是Java的主框架,所有的Java应用程序界面都是在主框架之中设计的

We will create a program/class called FrameDemo, and within the main() method of that class we will perform the bare minimum steps necessary to create and diaplaty a JFrame ,接下来将会用Demo来演示JFrame的用法

import javax.swing.*;
import java.awt.*;

public class FrameDemo {
	public static void main(String[] args) {
		JFrame theFrame = new JFrame("name");//窗体的名称
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭时自动退出
		theFrame.setSize(800,600);//窗体的大小
		theFrame.setVisible(true);//摆放的东西可见(窗体中)
	}
}//这里我们就实现了最外层顶级容器的构建
Adding 中级容器和原子组件到JFrame

我们可以使用窗体JFrame的内容嵌板提供的add()方法将原子组件逐一添加到窗体上进行显示

JFrame frame = new JFrame("name");
Container contentPane = frame.getContentPane();
contentPane.add(new Jabel("Label name"));//不可编辑的Jabel

我们还可以直接使用窗体提供的add()方法将原子组件添加到窗体上显示

比如我们在上面的基础上

public class FrameDemo {
	public static void main(String[] args) {
		JFrame theFrame = new JFrame("name");
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JLabel labelone = new JLabel("name");//不可修改编辑的标签
		labelone.setFont(new Font("Serif",Font.BOLD,20));
		theFrame.add(labelone);//添加了原子组件
		theFrame.setSize(800,600);
		theFrame.setVisible(true);
	}
}

添加组件到面板JPanel

JPanel是一个没有明显边界的中级容器,它不能像JFrame一样单独使用显示,它必须放在另一个容器中,被用作将多个其他图形化Component组织在一起的容器,它可以组织管理多个原子组件或者嵌套使用

通过JPanel提供的add()方法防止各种原子组件或中级容器

JLabel stuff = new JLabel(“I am a Label”);

JPane APanel = new JPanel();

aPanel.add(stuff);//放在面版上,然后将面板放在顶级容器上

一个JPanel 也可以放置布局其他的JPanel

这里我们就再在上面的基础再添加一下功能

public class FrameDemo {
	public static void main(String[] args) {
		JFrame theFrame = new JFrame("name");
		JPanel panelOne = new JPanel();//多个面板第二个面板看不见,覆盖了
		JLabel labelone = new JLabel("name");
		JLabel labeltwo = new JLabel("name");
		JLabel labelthree = new JLabel("name");
		Font fon = new Font("Serif",Font.BOLD,20);
		labelone.setFont(fon);//多次用就直接new了指代
		labeltwo.setFont(fon);
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		theFrame.add(panelOne);//加上面板
		panelOne.add(labelone);
		panelOne.add(labeltwo);
		theFrame.pack();//打包
		theFrame.setSize(600,600);
		theFrame.setVisible(true);
	}
}

使用窗体JFrame的内容嵌板或者窗提供的add()方法将面板JPanel添加到窗体上,显示面板上摆放的原子组件

Java页面布局管理器 Layout Fundamentals

我们上面说过如果建立两个JPanel,如果不进行布局管理,那么就会造成页面的覆盖,特别是再复杂的界面编程的时候,我们跟容易发生这样的事情

Layout management jis the process of determing the layout(布局),Java allows you to take these two approches:

  • Automatic layout ------ use a layout manager to determine the layout antomatically.
  • Manual Layout ---- uae no layout manager .specify the position and size of each widget window exlictly.采用无布局管理器,setLayout(null)必须手动使用setLocation(),setSize(),setBounds()等方法手工设置组件的大小和位置,此方法会导致平台相关,不推荐使用,我们还是要使用布局管理器

所以我们就使用自动化布局的方案

Automatic layout 自动化布局

Java的自动化布局采用了我们之前所说的strategy pattren ,就是策略模式,也就是我们要减少相似代码的覆写,而使用面向接口的编程;为了使生成的图形用户界面具有良好的平台无关性,Java提供了布局管理器,来管理布局

  • 每一个容器都指定一个布局管理器,当容器需要对某一个组件惊醒定位或判断器尺寸大小时,就会调用相应的布局管理器,就像我们的迭代器也是这样子的,面向接口编程

  • 布局管理器LayoutManager是一个接口

    • 具体的布局组件的算法分别封装再一个实现布局管理器的接口的类中,容器可以再不同运算时刻调用不同的布局管理器

不同的布局管理器有BorderLayout(中心),FlowLayout(流水账),GirdLayout(网格)

如何给一个容器指定布局管理器

We either use the default layout manager that id associated with a container such as :

JFrame 缺省的是 BoradLayout 中心

JPanel 缺省的是 FlowLayout 流水账 可以看出来,因为我们之前实现的时候,两个label是按照顺序直接连接起来的,就是流水账

那我们如何改变呢,我们就借助方法setLayout来实现 void setLayout(LayoutManager mgr);这样我们就可以改变布局管理器

BorderLayout

BorderLayout is the default layout manager for JFrame. The BorderLayout subdivides a Container into five regions.五个 方位来布局

每个区域只能放置一个组件(可以是中级容器或原子组件)

如果不指定对象的摆放区域,缺省的CENTER,可以通过容器添加组件的add方法的第二个参数来指出组件的摆放区域,add的第二个参数的取值:

比如BoarderLayout.NORTH 置于顶端 BorderLayout.SOUTH .WEST .EAST .CENTER 填满中央区域,与四周组件连接,或延展至边缘

public static void main(String[] args) {
		JFrame theFrame = new JFrame("BoarderLayout");
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		BorderLayout layout = new BorderLayout();//创建布局管理器对象
		theFrame.setLayout(layout);//调用布局管理器
		theFrame.add(new JButton("West"),BorderLayout.WEST);
		theFrame.add(new JButton("NORTH"),BorderLayout.NORTH);
		theFrame.setSize(400,400);
		Dimension frameSize = theFrame.getSize();
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		theFrame.setVisible(true);
	}//这里我们就可以将几个按钮放在几个方位
FlowLayout

就是流水账布局,就是从上到下,从做到右,按照对齐的方式进行放置,如果当前行放置不下,就放置到下一行

这个类的构造方法有几个

Flowlayout() 无参的构造方法,对齐方式为居中对齐,横向纵向间隔都是缺省的5个像素

FlowLayout(FlowLayout.LEFT)

居左对齐,横向纵向间隔都是5个像素

FlowLayout (FlowLayout.RIGHT,20,40)

第一个参数组件表示组件的对齐方式,至组件在这一行的位置是居中对齐,居右对齐和居左对齐,迭戈参数是组件之间的横向间隔,第三个参数是组件的纵向讲个,单位都是像素

GirdLayout

GirdLayout可以建立一个组件表格,而且当组件被放置到容器中时,会按照次序从左至右,由上到下摆放在每个各自Gird中

在构造方法中指定了要求的行数和烈属,各行各列所分配的空间的大小都是相同的

GirdLayout gird = new GirdLayout(7,3); 利用JPanel是的某个区域显示抖个组件达到复杂用户的设计

public static void main(String[] args) {
		JFrame theFrame = new JFrame("GirdLayout");
		theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		GridLayout grid = new GridLayout(7,3);//创建布局管理器对象
		theFrame.setLayout(grid);//调用布局管理器
		for(int i = 1;i <= 7;i++)
		{
			for(int j = 1;j <= 3;j++)
			{
				theFrame.add(new JButton("Row" + i +"col"+ j));
			}
		}
//		Dimension frameSize = theFrame.getSize();
//		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		theFrame.setVisible(true);
	}

这样我们就能够生成一个7 3的按钮表,复杂的设计就是我们层层布局,从底层的JFrame开始就要认真思考布局

java界面编程以及事件处理

我们上面实现我们的界面都是在main函数中,但是我们在实际操作中是基本上封装在不同的类中,这里我们要使用就要继承

图形用户界面程序搭建框架

继承Frame创建用户界面程序
public class JFrameName extends JFrame

那么这个子类都可以调用Frame就都可以使用超类的构造函数,我们创建界面交互类时就创建一些私有属性,就是我们需要摆放的组件如JButton之类的,构造函数我们首先继承超类,之后我们进行一些改变颜色的操作之类的,之后我们就可以在main函数中直接操作

继承JPanel创建用户界面程序
public class JPanelName extends JPanel

建立一个JPanel中级容器,把要显示的界面元素添加到该中级容器中,然后将该中级容器放置到JFrame中

只是我们在main函数还是要把JFrame写出来,并且放置该中级容器

事件 Events - Basic Concepts

GUI events are generated when the user interacts with a component on the GUI

for example , when a JButton is clicked ,Actioon Event(用户对界面的操作在java里的描述),the tyoe of events that is generated

Each type of event is represented by a distinct class

As with virtually everything else in java events are objects!

java.awt.event----classes related to AWT event handling

javax.swing.event---- classes related to Swing event handling//组件的事件

这些事件我们就可以去看一下事件的列表来看

Event handling 事件处理

我们上面说了我们如果用户与界面交互之后触发了相关的事件之后,programmer需要做的就是监听与处理

In order to handle events

  • 创建监听类---- 对于某种类型的事件XXXEvent,要想接受并处理这类事件,必须定义实现监听器接口XXXListener监听类

    • You must create a listener class that must implement(实现) the appropriate interface.

      class ListenerOne implements ActionListener{}
          
         public void actionPerformed(ACtionEvent event)
      {
          label.setText(buttonOne.getText());//怎么处理
      }
      }
      
  • 调用组件的addXXXListener()方法注册Listener对象,就可以监听该事件该事件除法的XXXEvent,就是我们要查资料观察这些监听器

buttonOne.addActionLister(new ListenerOne());//注册事件

好了,我们今天的分享结束了,明天我们就会进入其他的部分的学习,或者可能对于界面编程实现一个简单的项目~~

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python 中的线程睡眠可以通过 `time.sleep()` 函数来实现,该函数会让当前线程暂停指定的时间,单位为秒。例如,以下代码会让当前线程睡眠 1 秒钟: ```python import time print("start") time.sleep(1) print("end") ``` 输出: ``` start (end 1 秒钟后输出) ``` 需要注意的是,线程睡眠会让当前线程阻塞,即当前线程会暂停执行,等待指定的时间后再继续执行。如果在主线程中使用线程睡眠,会导致整个程序的执行被暂停。 另外,需要注意的是 Python 中的线程与操作系统的线程并不是一一对应的关系,Python 解释器会使用一个全局锁来保证同一时刻只有一个线程在执行 Python 代码。因此,如果在 Python 中使用多线程,可能会出现线程间的竞争和阻塞,需要使用适当的同步机制(如锁、信号量等)来解决。 至于后台线程,它是一种特殊的线程,在程序退出时会自动结束,不需要等待其执行完成。可以通过设置线程对象的 `daemon` 属性来创建后台线程。例如,以下代码创建了一个后台线程: ```python import threading import time def count(): for i in range(5): print(i) time.sleep(1) t = threading.Thread(target=count) t.daemon = True t.start() print("main thread exit") ``` 输出: ``` 0 main thread exit 1 2 3 4 ``` 注意,当主线程退出时,后台线程也会随之结束,即使后台线程没有执行完毕。因此,需要确保后台线程的执行时间不会超过主线程的生命周期。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值