// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= 在 Java GUI 应用程序中处理图像
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: 在 Java GUI 应用程序中处理图像 - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, 在 Java GUI 应用程序中处理图像


image::images/netbeans-stamp-80-74.png[title="此页上的内容适用于 NetBeans IDE 7.4 和 8.0"]


*要学完本教程，您需要具备以下软件和资源。*

|===
|软件或资源 |要求的版本 

|link:http://netbeans.org/downloads/[+NetBeans IDE+] |版本 7.4 或 8.0 

|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java 开发工具包 (JDK)+] |版本 6、7 或 8 
|===


== 简介

在应用程序中处理图像是很多 Java 编程初学者遇到的一个常见问题。要访问 Java 应用程序中的图像，标准作法是使用 `link:http://download.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)[+getResource()+]` 方法。本教程介绍了如何使用 IDE 的 GUI 构建器构建代码，以便在应用程序中包含图像（和其他资源）。此外，您还将了解如何定制 IDE 生成图像处理代码的方式。

本教程生成的应用程序是一个简单的 JFrame，其中包含一个显示单个图像的 JLabel。


== 创建应用程序

1. 选择 "File"（文件）> "New Project"（新建项目）。
2. 在新建项目向导中，选择 "Java" > "Java Application"（Java 应用程序），然后单击 "Next"（下一步）。
3. 键入 `ImageDisplayApp` 作为项目名称。
4. 清除 "Create Main Class"（创建主类）复选框。

[.feature]
--
image::images/newproj-small.png[role="left", link="images/newproj.png"]
--



. 单击 "Finish"（完成）。


== 创建应用程序窗体

在本节中，将创建 JFrame 窗体并在窗体中添加 JLabel。

*要创建 JFrame 窗体，请执行以下操作：*

1. 在 "Projects"（项目）窗口中，展开  ``ImageDisplayApp``  节点。
2. 右键单击 "Source Packages"（源包）节点，然后选择 "New"（新建）> "JFrame Form"（JFrame 窗体）。
3. 键入 `ImageDisplay` 作为类名。
4. 键入 `org.me.myimageapp` 作为包名。
5. 单击 "Finish"（完成）。

*要添加 JLabel，请执行以下操作：*

* 在组件面板中，选择 "Label"（标签）组件并将其拖至 JFrame 上。

此时，该窗体类似于下图：

[.feature]
--
image::images/form-small.png[role="left", link="images/form.png"]
--


== 为图像添加包

在应用程序中使用图像或其他资源时，通常应为资源创建单独的 Java 包。在本地文件系统上，包对应于一个文件夹。

*要为图像创建包，请执行以下操作：*

1. 在 "Projects"（项目）窗口中，右键单击 `org.me.myimageapp` 节点，然后选择 "New"（新建）> "Java Package"（Java 包）。

[.feature]
--
image::images/package-small.png[role="left", link="images/package.png"]
--



. 单击 "Finish"（完成）。

在 "Projects"（项目）窗口中，您应该会看到新包出现在 `Source Packages`（源包）文件夹内。

image::images/project-with-imagepack.png[]


== 在标签上显示图像

在此应用程序中，图像将嵌入到 JLabel 组件中。

*要将图像添加到标签上，请执行以下操作：*

1. 在 GUI 设计器中，选择已添加到窗体上的标签。
2. 在 "Properties"（属性）窗口中，单击 "Properties"（属性）类别，然后滚动到 icon 属性。
3. 单击省略号 (...) 按钮。
显示图标属性编辑器。

[.feature]
--
image::images/importimage-small.png[role="left", link="images/importimage.png"]
--



. 在 icon 属性对话框中，单击 "Import to Project"（导入到项目）。


. 在文件选择器中，导航到系统上要使用的任何图像。然后，单击 "Next"（下一步）。


. 在向导的 "Select target folder"（选择目标文件夹）页中，选择 `newpackage` 文件夹，然后单击 "Finish"（完成）。

