图形界面设计

Posted 快乐在角落里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形界面设计相关的知识,希望对你有一定的参考价值。

第8章 图形界面设计

1 AWT 和 Swing

图形用户界面简称GUI

设计图形用户界面时一般有3个步骤,分别是选取组件,设计布局和响应事件。

Java抽象窗口工具集称为AWT,后来的JDK版本提供的Swing功能更强

awt在java.awt包中,swing在javax.swing包中

Swing组件与AWT组件最大的不同是Swing组件在实现时不包含任何本地代码,因此Swing组件可以不受硬件平台的限制,而具有更多的功能。不包含本地代码的Swing组件被称为轻量级组件,而包含本地代码的AWT组件成为重量级组件。

当重量级组件和轻量级组件一同使用时,如果组件区域有重叠,则重量级组件总是显示在上面。

Java的图形用户界面由各种组件构成,组件是构成图形用户界面的基本元素。

按钮,文本输入框,标签都是组件,框架,面板都称为容器。

2 容器

组件可以分为容器组件和非容器组件,容器组件就是可以包含其它组件的组件,分为顶层容器和一般用途容器,非容器组件必须要包含在容器中。

Java为所有容器类定义了Container父类,容器的共有操作都定义在Container类中。

顶层容器

Swing提供了4种顶层容器,分别为 JFrame,JApplet,JDialog 和 JWindow。

JFrame是一个带有标题和控制按钮(最小化,恢复/最大化,关闭)的独立窗口,有时称为框架,创建应用程序时需要使用JFrame。

JApplet创建小应用程序,他被包含在浏览器窗口中。

JDialog创建对话框。

Jwindow是一个不带有标题行和控制按钮的窗口,很少使用。

JFrame构造方法

空构造方法和指定标题的构造方法

new JFrame();//不可见,无标题新框架窗体
new JFrame("新窗口");//初始不可见,具有指定标题的新框架窗体

相关方法

//移动并调整框架大小,左上角位置的横纵坐标由x,y控制,框架的宽高由width和height控制
void setBounds(int x,int y,int width,int height)
//框架的宽高由width和height控制
void setSize(int width,int height)
//设置框架的背景色
void setBackground(Color bg)
//设置框架可见或不可见
void setVisible(boolean flag)
//调整框架的大小,已适合其子组件的首选大小和布局
void pack()    
//设置框架的标题
void setTiltle(String title)
// 返回此框架窗体的内容窗格对象
Container getContentPane()
//设置布局管理器
void setLayout(LayoutMananger manager)

内容窗口

四个顶层容器中的每一个都有一个内容窗格。有两种方法可以将组件放入内容窗格中,一种方法是通过顶层容器的getContentPane 方法获取其默认的内容窗格。返回只是一个 Container 它仍然是一个容器。

另一种方法是创建一个新的内容窗格,以取代顶层容器默认的内容窗格。通常的做法是创建一个JPanel的实例,他是 Container 的子类。然后将组件添加到 JPanal实例中,再通过顶层容器的setContentPane方法将JPanel实例设置为新的内容窗格。

顶层容器默认内容窗格的布局管理器是 BorderLayout,而JPanel默认的布局管理器是FlowLayout,因此需要为JPanel实例设置一个 BorderLayout 布局管理器。

面板

普通面板JPanel和滚动面板 JScrollPane都是用途广泛的容器。与顶层容器不同,面板不能独立存在,必须被添加到其他容器内部。面板可以嵌套,由此可以设计出复杂的图形用户界面。

当容器中组件过多而不能在显示区域内全部显示时,可以让容器带滚动条,从而显示出全部的组件。使用滚动面板可以实现这个功能。

JPanel构造方法

JPanel JPanel();
JPanel JPanel(LayoutManager manager);

使用 add(Component comp) 方法可以将指定组件追加到面板中

JScrollPane 是带有滚动条的面板,他是 Container的子类。但是只能添加一个组件,所以当有多个组件需要添加时,一般是先将多个组件添加到JPanel中,然后再将这个JPanel添加到JScrollPane中。

