跳转到内容

用户界面

100% developed
来自维基教科书,开放的书籍,面向开放的世界

导航 用户界面 主题:v  d  e )


小程序和普通命令行执行程序的主要区别在于小程序允许扩展图形用户界面 (GUI)。

由于小程序提供了创建复杂 GUI 的能力,因此开发人员了解如何创建此类程序非常重要。

应用样式和添加内容

[编辑 | 编辑源代码]

在 Java 小程序中,图形部分在两个不同的区域初始化和添加。虽然对象在主类中初始化,但它们在 init() 方法中添加到小程序的布局中。这是使用 add(<object>) 语法完成的。一个典型的 init() 方法看起来像这样

Example 代码节 9.8:一个典型的 init() 方法
...

public void init() {
    setFont(new Font("Times New Roman", Font.PLAIN, 24));
    setForeground(Color.white);
    setBackground(Color.black);
    setLayout(new GridLayout);
   
    ...
   
    add(label);
    add(button);
}

下面将介绍此方法的不同方面。

许多小程序使用按钮。小程序与用户之间只有几种联系方式,而使用按钮是其中一种方式。创建按钮的方式与大多数其他 Java 小程序对象相同

Example 代码节 9.9:创建按钮
Button submitButton = new Button("Submit");

在初始化按钮时,有必要在给定参数中定义将在该按钮上显示的文本。在本例中,按钮使用显示在上面的“提交”一词进行初始化。将按钮添加到实际布局是在 init() 方法中完成的,如上所述。

Example 代码节 9.10:显示按钮
public void init() {
   
    ...
   
    add(submitButton);
}

让按钮执行任务或利用用户的输入要复杂一些。这些功能需要一个 ActionListener,将在 ActionListener 部分进行讨论。


标签是小程序中的区域,包含用户无法编辑的文本。这通常非常适合描述(例如,“插入名称:”)。标签的初始化和添加到小程序布局的方式与按钮相同。此外,与按钮一样,标签中的文本必须在初始化时识别。但是,如果标签将接收其文本作为随后函数的结果,并且应从空白开始,则不应该在引号之间放置文本。

Example 代码节 9.11:显示标签
Label nameLabel = new Label("Name: ");

...

public void init() {
    add(nameLabel);
}


文本字段

[编辑 | 编辑源代码]

文本字段是applet中允许用户插入文本的区域。文本字段的两个参数是可选的,它们可以设置字段中的预定义文本或设置文本字段中允许的列数。以下是一些示例

Example 代码部分 9.12:文本字段创建
    TextField t1 = new TextField();                // Blank
    TextField t2 = new TextField(5);               // Blank in 5 columns
    TextField t3 = new TextField("Input here");    // Predefined text
    TextField t4 = new TextField("Input here", 5); // Predefined text in 5 columns

    ...

    public void init() {
        add(t1);
        add(t2);
        add(t3);
        add(t4);
        ...
    }


在您的 Java applet 中使用时尚的字体可能很有必要,以帮助保持您的 Java applet 的吸引力。setFont() 允许定义整个 applet 中使用的字体,或者一次设置一个元素的字体。

设置字体的语法为 setFont(<fontName>, <fontStyle>, <fontSize>)

要使 applet 中的所有字体为普通字体的 24 号 Times New Roman,应使用以下代码

Example 代码部分 9.13:字体设置
Font f = new Font("Times New Roman", Font.PLAIN, 24);
setFont(f);

无需在两行代码中初始化字体并设置字体。

Example 代码部分 9.14:直接字体设置
setFont(new Font("Times New Roman", Font.PLAIN, 24));

但是,要使元素 a 的字体为普通字体的 24 号 Times New Roman,而元素 b 的字体为斜体的 28 号 Times New Roman,应使用以下代码

Example 代码部分 9.15:对象字体设置
a.setFont(new Font("Times New Roman", Font.PLAIN, 24));
b.setFont(new Font("Times New Roman", Font.ITALIC, 28));

要设置 applet 中使用的字体的颜色,可以使用 setForeground(<color>) 方法。此方法已经包含了一些预定义的颜色,可以通过调用例如 setForeground(Color.white) 来使用。以下是所有预定义的颜色

  • Color.black
  • Color.blue
  • Color.cyan
  • Color.darkGray
  • Color.gray
  • Color.green
  • Color.red
  • Color.white
  • Color.yellow

要创建自定义颜色,可以将颜色的 RGB 值作为颜色参数传入。例如,如果红色不是预定义的颜色,则可以使用 setForeground(new Color(255, 0, 0)) 来定义红色。

与字体样式一样,字体颜色也可以应用于单独的元素。语法遵循相同的模式:a.setForeground(Color.white)