[.feature]
--
image::images/targetfolder-small.png[role="left", link="images/targetfolder.png"]
--



. 单击 "OK"（确定）以关闭 "icon property"（图标属性）对话框。

单击 "OK"（确定）后，IDE 将执行以下任务：

* 将图像复制到项目中。因此，在构建和分发应用程序时，图像将包含在可分发的 JAR 文件中。
* 在 ImageDisplay 类中生成代码以访问图像。
* 在窗体的 "Design"（设计）视图中显示标签上的图像。

[.feature]
--
image::images/label-added-small.png[role="left", link="images/label-added.png"]
--

此时，可以执行一些简单操作以改进窗体外观，例如：

* 在 "Properties"（属性）窗口中，选择 `text` 属性，然后删除 `jLabel1`。该值是由 GUI 构建器构建的，以作为标签的显示文本。不过，将使用标签显示图像而不是文本，因此不需要使用该文本。
* 将 `jLabel1` 拖动到窗体中心。

[.feature]
--
image::images/centered-small.png[role="left", link="images/centered.png"]
--

*要查看生成的代码，请执行以下操作：*

1. 在 GUI 设计器中，单击 "Source"（源）按钮。（如果 "Source"（源）按钮处于隐藏状态，则从主菜单中选择 "View"（视图）> "Source Editor Toolbar"（源代码编辑器工具栏）。）
2. 向下滚动到显示 "Generated Code" 的行。
3. 单击 "Generated Code" 行左侧的加号 (+)，以显示 GUI 设计器生成的代码。

关键的一行如下所示：


[source,java]
----

jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/me/myimageapp/newpackage/image.png"))); // NOI18N
----

由于使用了 `jLabel1` 的 `icon` 属性的属性编辑器，因此，IDE 生成 `setIcon` 方法。该方法的参数包含针对 `ImageIcon` 匿名内部类的 `link:http://download.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)[+getResource()+]` 方法调用。请注意，为图像生成的路径与它在应用程序的包结构中的位置相对应。

*注：*

* 如果在 icon 属性编辑器中使用 " External Image"（外部图像）选项，IDE 将生成图像的绝对路径，而无需将图像复制到项目中。因此，在您的系统上运行应用程序时，将显示该图像；而在其他系统上运行应用程序时，可能不会显示该图像。
* 还可以使用 `getResource` 方法访问其他类型的资源，例如，包含应用程序可能需要使用的数据的文本文件。

*在 Jlabel 上注册鼠标事件的事件处理程序：*

在 "Design View"（设计视图）中，右键单击 "JLabel"，然后从弹出菜单中选择 "Events"（事件）> "Mouse"（鼠标）> "mouseClicked/mousePressed/mouseReleased"。
将为相应事件生成一个事件处理程序。

*注：*在事件处理程序中，可以使用 `event.getPoint()`、`event.getX()` 或 `event.getY()` 方法获得鼠标坐标（例如鼠标单击的位置）。有关详细信息，请参见 link:http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/event/MouseEvent.html[+MouseEvent 类+]。


== 将图像显示为框架上的背景

GUI 构建器不直接支持 JFrame 的背景图像，因为 Swing 不直接支持 JFrame 的背景图像。
不过，可以通过各种间接的方法实现这一目标。在该应用程序中，包含图像的 JLabel 将嵌入 JFrame 组件中，而透明的 JPanel 将放置在 JLabel 之上，用作所有组件的父项。

*将透明的 JPanel 添加到包含图像的 JFrame 中：*

1. 选择 "File"（文件）> "New Project"（新建项目）。
2. 在新建项目向导中，选择 "Java" > "Java Application"（Java 应用程序），然后单击 "Next"（下一步）。
3. 键入 `BackgroundImageApp` 作为项目名称。
4. 清除 "Create Main Class"（创建主类）复选框。

[.feature]
--
image::images/prj-small.png[role="left", link="images/prj.png"]
--



. 单击 "Finish"（完成）。