public static void main(String[] args) 
    JScrollPane scrollPane = new JScrollPane();
    //创建一个显示指定组件内容的JScrollPane,只要组件的内容超过视图大小,就会显示水平和垂直滚动条
    scrollPane = new JScrollPane(panel);
    scrollPane.setHorizontalScrollBarPolicy
        (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);//水平需要时可见
    scrollPane.setHorizontalScrollBarPolicy
        (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);//水平时总是不可见
    scrollPane.setHorizontalScrollBarPolicy
        (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);//水平时总是可见

    scrollPane.setVerticalScrollBarPolicy
        (ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);//垂直需要时可见
    scrollPane.setVerticalScrollBarPolicy
        (ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);//垂直总是不可见
    scrollPane.setVerticalScrollBarPolicy
        (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);//垂直总是可见

AWT中还有一个滚动条组件,提供了一个允许用户在一定范围的值中进行选择的便捷方法

new Scrollbar();//新的垂直滚动条
new Scrollbar(Scrollbar.HORIZONTAL);//水平滚动条
new Scrollbar(Scrollbar.VERTICAL);//垂直滚动条
Scrollbar(int orientation, int value, int visible, int minimum,int maximum)
//orientation指定方向,value滚动条初始值,visible滚动条可视量
//minimum滚动条最小值,maximum滚动条最大值

3 标签及按钮

标签

JLabel 对象是最简单的Swing组件,通常用于显示提示性的文本信息或图标。不可被编辑,构造方法有6种。

new JLabel();//空标签
new JLabel(Icon image);//显示图标的标签 可用ImageIcon传入图片地址
new JLabel("");//创建一个显示文本信息的标签
new JLabel(imageIcon,JLabel.CENTER);//创建一个水平对齐的图标
new JLabel("",JLabel.RIGHT);//创建一个水平对齐的文本标签
new JLabel("",imageIcon,JLabel.LEFT);//创建一个水平对齐带文本带图标的标签
//水平对齐方式
//JLabel.CENTER;居中
//JLabel.RIGHT;右对齐
//JLabel.LEFT;左对齐
jLabel1.setHorizontalAlignment(JLabel.CENTER);
jLabel1.setVerticalAlignment(JLabel.BOTTOM);
setText(String text);
setIcon(Icon icon);

按钮

JButton是Java图形用户界面的基本组件之一,经常用到的按钮有4种形式。

JButton,JToggleButton,JCheckBox,JRadioButton

各种按钮上都可以设置文本,设置图标,注册事件侦听程序。有 addActionListener,setEnabled,setText,setIcon 等方法

构造方法有空按钮,没有显示文本但有图标的按钮,有显示文本没有图标的按钮,有显示文本也有图标的按钮

使用 addActionListener 为按钮注册事件侦听程序并实现 ActionListener接口

// 常用方法
button.setMnemonic(KeyEvent.VK_A);//设置当前按钮的键盘助记符 KeyEvent
button.setText("按钮1");
button.getText();
button.setToolTipText("快捷键按 alt + A");//设置要显示的提示文本
button.addActionListener(e -> 
    System.out.println("111");
);//添加事件侦听程序

切换按钮 复选按钮 单选按钮

JToggleButton有选中状态和未选中状态

构造方法有设置默认选定和未选定,还可以设置文字和图片,有一个 isSelected() 方法,可以获知按钮当前的状态,返回值为true时处于选中状态

JCheckBox,JRadioButton都是JToggleButton 的子类,也可以选中和未选中

具有两种状态的按钮不仅可以注册 ActionEvent 事件监听程序,还可以注册 ItemEvent 事件监听程序。ItemListener 接口当按钮的状态发生改变时将会调用该类方法。

ItemListener, ActionListener 的区别在该程序中就是 ItemListener 会监听按钮组里面取消选中的操作,而 ActionListener不会。

ActionEvent 和 ItemEvent 都提供了 getSource() 方法,但返回对象是 Object,需要强转才能使用,ItemEvent 还有个 getItem()方法,返回值和用法和 getSource() 一致。

isSelected() 返回 true 或者 false,表名按钮是否选中

JCheckBox 加入按钮组之后只能单选,JRadioButton 如果不加入按钮组也可以多选,但是通常用 JCheckBox 表示可多选的选择项(不加入按钮组),而用 JRadioButton 表示只能单选的选择项(加入按钮组),因此 JCheckBox 称为复选按钮,而 JRadioButton 被称为单选按钮

