GUI图形界面(2)

2024-06-07 01:38
文章标签 gui 图形界面

本文主要是介绍GUI图形界面(2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

随着 Internet 的飞速发展,Java 技术也得到了越来越广泛的应用。而无论我们是采用 J2SE、J2EE 还是 J2ME,GUI 都是不能回避的问题。现在的应用软件越来越要求界面友好、功能强大而又使用简单。而众所周知,在 Java 中进行 GUI 设计相对于其跨平台、多线程等特性的实现要复杂和麻烦许多。这也是很多 Java 程序员抱怨的事情。但 GUI 已经成为程序发展的方向,所以我们也必须了解 Java 的 GUI 设计方法和特点。其实,采用 Java 提供的布局管理器接口和相应的布局管理类,我们也可以做出相当漂亮的界面来,当然实现起来肯定要比 VB 麻烦许多。本文试图通过自己的开发经历介绍一些具体的应用实例,希望能给那些曾经象我一样苦闷的 Java 痴迷者一些帮助。

Java 中的布局管理器

2.1 为什么要使用布局

在实际编程中,我们每设计一个窗体,都要往其中添加若干组件。为了管理好这些组件的布局,我们就需要使用布局管理器。比如说,设计一个简单的计算器,或一个文本编辑器等等。这些组件是让 JVM 自己任意安排呢?还是按照一定的位置关系进行规范的安排呢?当然应该选择后者。 将加入到容器的组件按照一定的顺序和规则放置,使之看起来更美观,这就是布局。在 Java 中,布局由布局管理器 (LayoutManager) 来管理。那么,我们在什么时候应该使用布局管理器?应选择哪种布局管理器?又该怎样使用布局管理器呢?

如果你写的是 GUI 程序,在使用 AWT/Swing 组件时就不应硬性设置组件的大小和位置,而应该使用 Java 的布局管理器(LayoutManager)来设置和管理可视组件的大小和位置,否则就有可能造成布局混乱。不信,你可以新建一个 Frame(或 JFrame),通过 setBounds() 方法往其中添加几个 Button(或 JButton),一旦你将窗体拉大或缩小时,你会发现组件的排列完全不是按你所预想的那样。为了解决这个问题,即当窗体(或容器)缩放时,组件位置也随之合理调整,我们就需要使用布局管理器。

为此,我们首先要知道 Java 的布局方式,Java 提供的 API 中有些什么布局管理器,它们的布局特点是什么。

2.2 Java 的布局方式

我们都知道,Java 的 GUI 界面定义是由 AWT 类包和 Swing 类包来完成的。它在布局管理上采用了容器和布局管理分离的方案。也就是说,容器只管将其他组件放入其中,而不管这些组件是如何放置的。对于布局的管理交给专门的布局管理器类(LayoutManager)来完成。

现在我们来看 Java 中布局管理器的具体实现。我们前面说过,Java 中的容器类(Container),它们只管加入组件(Component),也就是说,它只使用自己的 add() 方法向自己内部加入组件。同时他记录这些加入其内部的组件的个数,可以通过 container.getComponentCount() 方法类获得组件的数目,通过 container.getComponent(i) 来获得相应组件的句柄。然后 LayoutManager 类就可以通过这些信息来实际布局其中的组件了。

Java 已经为我们提供了几个常用的布局管理器类,例如: FlowLayout、BorderLayout、GridLayout、GridBagLayout 等。下面列表说明它们的布局特点:

特点
java.awt CardLayout 将组件象卡片一样放置在容器中,在某一时刻只有一个组件可见
java.awt FlowLayout 将组件按从左到右而后从上到下的顺序依次排列,一行不能放完则折到下一行继续放置
java.awt GridLayout 形似一个无框线的表格,每个单元格中放一个组件
java.awt BorderLayout 将组件按东、南、西、北、中五个区域放置,每个方向最多只能放置一个组件
java.awt GridBagLayout 非常灵活,可指定组件放置的具体位置及占用单元格数目
Javax.swing BoxLayout 就像整齐放置的一行或者一列盒子,每个盒子中一个组件
Javax.swing SpringLayout 根据一组约束条件放置子组件
Javax.swing ScrollPaneLayout 专用于 JScrollPane,含一个 Viewport,一个行头、一个列头、两个滚动条和四个角组件
Javax.swing OverlayLayout 以彼此覆盖的形式叠置组件
Javax.swing ViewportLayout JViewport 的默认布局管理器

事实上,在大多数情况下,综合运用好这些布局管理器已可以满足需要。当然对于特殊的具体应用,我们可以通过实现 LayoutManager 或 LayoutManager2 接口来定义自己的布局管理器。下面我们通过几个实例来了解几个常用的布局管理器的使用方法。

GUI 设计应用实例

3.1 FlowLayout/GridLayout/BorderLayout 的应用实例

3.1.1 应用背景

假设我们要编写一个简单的计算器 JApplet,其基本界面如下:


 

3.1.2 解决方法

通过其界面要求可知,我们可以通过将"BackSpace"和"Clear"JButton 放置在一个 JPanel(1)中,采用 FlowLayout 布局;将显示结果的 JTextField 和该 JPanel 一起放置到另外一个 JPanel(2),采用 GridLayout 布局;而将其它的 JButton 则放置在另外一个 JPanel(3)中,采用 GridLayout 布局;再将 JPanel(2)和 JPanel(3)加入该 JApplet,即可实现界面需求。具体实现方法如下:

 /** 以 FlowLayout 布局 JPanel(1)*/JPanel p1 = new JPanel(new FlowLayout()); // 默认组件从居中开始// 加入"BackSpace"和"Clear"JButtonp1.add(backButton);p1.add(clearButton);/** 以 GridLayout 布局 JPanel(2)*/JPanel p2 = new JPanel(new GridLayout(2, 1));   // 放置 2 行,每行 1 个组件// 加入显示结果的 JTextField 和 JPanel(1)p2.add(displayField);p2.add(p1);/** 以 GridLayout 布局 JPanel(3)*/JPanel p3 = new JPanel(new GridLayout(4, 5));   // 放置 4 行,每行 5 个组件String buttonStr = "789/A456*B123-C0.D+=";for (int i = 0; i < buttonStr.length(); i++)this.addButton(p3, buttonStr.substring(i, i + 1));//addButton 方法private void addButton(Container c, String s){JButton b = new JButton(s);if (s.equals("A"))b.setText("sqrt");else if (s.equals("B"))b.setText("1/x");else if (s.equals("C"))b.setText("%");else if (s.equals("D"))b.setText("+/-");b.setForeground(Color.blue);c.add(b);b.addActionListener(this);}/** 以 BorderLayout 布局 JApplet*/this.setLayout(new BorderLayout());this.add(p2, "North");this.add(p3, "Center");

这样,就一切 OK 啦。具体的实现代码可参见附件中的 CalculateApplet.java 文件。

3.2 带工具栏和状态栏的 GridLayout/BorderLayout 应用实例

3.2.1 实际问题

在很多情况下我们需要动态设置工具栏和状态栏,看下面的应用实例:


 

以上是在视图的工具栏和状态栏都被复选的时候,以下分别为某一个没选或都未选的情况。


 

3.2.2 解决方法

	 /** 工具栏 JToolBar 采用从左开始的 FlowLayout 布局 */JToolBar toolBar = new JToolBar(); 	toolBar.setBorderPainted(false); // 不画边界toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));/** 窗体采用动态的 BorderLayout 布局,通过获取工具栏或状态栏的复选标记进行界面的动态调整 */JSplitPane splitPane = new JSplitPane();splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); // 设置统计窗口分隔条的方向splitPane.setDividerLocation(300); 	 // 设置分隔条的位置splitPane.setOneTouchExpandable(true);JCheckBoxMenuItem toolBarItem = new JCheckBoxMenuItem("工具栏 (T)", true);JLabel statusLabel = new JLabel("当前统计目标 :");JCheckBoxMenuItem statusBarItem = new JCheckBoxMenuItem("状态栏 (S)", true);/** 设置系统窗体布局并动态设置工具栏和状态栏 */private void setLayout(){if (toolBarItem.getState() &&' statusBarItem.getState()){this.getContentPane().add(BorderLayout.NORTH, toolBar);this.getContentPane().add(BorderLayout.CENTER, splitPane);this.getContentPane().add(BorderLayout.SOUTH, statusLabel);}else if (toolBarItem.getState() && !statusBarItem.getState()){this.getContentPane().add(BorderLayout.NORTH, toolBar);this.getContentPane().remove(statusLabel);}else if (statusBarItem.getState() && !toolBarItem.getState()){this.getContentPane().add(BorderLayout.SOUTH, statusLabel);this.getContentPane().remove(toolBar);}else if (!toolBarItem.getState() && !statusBarItem.getState()){this.getContentPane().remove(toolBar);this.getContentPane().remove(statusLabel);}this.show(); // 添加或移去组件后刷新界面}

通过该方法即可实现界面的动态刷新与调整。

3.3 GridBagLayout 应用实例

3.3.1 实际问题

GridBagLayout 是 Java API 提供的一个较复杂的布局管理器,利用好它可以解决许多实际编程中的令人烦恼的界面设计问题。看下面的界面应用实例:


 

3.3.2 解决方法

这个界面的设计比较复杂,涉及多个标签域(JLabel)、文本域(JTextField、JTextArea),且标签域的大小还不一样,如附件标签;并当窗体缩放时,标签域的大小应不改变,而文本域则必须自适应缩放。如何来实现呢?请看下面的代码:(工具栏的实现不再赘述)

 /** 系统的界面布局实现 */GridBagConstraints gridBag = new GridBagConstraints();gridBag.fill = GridBagConstraints.HORIZONTAL;  // 以水平填充方式布局gridBag.weightx = 0;  // 行长不变gridBag.weighty = 0;  // 列高不变fromLabel.setForeground(Color.blue);fromLabel.setFont(new Font("Alias", Font.BOLD, 16));this.add(fromLabel, gridBag, 0, 1, 1, 1);  // 指定发信人标签位置receiveLabel.setForeground(Color.blue);receiveLabel.setFont(new Font("Alias", Font.BOLD, 16));this.add(receiveLabel, gridBag, 0, 2, 1, 1); // 指定收信人标签位置及大小ccLabel.setForeground(Color.blue);ccLabel.setFont(new Font("Alias", Font.BOLD, 16));this.add(ccLabel, gridBag, 0, 3, 1, 1); // 指定抄送人标签位置及大小subjectLabel.setForeground(Color.blue);subjectLabel.setFont(new Font("Alias", Font.BOLD, 16));his.add(subjectLabel, gridBag, 0, 4, 1, 1); // 指定主题标签位置及大小accessoryLabel.setForeground(Color.blue);accessoryLabel.setFont(new Font("Alias", Font.BOLD, 16));this.add(accessoryLabel, gridBag, 0, 5, 1, 1); // 指定附件标签位置及大小gridBag.weightx = 100; // 行自适应缩放gridBag.weighty = 0;// 列高不变fromField.setText("admin@watermelon.com");this.add(fromField, gridBag, 1, 1, 2, 1); // 指定发信人文本域(JTextField)位置及大小this.add(receiveField, gridBag, 1, 2, 2, 1); // 指定收信人文本域(JTextField)位置及大小this.add(ccField, gridBag, 1, 3, 2, 1); // 指定抄送人文本域(JTextField)位置及大小this.add(subjectField, gridBag, 1, 4, 2, 1); // 指定主题文本域(JTextField)位置及大小accessoryArea.setEditable(false);// 设置不显示水平滚动条(该 JTextArea 置于 JScrollPane 中)accessoryScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);this.add(accessoryScroll, gridBag, 1, 5, 2, 1); // 指定附件文本区(JTextArea)位置及大小gridBag.fill = GridBagConstraints.BOTH;// 采用全填充方式布局gridBag.weightx = 100;// 行自适应缩放gridBag.weighty = 100;// 列自适应缩放mailArea.setBackground(Color.blue);mailArea.setForeground(Color.yellow);mailArea.setTabSize(4);// 指定信件主体区(JTextArea)的位置及大小。(该 JTextArea 也置于 JScrollPane 中)this.add(scroll, gridBag, 0, 6, 3, 1);在上面用到一个方法 add(),这个方法是自己定义的:private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h){gbc.gridx = x;gbc.gridy = y;gbc.gridheight = h;gbc.gridwidth = w;this.getContentPane().add(c, gbc);}

在用到 GridBagLayout 布局管理器的组件添加方法中,都可以重用它。事实上,你还可以在方法最前面加一个参数 Container cn,而将方法中的 this 相应的改为 cn,就可以通用于所有需要使用 GridBagLayout 进行布局管理的容器中。在下面的复杂例程中我们就会用到。

3.4 综合多个布局的复杂应用实例

3.4.1 实际问题

请看下面的实际应用界面要求:


(图 3.4-1)
图 3.4-1  

(图 3.4-2)
图 3.4-2  

(图 3.4-3)
图 3.4-3  

在这个具体应用中,底部的 JButton 组是确定的,但 JTabbedPane 的每一个选项都不同,如何实现呢?

3.4.2 解决方案

首先我们可以采用 BorderLayout 确定主题对话框的布局方式,实现方法如下:

 JTabbedPane dbTabPane = new JTabbedPane();
…… // 下面需要用到的 JButton 等组件变量定义(或声明)private void initLayout(){initDBTabPane();// 初始化 JTabbedPane:DBTabPane 组件this.getContentPane().add(BorderLayout.CENTER, dbTabPane);// 将 JTabbedPane 组件:dbTabPane 布局于 JDialog 对话框的中间initButtonPanel();// 初始化 JPanel:ButtonPanel 组件this.getContentPane().add(BorderLayout.SOUTH, buttonPanel);// 将 JPanel 组件:buttonPanel 布局于 JDialog 对话框的底部(南面)}private void initDBTabPane(){JPanel loginPanel = new JPanel(new GridLayout(10, 1));// 为保证两个 JCheckBox 组件位于顶端,设置为共 10 行,每行一个组件的布局,但只// 放置界面要求的两个组件,这样就保持了界面的美观,否则如定义为//Gridlayout(2,1) 则会使两个组件居中,而且中间会隔开较长的距离。pwdBox.setMnemonic('P');loginPanel.add(pwdBox);dspBox.setMnemonic('D');loginPanel.add(dspBox);dbTabPane.add("Login", loginPanel); // 设置"Login"JPanel(图 3.4-1)的布局needRadio.setMnemonic('N');allRadio.setMnemonic('A');cacheRadio.setMnemonic('U');radioPanel.setBorder(new TitledBorder("Load Option"));// 加上边界标题radioPanel.add(needRadio);radioPanel.add(allRadio);radioPanel.add(cacheRadio);// 以上为加入需要的 JRadioButton 组件到指定的 JPanel: radioPanelqueryPanel.add(radioPanel);// 加入含 JRadioButton 组的 JPanel 到 queryPanelreqBox.setMnemonic('R');boxPanel.add(reqBox);saveBox.setMnemonic('S');boxPanel.add(saveBox);autoBox.setMnemonic('t');boxPanel.add(autoBox);// 以上为加入需要的 JCheckBox 组到指定的 JPanel:boxPanelqueryPanel.add(boxPanel); // 加入含 JCheckBox 组的 JPanel 到 queryPaneldbTabPane.add("Query", queryPanel);// 设置"Query"JPanel(图 3.4-2)的布局initDrvPanel();}/** 设置"Drivers"JPanel(图 3.4-3)的布局 */private void initDrvPanel(){gridBag.fill = GridBagConstraints.HORIZONTAL;gridBag.weightx = 100;gridBag.weighty = 0;tipLabel.setForeground(Color.black);this.add(drvPanel, tipLabel, gridBag, 0, 0, 4, 1);urlLabel.setForeground(Color.black);this.add(drvPanel, urlLabel, gridBag, 0, 5, 4, 1);urlField.setEditable(false);this.add(drvPanel, urlField, gridBag, 0, 6, 4, 1);gridBag.weightx = 0;gridBag.weighty = 0;addButton.setMnemonic('A');this.add(drvPanel, addButton, gridBag, 3, 1, 1, 1);editButton.setMnemonic('E');this.add(drvPanel, editButton, gridBag, 3, 2, 1, 1);removeButton.setMnemonic('R');this.add(drvPanel, removeButton, gridBag, 3, 3, 1, 1);gridBag.fill = GridBagConstraints.BOTH;gridBag.weightx = 100;gridBag.weighty = 100;// 设置 JTable 组件:drvTable 的从 0 到 7 行第 0 列的值for (int i = 0; i < 8; i++)drvTable.setValueAt(drvStrs[i],i,0);// 设置 JTable 的列头drvTable.getColumn(drvTable.getColumnName(0)).setHeaderValue("All Drivers");drvTable.setShowGrid(false);// 设置不显示网格线this.add(drvPanel, drvScroll, gridBag, 0, 1, 3, 4);dbTabPane.add("Drivers", drvPanel);}/** 初始化底部 JButton 组的布局 */private void initButtonPanel(){JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));// 从右边开始进行 FlowLayout 布局okButton.setMnemonic('O');buttonPanel.add(okButton);cancelButton.setMnemonic('C');buttonPanel.add(cancelButton);helpButton.setMnemonic('H');buttonPanel.add(helpButton);}/** 给指定的容器 cn 在指定的(x,y)位置放置指定大小(宽度 =w, 高度 =h)的组件 c*/private void add(Container cn, Component c, GridBagConstraints gbc, int x,int y, int w, int h){gbc.gridx = x;gbc.gridy = y;gbc.gridwidth = w;gbc.gridheight = h;cn.add(c, gbc);}

结束语

以上是本人在两年多 J2EE 应用开发中,总结的关于用 Java 进行 GUI 设计的一些经验,希望能给曾经象我一样迷惘,但依旧对 Java 一往情深,至今仍在摸索探求 Java GUI 设计捷径的朋友一些启示。更希望借此机会抛砖引玉,与更多的朋友进行交流与探讨。其实,在 Java 中所有的布局管理器都要实现一个接口,即 LayoutManager Inerface 或者是它的一个子接口 LayoutManager2 Interface,后者用于更复杂的布局管理。如果在实际应用中,觉得 Java API 提供的这些布局管理器仍不够用,你完全可以自己来实现其中某一个接口的方法,从而为你自己的具体 GUI 应用设计提供更好的布局管理。

这篇关于GUI图形界面(2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1037827

相关文章

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

Golang GUI入门——andlabs ui

官方不提供gui标准库,只好寻求第三方库。 https://github.com/google/gxui 这个gui库是谷歌内部人员提供的,并不是谷歌官方出品,现在停止维护,只好作罢。 第三方gui库 找了好多,也比较了好多,最终决定使用的是还是 https://github.com/andlabs/ui 相信golang gui还会发展的更好,期待更优秀的gui库 由于andlabs

GUI编程08:画笔paint

本节内容视频链接:10、画笔paint_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p=10&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5 package com.yundait.lesson03;import java.awt.*;import java.awt.event.Wind

C++入门(06)安装QT并快速测试体验一个简单的C++GUI项目

文章目录 1. 清华镜像源下载2. 安装3. 开始菜单上的 QT 工具4. 打开 Qt Creator5. 简单的 GUI C++ 项目5.1 打开 Qt Creator 并创建新项目5.2 设计界面5.3 添加按钮的点击事件5.4 编译并运行项目 6. 信号和槽(Signals and Slots) 这里用到了C++类与对象的很多概念 1. 清华镜像源下载 https://

Git Gui 查看分支历史的时候中文显示乱码

如图所示 在Git Gui工具栏上选择-编辑-选项: 选择:Default File Contents Encoding, change为UTF-8 成功:

结合Python与GUI实现比赛预测与游戏数据分析

在现代软件开发中,用户界面设计和数据处理紧密结合,以提升用户体验和功能性。本篇博客将基于Python代码和相关数据分析进行讨论,尤其是如何通过PyQt5等图形界面库实现交互式功能。同时,我们将探讨如何通过嵌入式预测模型为用户提供赛果预测服务。 本文的主要内容包括: 基于PyQt5的图形用户界面设计。结合数据进行比赛预测。文件处理和数据分析流程。 1. PyQt5 图形用户界面设计

Python GUI入门详解-学习篇

一、简介 GUI就是图形用户界面的意思,在Python中使用PyQt可以快速搭建自己的应用,自己的程序看上去就会更加高大上。 有时候使用 python 做自动化运维操作,开发一个简单的应用程序非常方便。程序写好,每次都要通过命令行运行 python 程序,就不是那么人性化了。为了更方便的操作,使用 Python GUI 编写界面程序,方便后续程序的操作。 二、安装PyQt5和配置可视化界面

王立平--Unity中的GUI Skin

C#脚本: public class NewBehaviourScript2 : MonoBehaviour { public Texture t; public GUISkin skin; // Use this for initialization void Start () { }  void OnGUI(){ GUILayout.BeginArea(new Rect(0, 0, Scr

王立平--GUI与GUILayout的区别

GUI.Button (new Rect(0,0,5,5,"哈哈"); GUILayout.Button ("heheh"); 1.以上代码都是现实一个按钮 2.不同之处: GUI中需要通过new Rect()指定button的位置,不灵活 GUILayout不需要指定位置,会自动确定现实位置,较为灵活。

yolov5 +gui界面+单目测距 实现对图片视频摄像头的测距

可实现对图片,视频,摄像头的检测  项目概述 本项目旨在实现一个集成了YOLOv5目标检测算法、图形用户界面(GUI)以及单目测距功能的系统。该系统能够对图片、视频或实时摄像头输入进行目标检测,并估算目标的距离。通过结合YOLOv5的强大检测能力和单目测距技术,系统能够在多种应用场景中提供高效、准确的目标检测和测距功能。 技术栈 YOLOv5:用于目标检测的深度学习模型。Open