. 在 "Projects"（项目）窗口中，展开 `BackgroundImageApp` 节点。


. 右键单击 "Source Packages"（源包）节点，然后选择 "New"（新建）> "JFrame Form"（JFrame 窗体）。


. 键入 `ImageDisplay` 作为类名。


. 键入 `org.me.mybackgroundapp` 作为包名。

[.feature]
--
image::images/newjframe-small.png[role="left", link="images/newjframe.png"]
--



. 单击 "Finish"（完成）。


. 在 "Design"（设计）视图中，右键单击 "JFrame"，然后从弹出式菜单中选择 "Set Layout"（设置布局）> "Grid Bag Layout"（网格包布局）。


. 右键单击 "JFrame"，然后从弹出式菜单中选择 "Add From Palette"（从组件面板上添加）> "Swing Containers"（Swing 容器）> "Panel"（面板）。


. 在 "Properties"（属性）窗口中，取消选择 jPanel 的 `opaque` 属性。


. 右键单击 "JFrame"，然后从弹出式菜单中选择 "Add From Palette"（从组件面板上添加）> "Swing Controls"（Swing 控件）> "Label"（标签）。


. 在 "Projects"（项目）窗口中，右键单击 `org.me.mybackgroundapp` 节点，然后选择 "New"（新建）> "Java Package"（Java 包）。


. 单击 "Finish"（完成）。添加新包。


. 在 GUI 设计器中，选择已添加到窗体上的标签。


. 在 "Properties"（属性）窗口中，单击 "Properties"（属性）类别，然后滚动到 icon 属性。


. 单击省略号 (...) 按钮。


. 在 icon 属性对话框中，单击 "Import to Project"（导入到项目）。


. 在文件选择器中，导航到系统上要使用的任何图像。然后，单击 "Next"（下一步）。


. 在向导的 "Select Target Folder"（选择目标文件夹）页中，选择 `newpackage` 资源文件夹，然后单击 "Finish"（完成）。

[.feature]
--
image::images/targetfolder-small.png[role="left", link="images/targetfolder.png"]
--



. 单击 "OK"（确定）以关闭 "icon property"（图标属性）对话框。


. 在 "Navigator"（导航器）窗口中，右键单击 "jPanel"，然后从弹出式菜单中选择 "Properties"（属性）。


. 在 "Properties"（属性）对话框中，将 `Grid X`、`Grid Y`、`Weight X` 和 `Weight Y` 属性设置为 `1`，并将 `Fill` 属性设置为 `Both`。

[.feature]
--
image::images/panelprops-small.png[role="left", link="images/panelprops.png"]
--



. 单击 "Close"（关闭）。


. 针对 jLabel 重复步骤 24 和 25。


. 在 "Properties"（属性）对话框中，选择 `text` 属性，然后删除 `jLabel1`。

[.feature]
--
image::images/labelprops-small.png[role="left", link="images/labelprops.png"]
--

背景完成。现在，您可以执行拖动操作了，例如可将 jLabel 和 jTextField 拖至 "Palette"（组件面板）中的 jPanel。二者都将显示在背景图像之上。

image::images/background.png[]

*注：*上述解决方案的优点在于，无论是在设计时还是运行时，背景图像都会显示出来。


== 构建和运行应用程序

现在，已构建了用于访问和显示图像的代码，您可以构建和运行应用程序以确保能够访问该图像。

首先，您需要设置项目的主类。在设置主类后，IDE 便会知道在运行项目时运行哪个类。此外，这还会确保在构建应用程序时构建应用程序 JAR 文件中的 `Main-Class` 元素。

*要设置项目的主类，请执行以下操作：*

1. 右键单击 "ImageDisplayApp" 项目节点，然后选择 "Properties"（属性）。
2. 在 "Project Properties"（项目属性）对话框中，选择 "Run"（运行）类别。
3. 单击 "Main Class"（主类）字段旁边的 "Browse"（浏览）按钮。然后选择 `org.me.myimageapp.ImageDisplay` 类。