布局使 applet 可见。如果没有布局,将不会显示任何内容。有五种不同的布局类型可供选择 - 一些非常简单,而另一些则很复杂。

流式布局

[编辑 | 编辑源代码]

此布局将组件从左到右放置,使用所需的空间。流式布局是 applet 的默认布局,因此无需设置。但是,为了清楚起见,可以将 applet 布局指定为流式布局,方法是在 init() 方法的顶部放置此行代码

Example 代码部分 9.16:流式布局
setLayout(new FlowLayout());

添加到布局中的后续组件将按添加顺序放置在屏幕上。

Example 代码部分 9.17:组件显示
public void init() {
    setLayout(new FlowLayout());
    add(nameLabel);
    add(t1);
    add(submitButton);
}

假设这些变量与上面的定义相同,这些代码行将创建一个由标签、文本字段和按钮组成的 applet 布局。如果窗口允许,它们将全部显示在一行上。通过更改窗口的宽度,流式布局将相应地收缩和扩展组件。


网格布局

[编辑 | 编辑源代码]

此布局以表格(网格)的形式排列组件。构造函数中指定了网格中的行数和列数。如果存在,另外两个参数指定了组件之间的垂直和水平填充。

Computer code 代码清单 9.4:GridLayoutApplet.java
import java.applet.Applet;
import java.awt.Button;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.TextField;

public class GridLayoutApplet extends Applet {

    Button submitButton = new Button("Submit");
    TextField t1 = new TextField();                // Blank
    TextField t2 = new TextField(5);               // Blank in 5 columns
    TextField t3 = new TextField("Input here");    // Predefined text
    TextField t4 = new TextField("Input here", 5); // Predefined text in 5 columns
    Label nameLabel = new Label("Name: ");

    /**
     * Init.
     */
    public void init() {
        // 3 rows, 4 columns, 2 pixel spacing
        setLayout(new GridLayout(3, 4, 2, 2));
        add(nameLabel);
        add(t1);
        add(t2);
        add(t3);
        add(t4);
        add(submitButton);
    }
}


这些项目已按以下顺序显示

 1st   2nd 
 3th   4th 
 5th   6th 

我们看到布局已配置为从左到右填充网格,然后从上到下填充,并且最后两列被忽略(它们甚至不存在)。它们被忽略是因为没有足够的项目来填充它们,并且行数优先于列数。这意味着,当您指定一个非零行数时,列数将被简单地忽略。您应该指定零行,以便考虑列数。

网格布局创建大小相同的单元格。因此,它不仅可以用于以网格形式显示项目,还可以用于显示两个宽度或高度相同的项目。

边框布局

[编辑 | 编辑源代码]

此布局将一个大型组件放置在中心,并在边缘放置最多四个组件。当使用此布局向容器添加内容时,您需要将位置指定为第二个参数,例如,中心位置使用 BorderLayout.CENTER,边缘位置使用一个世界方向(BorderLayout.NORTH 指向顶部边缘)。

Example 代码部分 9.19:边框布局
import java.awt.*;

Container container = getContentPane();
container.setLayout(new BorderLayout());

JButton b2 = new JButton("two");
// Add the button to the right edge.
container.add(b2, BorderLayout.EAST);
...


如果您有两个组件,将第一个组件放在北部,第二个组件放在中心,与将第一个组件放在中心,第二个组件放在南部是不一样的。在第一种情况下,布局将计算组件的大小,第二个组件将占用所有剩余的空间。在第二种情况下,情况相反。

卡片布局

[编辑 | 编辑源代码]
一堆卡片

卡片布局一次仅显示一个项目,并且仅在交互性时才有趣。其他项目存储在堆栈中,显示的项目是堆栈中的一个项目。卡片布局的名称是指一副玩牌,您可以在其中看到堆栈顶部的牌,也可以将一张牌放在顶部。卡片布局的不同之处在于堆栈中的项目保持其顺序。当您使用此布局时,您必须使用此方法将项目添加到容器中,即 applet

void add(String itemId, Component item) 将项目添加到容器中,并将项目与 ID 关联。

卡片布局有多种方法可以更改当前显示的项目

void first(Container container) 显示堆栈中的第一个项目。
void next(Container container) 显示位于显示项目之后堆栈中的项目。
void previous(Container container) 显示位于显示项目之前堆栈中的项目。
void last(Container container) 显示堆栈中的最后一个项目。
void show(Container container, String itemId) 按 ID 显示项目。
Computer code 代码清单 9.5:CardLayoutApplet.java
import java.applet.Applet;
import java.awt.CardLayout;
import java.awt.Label;

public class CardLayoutApplet extends Applet {