//设置边框
Border etchedBorder = BorderFactory.createEtchedBorder();
Border border = BorderFactory.createTitledBorder(etchedBorder, "复选按钮");
jPanel.setBorder(border);

//加入按钮组
ButtonGroup group1 = new ButtonGroup();
group1.add(checkBox4);
group1.add(checkBox5);
group1.add(checkBox6);

//文本框
JTextArea textArea = new JTextArea();
//带滚动条面板
JScrollPane scrollPane = new JScrollPane(textArea);

4 布局管理器

容器中包含了组件。组件的布局,包括各组件的位置和大小,通常由布局管理器负责安排。每个容器都有一个默认的布局管理器,可以通过容器的 setLayout() 方法改变容器的布局管理器

FlowLayout 布局管理器

定义在awt包中,这个布局管理器对容器中组件进行布局的方式是将组件逐个地放置在容器的一行上,一行放满后就另起一个新行。

FlowLayout()//默认构造方法,居中对齐,默认水平和垂直间距5个像素
FlowLayout(int 对齐)//创建一个指定对齐方式的布局管理器,默认水平和垂直间距5个像素
FlowLayout(int 对齐,int 水平间距,int 垂直间距)//创建指定对齐方式和水平间距垂直间距的布局管理器
new FlowLayout(FlowLayout.LEFT)//左对齐 0
new FlowLayout(FlowLayout.CENTER);//居中对齐 1
new FlowLayout(FlowLayout.RIGHT);//右对齐 2
new FlowLayout(FlowLayout.LEADING);//该值表示每行组件都应对齐到容器方向的前缘 3 
new FlowLayout(FlowLayout.TRAILING);//该值表示每行组件都应与容器方向的后缘对齐 4

与其他布局管理器不同的是,FlowLayout 并不强行设定组建的大小,而是允许组件拥有它们自己所希望的尺寸,每个组件都有一个 getPreferredSize() 方法,容器的布局管理器会调用这一方法取得每个组件希望的大小。

BorderLayout 默认布局管理器

是顶层容器中内容窗格的默认布局管理器,它提供了一种较为复杂的组件布局管理方案。每个由 BorderLayout 管理的容器被划分成5个区域,分别代表容器的上部(North),下部(South),左部(West),右部(East)和中部(Center)

分别用以下常量表示,在容器的每个区域可以加入一个组件

BorderLayout.NORTH
BorderLayout.SOUTH
BorderLayout.WEST
BorderLayout.EAST
BorderLayout.CENTER

两个构造方法,默认没有间距的布局管理器,和指定水平和垂直间距的布局管理器

组件必须通过 add() 方法加入到容器中的指定区域。如果没有指定,则默认会放置到 Center 区域

在容器的每个区域,只能加入一个组件,如果试图向某个区域加入多个组件,那么只有最后一个组件是有效的。

对于除Center外的其他边界区域,如果没有使用,那么它的大小将变为零,此时 Center 区域将会扩展并占据这个未用区域的未知。

当窗口大小改变时,窗口中按钮的相对位置不会发生改变,但按钮的大小会随之改变。

GridLayout 网格式布局管理器

是一种网格式的布局管理器,他将容器空间划分成若干行乘若干列的网格,组件依次放入其中,每个组件占据一格。有三个构造方法。

public GridLayout() 
    this(1, 0, 0, 0);

public GridLayout(int rows, int cols) 
    this(rows, cols, 0, 0);

public GridLayout(int rows, int cols, int hgap, int vgap) 
    if ((rows == 0) && (cols == 0)) 
        throw new IllegalArgumentException("rows and cols cannot both be zero");
    
    this.rows = rows;
    this.cols = cols;
    this.hgap = hgap;
    this.vgap = vgap;

默认创建一个只有一行的网格布局管理器,网格的列数根据实际需要而定。

创建指定行数,列数的布局管理器。

创建指定行数,列数,水平和垂直间距的布局管理器。

构造方法中,行数和列数中的一个可以为0,但不能同时为0,如果行为0,那么网格的行数将根据实际需要而定,如果列为0,也将根据实际需要来定。

网格每列的宽度都是相同的,每行的高度也是相同的。组建被放入容器的次序决定了它所占据的位置。每行网格从左至右依次填充,一行用完之后转入下一行。

如果想在组建之间留有空白,则可以添加一个空白标签

