[Java][图形程序设计Swing][学习笔记]

网友投稿 718 2022-05-29

很多人印象中Java编写的程序都是通过键盘接收输入,在控制台屏幕上显示结果。其实Java还可以编写使用图形用户界面(GUI) 的程序,今天就为大家介绍一下Java的图形界面-Swing。

1,Swing 概述

在 Java 1.0 刚刚出现的时候,包含了一个用于基本 GUI 程序设计的类库,Sun将它称为抽象窗口工具箱( Abstract Window Toolkit, AWT)。基本AWT库采用将处理用户界面元素的任务委派给每个目标平台( Windows、Solaris、 Macintosh 等)的本地 GUI 工具箱的方式,由本地 GUI 工具箱负责用户界面元素的创建和动作。因此,Sun 公司的口号是“ 一次编写,随处使用”。

但此方法在不同平台上,操作会存在差异。要想给予用户一致的、 可预见性的界面操作方式是相当困难的。在不同平台上的 AWT 用户界面库中存在着不同的 bug。研发人员必须在每一个平号上测试应用程序, 因此人们嘲弄地将 AWT 称为“ 一次编写, 随处调试”。

在 1996 年,Netscape 创建了一种称为 IFC ( Internet Foundation Class) 的 GUI 库, 它采用了与 AWT 完全不同的工作方式。它将按钮、菜单这样的用户界面元素绘制在空白窗口上,而对等体只需要创建和绘制窗口。因此,Netscape 的 IFC 组件在程序运行的所有平台上的外观和动作都一样。Sun 与 Netscape 合作完善了这种方式, 创建了一个名为 Swing 的用户界面库。

注意:Swing 没有完全替代 AWT, 而是基于 AWT 架构之上。Swing 仅仅提供了能力更加强大的用户界面组件。 尤其在采用 Swing 编写的程序中,还需要使用基本的 AWT 处理事件。可以理解为:Swing 是指 “ 被绘制的” 用户界面类;AWT 是指像事件处理这样的窗口工具箱的底层机制。

Swing的优势主要有:

Swing 拥有一个丰富、 便捷的用户界面元素集合。

Swing 对底层平台依赖的很少,因此与平台相关的 bug 很少。

Swing 给予不同平台的用户一致的感觉。

2,创建框架

在 Java 中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)。在 AWT 库中有一个称为 Frame 的类, 用于描述顶层窗口。这个类的 Swing 版本名为 JFrame,它扩展于 Frame 类。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修改部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。

本节中将介绍有关Swing的JFrame的常用方法。以下例子是给出了一个在屏幕中显示一个空框架的简单程序。

import javax.swing.*; import java.awt.*; public class SimpleFrameTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { SimpleFrame frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } } class SimpleFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public SimpleFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); } }

Swing类位于javax.swing包中。包名javax表示这是一个Java扩展包,而不是核心包。

默认情况下,框架的大小为0×0像素,这种框架没有什么实际意义。这里定义了一个子类SimpleFrame,它的构造器将框架大小设置为300×200像素。这是SimpleFrame和JFrame之间唯一的差别。

在SimpleFrameTest类的main方法,我们构造了一个SimpleFrame对象使它可见。

在每个Swing程序中,有两个技术问题需要强调

1,所有的Swing组件必须由事件分派线程(event dispatch thread)进行配置,线程将鼠标点击和按钮控制转移到用户接口组件。下面的代码片段是事件分派线程中的执行代码:

EventQueue.invokeLater(()-> { statements });

2,定义一个用户关闭这个框架时的响应动作。对于这个程序而言,只让程序简单退出即可。选择这个响应动作的语句是:frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);,在包含多个框架的程序中,不能在用户关闭其中的一个框架时就让程序退出。在默认情况下,用户关闭窗口时只是将框架隐藏起来,而程序并没有终止。框架起初是不可见的,为了显示框架,main方法需要调用框架的setVisible()方法。

在初始化语句结束后,main方法退出。需要注意,退出main并没有终止程序,终止的只是主线程。事件分派线程保持程序处于激活状态,知道关闭框架或调用System.exit方法终止程序。

3,框架定位

JFrame类本身只包含若干个改变框架外观的方法。当然,通过继承,从JFrame的各个超类中继承了许多用于处理框架大小和位置的方法。其中最重要的有下面几个:

setLocation和setBounds方法用于设置框架的位置。

setIconImage用于告诉窗口系统在标题栏、任务切换窗口等位置显示哪个图标。

setTitle用于改变标题栏的文字。

setResizable利用一个boolean值确定框架的大小是否允许用户改变。

AWT和Swing中框架和组件类的继承层次

3.1,框架属性

组件类的很多方法是以获取/设置方法对形式出现的,这样的一个获取/设置方法对被称为一种属性。属性包含属性名和类型。将get或set之后的第一个字母改为小写字母就可以得到相应的属性名。

针对get/set约定有一个例外:对于类型为boolean的属性,获取方法由is开头。

3.2,确定合适的框架大小

要记住:如果没有明确地指定框架的大小,所有框架的默认值为0×0像素。

API:java.awt.Component 1.0

boolean isVisible()

void setVisible(boolean b)

获取或设置visible属性。组件最初是可见的,但JFrame这样的顶层组件例外。

void setSize(int width,int height) 1.1

使用给定的宽度和高度,重新设置组件的大小。

void setLocation(int x,int y) 1.1

将组件移到一个新的位置上。如果这个组件不是顶层组件,x和y左边(或者p.x和p.y)是容器坐标;否则是屏幕坐标(例如:JFrame)

void setBounds(int x,int y,int width,int height) 1.1

移动并重新设置组件的大小

Dimension getSize() 1.1

void setSize(Dimension d) 1.1

获取或设置当前组件的size属性

API:java.awt.Window 1.0

void toFront()

将这个窗口显示在其他窗口前面 — void toBack()

将这个窗口移到桌面窗口栈的后面,并相应地重新排列所有的可见窗口。

boolean isLocationByPlatform() 5.0

void setLocationByPlatform(boolean b) 5.0

获取或设置locationByPlatform属性。这个属性在窗口显示之前被设置,由平台选择一个合适的位置。

API:java.awt.Frame 1.0

boolean isResizable()

void setResizable(boolean b)

获取或设置resizable属性。这个属性设置后,用户可以重新设置框架的大小。

String getTitle()

void setTitle(String s)

获取或设置title属性,这个属性确定框架标题栏中的文字

Image getIconImage()

void setIconImage(Image image)

获取或设置iconImage属性,这个属性确定框架的图标。窗口系统可能会将图标作为框架装饰或其他部位的一部分显示。

boolean isUndecorated() 1.4

void setUndecorated(boolean b) 1.4

获取或设置undecorated属性。这个属性设置后,框架显示中将没有标题栏或关闭按钮这样的装饰。在框架显示之前,必须调用这个方法。

int getExtendedState() 1.4

void setExtendedState(int state) 1.4

获取或设置窗口状态。状态是下列值之一。

Frame.NORMAL

Frame.ICONIFIED

Frame.MAXIMINZED_HORIZ

Frame.MAXIMIZED_VERT

Frame.MAXIMIZED_BOTH

[Java][图形程序设计Swing][学习笔记]

API:java.awt.Toolkit 1.0

static Toolkit getDefaultToolkit()

返回默认的工具箱

Dimension getScreenSize()

返回用户屏幕的尺寸

API:javax.swing.ImageIcon 1.2

ImageIcon(String filename)

构造一个图标,其图像存储在一个文件中

Image getImage()

获得该图标的图像

6,使用颜色

Color类用于定义颜色。在java.awt.Color类中提供了13个预定义的常量,它们分别表示13种标准颜色

BLACK,BLUE,CYAN,DARK_GRAY,GRAY,GREEN,LIGHT_GRAY,MAGENTA,ORANGE,PINK,RED,WHITE,YELLOW

可以通过提供红、绿、蓝三色成分创建一个Color对象,以达到定制颜色的目的。三种颜色都是用0-255(也就是一个字节)之间的整型数值表示,调用Color的构造器格式为:Color(int redness,int greenness,int blueness)

API:java.awt.Color 1.0

Color(int r,int g,int b)

创建一个颜色对象

参数:r 红色值(0-255)

参数:g 绿色值(0-255)

参数:b 蓝色值(0-255)

API:java.awt.Graphics 1.0

Color getColor()

void setColor(Color c)

获取或改变当前的颜色。所有后续的绘图操作都使用这个新颜色

参数:c 新颜色

API:java.awt.Graphics2D 1.2