    static final String COMPONENT_POSITION_TOP = "TOP";
    static final String COMPONENT_POSITION_MIDDLE = "MIDDLE";
    static final String COMPONENT_POSITION_BOTTOM = "BOTTOM";

    Label topLabel = new Label("At the top");
    Label middleLabel = new Label("In the middle");
    Label bottomLabel = new Label("At the bottom");

    /**
     * Init.
     */
    public void init() {
        setLayout(new CardLayout());
        add(COMPONENT_POSITION_TOP, topLabel);
        add(COMPONENT_POSITION_MIDDLE, middleLabel);
        add(COMPONENT_POSITION_BOTTOM, bottomLabel);
        ((CardLayout)getLayout()).show(this, COMPONENT_POSITION_MIDDLE);
    }
}


布局的主要优点是您可以将它们相互组合,并且可以使用面板做到这一点。面板是一个包含其他组件的组件。然后可以将面板添加到顶层组件(框架或 applet)或另一个面板中,并根据此父组件的布局和约束将其本身放置。它有自己的布局,通常用于放置一组相关的组件,例如按钮

图 9.16:Java applet 示例。
测试您的知识

问题 9.5:我们想要创建一个基本的 FTP(文件传输协议)软件,其外观如下

应用程序名称
工具
工具
工具
工具
工具
工具
工具
工具
工具
本地文件夹




远程文件夹




状态栏

在顶部,它应该显示软件的名称。在名称下方,它应该显示从左到右显示的工具按钮,如果按钮到达右边界,则按钮的顺序将被换行。在按钮下方,它应该显示两个文件列表。这两个列表的宽度应相同,并且应使用应用程序的全部宽度。在这两个列表下方,它应该显示一个状态栏。

在 applet 上创建此显示。

答案

首先,我们必须分析显示。我们有四个独立的组件区域

  • 名称区域
  • 工具区域
  • 文件夹区域
  • 状态区域

因此,我们必须首先将这些区域分开,然后我们将这些区域拆分为组件。

Computer code 答案 9.5:Answer5.java
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;

public class Answer5 extends Applet {

    Label applicationNameLabel = new Label("Wikibooks FTP");
    Button tool1Button = new Button("Tool");
    Button tool2Button = new Button("Tool");
    Button tool3Button = new Button("Tool");
    Button tool4Button = new Button("Tool");
    Button tool5Button = new Button("Tool");
    Button tool6Button = new Button("Tool");
    Button tool7Button = new Button("Tool");
    Button tool8Button = new Button("Tool");
    Button tool9Button = new Button("Tool");
    Label localFolderLabel = new Label("5 files");
    Label remoteFolderLabel = new Label("3 files");
    Label statusBarLabel = new Label("Available");

    /**
     * Init.
     */
    public void init() {
        setLayout(new BorderLayout());

        // The application name
        add(applicationNameLabel, BorderLayout.NORTH);

        // The center
        Panel centerPanel = new Panel();
        centerPanel.setLayout(new BorderLayout());

        // The buttons
        Panel buttonPanel = new Panel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
        buttonPanel.add(tool1Button);
        buttonPanel.add(tool2Button);
        buttonPanel.add(tool3Button);
        buttonPanel.add(tool4Button);
        buttonPanel.add(tool5Button);
        buttonPanel.add(tool6Button);
        buttonPanel.add(tool7Button);
        buttonPanel.add(tool8Button);
        buttonPanel.add(tool9Button);
        centerPanel.add(buttonPanel, BorderLayout.CENTER);

        // The local and remote folders
        Panel folderPanel = new Panel();
        folderPanel.setLayout(new GridLayout(0, 2, 2, 2));
        folderPanel.add(localFolderLabel);
        folderPanel.add(remoteFolderLabel);
        centerPanel.add(folderPanel, BorderLayout.SOUTH);

        add(centerPanel, BorderLayout.CENTER);

        // The status bar
        add(statusBarLabel, BorderLayout.SOUTH);
    }
}
  1. 所有组件都放在边框布局中,以便我们有三个垂直的元素区域。
  2. 北部的区域是标题区域。
  3. 中心区域包含按钮和文件夹,稍后将被拆分。
  4. 南部的区域是状态栏区域。
  5. 中心区域现在使用边框布局拆分为中心按钮区域和南部的文件夹区域。
  6. 按钮区域然后使用流式布局拆分。
  7. 文件夹区域现在使用网格布局拆分。


我们使用网格布局来显示文件夹,以便两个组件之间具有相同的宽度。 我们不能使用网格布局来分隔名称、按钮、文件夹和状态栏,因为这些区域的高度不一致。 按钮必须位于边框布局的中心,因为按钮行数的计算会不准确,导致最后一行的按钮不会显示。

华夏公益教科书