如果网格的个数多余要添加的组件的个数,则空余的网格为空白。

如果网格的个数少于要添加的组件的个数,则系统根据实际需要适当添加。

当容器的大小发生改变时,组件相对位置不会改变,但是组件的大小会随之改变。

CardLayout 卡片式布局管理器

卡片式布局管理器,它将容器中的组件处理为一系列卡片,每一时刻只显示出其中的一张,而容器充当卡片的内容。让容器第一次显示时,第一个添加到 CardLayout 对象的组件为可见组件

卡片的顺序由组件对象本身在容器内部的顺序决定。

构造方法

public CardLayout() 
	this(0, 0);//无间距

public CardLayout(int hgap, int vgap) 
    this.hgap = hgap;//水平间距
    this.vgap = vgap;//垂直间距

除了将组件加入容器外,还有以下常用方法

void first(父容器)//第一张 父容器可以是内容窗格 frame.getContentPane()
void next(父容器)//下一张
void previous(父容器)//上一张
void last(父容器)//最后一张
void show(父容器,String)//翻转到已添加到此布局的具有指定 name 的卡片。如果不存在,则不方法任何事情

BoxLayout 布局管理器

将容器中的组件按水平方向排成一行或按垂直方向排成一列。当组件排成一行时,每个组件可以有不同的宽度,当组件排成一列时,每个组件可以有不同的高度。

构造方法只有一个

public BoxLayout(Container target, int axis) 
    if (axis != X_AXIS && axis != Y_AXIS &&
        axis != LINE_AXIS && axis != PAGE_AXIS) 
        throw new AWTError("Invalid axis");
    
    this.axis = axis;
    this.target = target;

创建一个将沿给定轴放置组件的布局管理器,Container 参数指明是为哪个容器设置此 BoxLayout 布局管理器,int型参数指明组件的排列方向,通常使用的常量有

BoxLayout.X_AXIS;//水平方向排列
BoxLayout.Y_AXIS;//垂直方向排列
BoxLayout.LINE_AXIS;//指定组件应按照目标容器的ComponentOrientation属性确定的文本行方向进行布局。
BoxLayout.PAGE_AXIS;//指定组件应按照目标容器的ComponentOrientation属性确定的行在页面上流动的方向进行布局。

在 javax.swing 中定义了一个专门使用 BoxLayout的特殊容器 Box类,Box类中提供了创建Box实例的静态方法

Box.createHorizontalBox();//水平方向排列
Box.createVerticalBox();//垂直方向排列
// 不可见组件
Box.createHorizontalGlue();//填满所有剩余水平空间
Box.createVerticalGlue();//填满所有剩余垂直空间
Box.createHorizontalStrut(100);//指定水平宽度
Box.createVerticalStrut(100);//指定垂直高度
Box.createRigidArea(new Dimension(100,100));//指定水平宽度和垂直高度

空布局

在特殊场合,也可以不使用布局管理器,而是通过数值指定组件的位置和大小,这时首先需要调用容器的 setLayout(null) 将布局管理区设置为空,然后调用组建的 setBounds() 方法设置组件的位置和大小

public void setBounds(int x, int y, int width, int height) 
    reshape(x, y, width, height);

前两个int型参数设置组件的位置,后两个int型参数设置组件的宽度和高度。

//设置边框
Border etchedBorder = BorderFactory.createEtchedBorder();
Border border = BorderFactory.createTitledBorder(etchedBorder, "复选按钮");
jPanel.setBorder(border);

//加入按钮组
ButtonGroup group1 = new ButtonGroup();
group1.add(checkBox4);
group1.add(checkBox5);
group1.add(checkBox6);

//文本框
JTextArea textArea = new JTextArea();
//带滚动条面板
JScrollPane scrollPane = new JScrollPane(textArea);

5 事件处理

对事件的响应称为事件处理

事件处理模型

Java 中定义了很多事件类,用于描述不同的用户行为。每当用户在组件上进行某种操作时,事件处理系统便会生成一个事件类对象。操作不同,事件类对象也会不同。

为了便于管理,系统将事件分类,称为事件类型。系统为每个事件类型提供一个侦听程序接口,它规定了接受并处理该类事件的方法的规范。为了接受并处理某类用户事件,组件必须注册相应的事件处理程序,这种事件处理程序称为事件侦听程序,侦听器。它是实现了对应侦听程序接口的一个类。