[.feature]
--
image::images/mainclass-small.png[role="left", link="images/mainclass.png"]
--



. 单击 "Select Main Class"（选择主类）按钮。


. 单击“确定”。关闭“项目属性”对话框。

*要构建项目，请执行以下操作：*

* 从主工具栏中选择 "Run"（运行）> "Clean &amp; Build Project (_project_name_)"（清理并构建项目 (project_name)）。

可以在 "Files"（文件）窗口中查看应用程序的构建产品。`build` 文件夹包含编译的类。`dist` 文件夹包含可运行的 JAR 文件，其中包含编译的类和图像。

image::images/files.png[]

*运行项目：*

* 从主工具栏中选择 "Run"（运行）> "Run Project (_project_name_)"（运行项目 (project_name)）。


== 创建定制代码

在很多应用程序中，无法像此示例一样以静态方式确定显示的图像。例如，用户可通过单击等操作来确定要显示的图像。

如果需要以编程方式选择要显示的图像，您可以编写自己的定制代码以访问和显示资源。IDE 禁止在 "Source"（源）视图的受保护块（包含 GUI 构建器构建的代码）中直接编写代码。不过，您可以通过属性编辑器（从 "Properties"（属性）窗口中访问）在受保护块中插入代码。通过以这种方式使用属性编辑器，可以确保在 GUI 构建器中进行设计更改时不会丢失定制代码。

*例如，要为 JLabel 的 `icon` 属性编写定制代码，请执行以下操作：*

1. 在 "Design View"（设计视图）或 "Navigator"（导航器）窗口中选择 JLabel。
2. 在 "Properties"（属性）窗口中，单击 `icon` 属性旁边的省略号 (...) 按钮。
3. 从对话框顶部的下拉列表中选择 "Custom Code"（定制代码）选项。

[.feature]
--
image:images/custom-code-small.png[role="left", link="images/custom-code.png"]
--

通过使用此属性编辑器中的 "Custom Code"（定制代码）选项，您可以自行填充 `setIcon` 方法的参数。可以使用所需的逻辑填充此参数，也可以调用在该类中的其他位置手动编写的不同方法以填充此参数。

[.feature]
--
image::images/custom-view-small.png[role="left", link="images/custom-view.png"]
--


== 小结

本教程说明了如何从使用 NetBeans IDE 创建的应用程序中访问图像。Java 教程进一步讨论了图像处理问题。

*注：*本教程中提供的示例与 Java 教程的link:http://java.sun.com/docs/books/tutorial/uiswing/components/icon.html[+如何使用图标+]部分中的第一个示例非常相似。一个不同之处是，执行本教程时生成的代码使用 `link:http://download.oracle.com/javase/6/docs/api/javax/swing/JLabel.html[+JLabel+]` 的 `link:http://download.oracle.com/javase/6/docs/api/javax/swing/JLabel.html#setIcon(javax.swing.Icon)[+setIcon+]` 方法将图标应用于标签。在 Java 教程示例中，应用于标签的图标是通过其构造函数传递的。

link:/about/contact_form.html?to=3&subject=Feedback:%20Handling%20Images%20in%20a%20GUI%20Application[+发送有关此教程的反馈意见+]



== 另请参见

* link:gui-functionality.html[+构建 GUI 应用程序简介+]
* link:quickstart-gui.html[+在 NetBeans IDE 中设计 Swing GUI+]
* link:../../trails/matisse.html[+Java GUI 应用程序学习资源+]
* link:../../trails/java-se.html[+常规 Java 开发学习资源+]
* link:http://wiki.netbeans.org/NetBeansUserFAQ#GUI_Editor_.28Matisse.29[+GUI 构建器 - 常见问题解答+]
* _使用 NetBeans IDE 开发应用程序_中的link:http://www.oracle.com/pls/topic/lookup?ctx=nb8000&id=NBDAG920[+实现 Java GUI+]