Paint getPaint()

void setPaint(Paint p)

获取或设置这个图形环境的绘制属性。Color类实现了Paint接口。因此,可以使用这个方法将绘制属性设置为纯色。

void fill(Shape s)

用当前的颜料填充该图形

API:java.awt.Component 1.0

Color getBackground()

void setBackground(Color c)

获取或设置背景颜色

参数:c 新背景颜色

Color getForeground()

void setForeground(Color c)

获取或设置前景颜色

参数:c 新背景颜色

7,文本使用特殊字体

如果经常选用不同的字体显示文本。人们可以通过字体名(font face name)指定一种字体。字体名由"Helvetica"这样的字体家族名(font family name)和一个可选的"Bold"后缀组成。例如:"Helvetica"和"Helvetica Bold"属于"Helvetica"家族的字体。

想知道某台计算机上允许使用的字体,需要调用GraphicsEnvironment类中的getAvailableFontFamilyNames方法。这个方法将返回一个字符型数组,其中包含了所有可用的字体名。

import java.awt.*; public class ListFonts { public static void main(String[] args) { String[] fontNames = GraphicsEnvironment .getLocalGraphicsEnvironment() .getAvailableFontFamilyNames(); for (String fontName : fontNames) { System.out.println(fontName); } } }

API:java.awt.Font 1.0

Font(String name,int style,int size)

创建一个新字体对象

参数:name 字体名。不是字体名(例如,“Helvetica Bold”),就是逻辑字体名(例如,“Serif”,“SansSerif”)

参数:style 字体风格(Font.PLAIN,Font.BOLD,Font.ITALIC或Font.BOLD+Font.ITALIC)

参数:size 字体大小

String getFontName()

返回字体名,例如,“Helvetica Bold”

String getFamily()

返回字体家族名,例如,“Helvetica”

String getName()

如果采用逻辑字体名创建字体,将返回逻辑字体,例如,“SansSerif”;否则,返回字体名。

Font deriveFont(int style) 1.2

Font deriveFont(float size) 1.2

Font deriveFont(int style,float size) 1.2

返回一个新字体,除给定大小和字体风格外,其余与原字体一样

API:java.awt.font.LineMetrics 1.2

float getLeading()

返回字体的行间距-从一行文本底端到下一行文本顶端之间的空隙

float getHeight()

返回字体的总高度-两条文本基线之间的距离(下坡度+行间距+上坡度)

API:java.awt.Graphics 1.0

Font getFont()

void setFont(Font font)

获取或设置当前的字体。这种字体将被应用与后续的文本绘制操作中。

参数:font 一种字体

void drawString(String str,int x,int y)

采用当前字体和颜色绘制一个字符串

参数:str 将要绘制的字符串

参数:x 字符串开始的x坐标

参数:y 字符串开始的y坐标

8,显示图像

对于照片这样的复杂图像来说,通常都是由扫描仪或特殊的图像处理软件生成的。

一旦图像保存在本地或网络上,就可以将它们读到Java应用程序中,并在Graphic对象上进行显示。

以下例子:在一个窗口中平铺显示了一幅图像。这里采用paintComponent方法来实现平铺显示。它的基本过程为:先在左上角显示图像的一个拷贝,然后使用copyArea将其拷贝到整个窗口。

import javax.swing.*; import java.awt.*; public class ImageTest { public static void main(String[] args) { JFrame frame = new ImageFrame(); frame.setTitle("ImageTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } /* * A frame with an image component * */ class ImageFrame extends JFrame { public ImageFrame() { add(new ImageComponent()); pack(); } } /* * A component that displays a tiled image * */ 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("blue-ball.gif").getImage(); } public void paintComponent(Graphics g) { if (image == null) { return; } int imageWidth = image.getWidth(this); int imageHeight = image.getHeight(this); //draw the image in the upper-left corner g.drawImage(image, 0, 0, null); //tile the image across the component for (int i = 0; i * imageWidth <= getWidth(); i++) { for (int j = 0; j * imageHeight <= getHeight(); j++) { if (i + j > 0) { g.copyArea(0, 0, imageWidth, imageHeight, i * imageWidth, j * imageHeight); } } } } public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } }

Java

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:从零开始—Scrum团队敏捷转型实战案例
下一篇:图神经网络“借力”华为ModelArts,让电商平台营销推广更精准
相关文章