JButton 中可以注册 ActionEvent 事件侦听程序,还可以删除添加的事件侦听程序。

addActionListener(ActionListener l);//添加事件侦听器
removeActionListener(ActionListener l);//移除指定的操作侦听器

这种处理事件机制称为委托事件处理模型 ,事件被直接送往产生这个事件的组件,组件需要注册一个或多个侦听程序。侦听程序的类包含了事件处理程序,用来接受和处理这个事件。事件是一个对象,他只向注册的侦听程序报告。

事件处理的步骤如下:

  1. 程序引入 java.awt.enent 包
  2. 给所需的事件源对象注册事件侦听程序
  3. 实现相应的方法、若某个侦听程序接口包含多个方法,则需要实现所有的方法。

事件的种类

在 java.awt.event 和 javax.swing.event 包中还定义了很多其他事件类。

常用事件类型表

事件适配器

事件侦听模式允许为一个组件注册多个侦听程序,通常的做法时在该事件的处理程序中编写需要的所有响应。当事件发生时,单个事件的多个侦听程序的调用顺序时不确定的。

为了进行事件处理,需要创建实现 Listener 接口的类,而在某些 Listener 接口中,声明了很多抽象方法,为了实现这些接口,需要一一实现这些方法。然而,在某些情况下,关心得只是接口中得个别方法。

为了编程方便,Java为一些声明了多个方法得 Listener 接口提供了相对应得适配器类。

在适配器类中实现了相应接口中的全部方法,只是方法的内容为空。

6 绘图基础

颜色

可以使用 java.awt 包中的 Color 类来定义和管理颜色。Color类的每个对象表示一种颜色。可以有两种方法生成颜色,一种是预定义的颜色,全大写全小写都行,另一种是通过红绿蓝三原色的值来组合。每种颜色由三个值来指定,称为RGB值,RGB分别代表红绿蓝。各个值表示对于原色的相对值,使用1个字节来保存。取值范围为0~255

可以使用 JComponent 中的方法设置组件的前景色和背景色。

panel.setForeground(Color.RED);//前景色
panel.setBackground(Color.green);//背景色

字体

显示文字的方法主要有三种

Graphics类
public void drawChars(char data[], int offset, int length, int x, int y)
public abstract void drawString(String str, int x, int y)
public void drawBytes(byte data[], int offset, int length, int x, int y)

文字字形有字体,样式及字号3个要素

常用的字体有 Times New roman,Symbol,宋体,楷体等

基本的样式有 Font.PLAIN(正常),Font.BOLD(粗体),Font.ITALIC(斜体)

字号是字的大小,单位是磅

可以使用 setFont 方法对组件中文本的字体进行设定,这个方法需要Font 类的一个实例做参数,没有预定义的字体常量,因此需要通过给字体名称,样式和大小自己创建 Font 对象,构造方法如下

public Font(String name, int style, int size)//字体名称,字体样式,字体大小

Font 类中常用的方法如下

public String getName()//返回此Font 的逻辑名称,即字体名称
public int getSize()//返回 Font 的字体大小
public int getStyle()// 返回 Font 的样式
public boolean isPlain()// 测试此 Font 的样式是否是正常的
public boolean isBold()// 测试此 Font 的样式是否是粗体的
public boolean isItalic()// 测试此 Font 的样式是否是斜体的

Graphics 类的基本功能

Graphics 类是所有图形处理的基础。是所有图形上下文的抽象父类,允许应用程序在组件以及屏幕图像上进行绘制。提供的功能有,建立字体,设定显示颜色,显示图像和文本,绘制和填充各种几何图形。

也可以在组件上绘制图形,当先后绘图的图形有重叠时,如何确定重叠部分的颜色呢,这称为绘图模式。

绘图模式分别是正常模式和异或模式,正常模式下,后绘制的图形覆盖先绘制的图形,使得先绘制的图形被重叠的部分不再可见。异或模式下,当前绘制的颜色,先前绘制的颜色及所选定的某种颜色之间进行某种处理,使用得到的新颜色进行绘制。

设置绘图模式如下

setPaintMode()//默认正常模式
setXORMode(Corlor c)//将此图形上下文的绘图模式设置为异或模式,参数 c 指定了绘制对象时与窗口进行异或的颜色

选择异或模式下,如果使用同一颜色绘制两遍,则相当于擦除第一次绘制的图形,也即恢复原来的状态。

所有绘制都必须通过一个图形对象完成。可以直接在框架 Frame 中显示文本信息,也可以直接在框架中绘图。在某个组件中绘图,一般应该为这个组件所属的子类重写 paint() 方法,在该重写的方法中进行绘图,

但要在 JComponent 子类的组件中绘图,应重写 paintComponent() 方法,在该方法中进行绘图。

系统自动为程序提供图形对象,并以参数 g 传递给 paint() 方法和 painComponent() 方法。

paintComponent 方法包含一个 Graphics 类型的参数,可以从图形对象或使用 Component的getGraphics() 方法得到 Graphics 对象

java.awt.Component 类中定义了 paint() 当组件被显示出来时,将调用该方法,还定义了repaint() 每当需要重绘时,可以调用该方法,该方法将自动调用 paint 方法。

JComponent 继承 Component 并重写了 paint 方法,该方法中会调用如下3个方法。

paintComponent()//绘制组件
paintBorder()//绘制组件的边框
paintChildren()//绘制组件中的子组件

通常情况下,如果需要在组件上绘制图形,只需要重写 JComponent 的 paintComponent 方法

Graphics 中定义了多种绘图方法,分别如下

//沿着由左上角为(x,y) 宽为 width,高为 height 的外接矩形所限定的椭圆绘制一条弧,弧起始于startAngle,延伸的距离由arcAngle定义
public abstract void drawArc(int x, int y, int width, int height,int startAngle, int arcAngle)
//绘制一条从点 (x1,y1)到点(x2,y2)的直线
public abstract void drawLine(int x1, int y1, int x2, int y2)
//绘制一个由左上角为(x,y)宽为width,高为height的外接矩形的椭圆
public abstract void drawOval(int x, int y, int width, int height)
//绘制由x和y坐标数组定义的一系列连接线。每队(x,y)定义了一个点。如果第一个点和最后一个点不同,则图形不是闭合的
public abstract void drawPolygon(int xPoints[], int yPoints[],int nPoints)
//绘制一个矩形,左上角为(x,y) 宽为width,高为 height
public void drawRect(int x, int y, int width, int height)
//用此图形上下文的当前颜色绘制圆角矩形的边框。矩形的左边和右边分别位于 x 和 x+width 。矩形的顶边和底边位于 y 和 y + height
public abstract void drawRoundRect(int x, int y, int width, int height,int arcWidth, int arcHeight)
//在点 (x,y) 处输出字符串 str,向右扩展
public abstract void drawString(String str, int x, int y)
//绘制指定矩形的3D突出显示边框。矩形的左上角为(x,y),宽为width,高为height,raised指示矩形是凸出平面显示还是凹入平面显示。
public void fill3DRect(int x, int y, int width, int height,boolean raised)

还可以用Graphics类的方法来指定图形是否要填充,不填充的图形只显示图形的轮廓,而且是透明的,即可以看到下面的图形。上述方法绘制的图形都属于这一类。

与此相对应的,填充的图形在边界内是实心的,并遮挡了下层的图形。这类方法与对应的图形绘制方法相同,只是用当前的前景色填充图形

public abstract void fillArc(int x, int y, int width, int height,int startAngle, int arcAngle);
public abstract void fillOval(int x, int y, int width, int height);
public abstract void fillPolygon(int xPoints[], int yPoints[],int nPoints);
public abstract void fillRect(int x, int y, int width, int height);
public abstract void fillRoundRect(int x, int y, int width, int height,int arcWidth, int arcHeight);

每个图形环境都有一种画图或是画字符串时正是用的前景色。画图所在的每个表面都有背景色,用 Graphics 类中的 setColor 方法可以设置背景色,使用所画组件的 setBackgroun 方法可以设置背景色

多边形

多边形是由多个边的图形,在Java中,他由对应于多边形各顶点的点序列 (x,y) 来定义。常用数组来保存坐标序列

画多边形的方法分别是 drawPolygon() 和 fillPolygon() 这两种方法都是重载的,一种使用整数数组当作参数来定义多边形形式的方法,另一种是使用 Polygon 类的对象来定义多边形。

当使用数组作为参数时,drawPolygon() 和 fillPolygon() 各带3个参数,第一个参数是表示多边形各点 x 坐标的整数数组,第二个参数是表示多边形各点 y 坐标的整数数组,第三个参数是一个整数,表示两个数组中有多少个点可用。放在一起看,前两个参数表示 (x,y) 的坐标

多边形常是封闭的,线段总是从坐标序列中最后一个点画会序列中的第一个点。

折线

折线也包含了连接每个线段的一系列点,但与多边形不同的是,绘制折线时第一个坐标和最后一个坐标并不自动连接起来。因为折线不封闭,所以也不能填充,他只有一个方法 drawPolyline() 方法中的参数与 drawPolygon() 类似

Polygon 类

当使用 Polygon 类做参数时,可以使用 java.awt 包中定义的 Polygon 类的对象来显示的定义多边形,drawPolygon() 和 fillPolygon()重载带一个 Polygon 参数

Polygon 对象封装了多边形边的坐标。Polygon 类的构造方法可以创建一个初始的空多边形,或是由代表各顶点坐标的整数数组定义的多边形。 Polygon 类中有方法可以将点添加到多边形中,也有方法可以判定给定的点是不是在多边形上。它还能得到多边形的外接矩形的方法,以及将多边形中的所有点移到另一个位置的方法

//空的多边形
public Polygon() 
	xpoints = new int[MIN_LENGTH];//4
	ypoints = new int[MIN_LENGTH];//4

//使用xpoints 和 ypoints 中相对应的坐标对 (x,y) 来创建多边形
public Polygon(int xpoints[], int ypoints[], int npoints)
//将由参数指定的点加入到多边形中
public void addPoint(int x, int y)
//如果指定的点含在多边形中,则返回真
public boolean contains(int x, int y)
//如果指定的点含在多边形中,则返回真
public boolean contains(Point p)
//得到多边形的外接矩形
public Rectangle getBounds()
//将多边形的各顶点沿 x 轴偏移 deltaX 沿 y轴偏移 deltaY
public void translate(int deltaX, int deltaY)

在重写 paintComponent 方法时,需要首先调用父类的 paintComponent 方法。

Graphics2D 绘图

为了解决图形对象的局限性,引入了 Java 2D,Java2D包括一个继承鱼Graphics 类的 Graphics2D类,增加了许多状态属性,扩展了 Graphics的绘图功能,可以绘制出更加丰富多彩的图形。

Graphics2D 拥有更强大的 二维图形处理能力,提供对几何形状,坐标转换,颜色管理以及文字布局更复杂的控制。

图形状态属性

Graphics2D类中定义了几种方法,用于添加或改变图形的状态属性。通过设定和修改状态属性,可以指定画笔宽度和画笔的连接方式,设定平移,旋转,缩放或剪裁变换图形,还可以设定填充图形的颜色和图案等。

图形状态属性用特定的对象存储,有以下一些属性

stroke 属性

stroke 属性控制线的宽度,笔形样式,线段连接方式或短划线图案。创建BasicStroke对象后,再调用setStroke 方法设置 stroke属性。

public BasicStroke()
//指定线的宽度
public BasicStroke(float width)
//指定线的宽度,端点样式 cap 及两线段交汇处的连接方式 join
/**
cap取值
BasicStroke.CAP_BUTT 无修饰
BasicStroke.CAP_ROUND 半圆形末端
BasicStroke.CAP_SQUARE 方形末端,默认值
join取值
BasicStroke.JOIN_MITER 尖型末端 默认值
BasicStroke.JOIN_ROUND 圆形末端
BasicStroke.JOIN_BEVEL 无修饰
 */
public BasicStroke(float width, int cap, int join)
public BasicStroke(float width, int cap, int join, float miterlimit)
public BasicStroke(float width, int cap, int join, float miterlimit,float dash[], float dash_phase)

paint 属性

paint 属性控制填充效果。先调用 GradientPaint() 方法确定填充效果,再使用 setPaint 方法进行设置

GradientPaint 方法如下

//构造一个简单的非周期性的 GradientPaint 对象,从点 (x1,y1) 到点 (x2,y2) color1 点 (x1,y1)的颜色 color2 点 (x2,y2)的颜色 从 color1 渐变到 color2
public GradientPaint(float x1,
                         float y1,
                         Color color1,
                         float x2,
                         float y2,
                         Color color2)
//根据 boolean 参数构造一个周期性或非周期性的GradientPaint 对象,如果希望渐变到终点又是起点的颜色,应将 cyclic 设置为 true
public GradientPaint(float x1,
                         float y1,
                         Color color1,
                         float x2,
                         float y2,
                         Color color2,
                         boolean cyclic)
transform 属性

该属性用来实现常用的图形平移,缩放,斜切等变换操作,首先创建 AffineTansform 对象,然后调用 setTransform 方法设置 transform 属性。最后,使用具有指定属性的 Graphics2D对象绘制图形。

构造方法和常用方法如下

//构造一个表示仿射变换的新 AffineTransform
public AffineTransform()
//旋转 theta 弧度
public static AffineTransform getRotateInstance(double theta)
//绕旋转中心(x,y)旋转
public static AffineTransform getRotateInstance(double theta,
                                                    double anchorx,
                                                    double anchory)
//x和y方向分别按 sx sy比例变换
public static AffineTransform getScaleInstance(double sx, double sy)
//平移变换
public static AffineTransform getTranslateInstance(double tx, double ty)
//斜切变换,shx和shy指定斜拉度
public static AffineTransform getShearInstance(double shx, double shy)
// 也可以先创建一个没有transform属性的AffineTransform 对象,然后用以下方法指定图形平移 旋转及缩放变换等属性
//将图形在x轴方向平移 tx 像素
public void translate(double tx, double ty)
//图形在x轴方向缩放sx倍,纵向缩放 sy倍
public void scale(double sx, double sy)
//图形以点(x,y) 为轴点,旋转 arc 弧度。
public void rotate(double theta, double anchorx, double anchory)
clip 属性

clip属性用于实现剪裁效果。可以调用setClip方法,确定剪裁区的 Shape,从而设置剪裁属性。可以使用连续多个 setClip() 得到他们交集的剪裁区。

composit 属性

compostit属性设置图形重叠区域的效果。先使用 方法 AlphaComposite.getInstance(int rule,float alpha) 得到 AlphaComposite 对象,再通过 setComposite() 方法设置混合效果。

alpha值的范围为 0.0f(完全透明) 至 0.1f(完全不透明)

Graphics2D 类的绘图方法

仍然保留了Graphics类的绘图方法,同时新增了许多新方法。新方法将几何图形(线段,圆等)作为一个对象来绘制

在 java.awt.geom 包中声明的一系列类,分别用于创建各种几何图形对象。

使用 Graphics2D类的新方法画一个图形的步骤通常是,先在重画方法 paintComponent() 或 paint() 中,把参数对象 g 强制转换成 Graphics2D对象,然后,用上述各图形类提供的静态方法 Double() 创建该图形的对象,最后,以图形对象为参数调用 Graphics2D对象的 draw() 方法绘制这个图形

Graphics2D 的几何图形类

Line2D,Rectangle2D,RoundRectangle2D,Ellipse2D,Arc2D,QuadCurve2D,CubicCurve2D

Line2D线段类,RoundRectangle2D 圆角矩形类,Ellipse2D 椭圆类,Arc2D圆弧类,QuadCurve2D 二次曲线类和CubicCurve2D三次曲线类。

7 简答题

Java 中提供了几种布局管理器?简述他们之间的区别

BorderLayout 布局管理器是如何安排组件的?

如果想以上中下的位置安排3个按钮,可以使用哪些布局管理器?

Frame 和 Panel 默认的布局管理器分别是什么类型?

什么是事件?事件是怎样产生的?

在API文档中查找Event类,解释其中 target,when,id,x,y 和 arg 分别表示什么内容

委托事件处理模型是怎样对事件进行处理的?事件侦听程序的作用是什么?

java.awt.event 中定义了哪些事件类?各类对应的接口是什么?各接口中都声明了哪些方法?

以上是关于图形界面设计的主要内容,如果未能解决你的问题,请参考以下文章

redhat6.5安装了图形界面,输入密码后进不去图形界面了

centos 7 可以安装图形界面吗

linux关闭x11图形化界面

Linux操作-关闭图形界面

linux如何启动图形界面

java编程采用图形界面实现两个内容的交换,图形界面如下图