Java 中文官方教程 2022 版(十九)(2)https://developer.aliyun.com/article/1486743
这是初始化树的代码:
rootNode = new DefaultMutableTreeNode("Root Node"); treeModel = new DefaultTreeModel(rootNode); treeModel.addTreeModelListener(new MyTreeModelListener()); tree = new JTree(treeModel); tree.setEditable(true); tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION); tree.setShowsRootHandles(true);
通过显式创建树的模型,代码确保树的模型是DefaultTreeModel
的一个实例。这样,我们知道树模型支持的所有方法。例如,我们知道可以调用模型的insertNodeInto
方法,即使该方法不是TreeModel
接口所必需的。
要使树节点中的文本可编辑,我们在树上调用setEditable(true)
。当用户完成编辑节点时,模型会生成一个树模型事件,告诉任何监听器,包括JTree
,树节点已更改。请注意,虽然DefaultMutableTreeNode
有用于更改节点内容的方法,但更改应通过DefaultTreeModel
的封装方法进行。否则,将不会生成树模型事件,监听器如树也不会知道更新。
要通知节点更改,我们可以实现一个TreeModelListener
。以下是一个检测用户何时为树节点键入新名称的树模型监听器示例:
class MyTreeModelListener implements TreeModelListener { public void treeNodesChanged(TreeModelEvent e) { DefaultMutableTreeNode node; node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent()); /* * If the event lists children, then the changed * node is the child of the node we have already * gotten. Otherwise, the changed node and the * specified node are the same. */ try { int index = e.getChildIndices()[0]; node = (DefaultMutableTreeNode) (node.getChildAt(index)); } catch (NullPointerException exc) {} System.out.println("The user has finished editing the node."); System.out.println("New value: " + node.getUserObject()); } public void treeNodesInserted(TreeModelEvent e) { } public void treeNodesRemoved(TreeModelEvent e) { } public void treeStructureChanged(TreeModelEvent e) { } }
这是Add按钮的事件处理程序使用的代码,用于向树中添加新节点:
treePanel.addObject("New Node " + newNodeSuffix++); ... public DefaultMutableTreeNode addObject(Object child) { DefaultMutableTreeNode parentNode = null; TreePath parentPath = tree.getSelectionPath(); if (parentPath == null) { //There is no selection. Default to the root node. parentNode = rootNode; } else { parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent()); } return addObject(parentNode, child, true); } ... public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible) { DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child); ... treeModel.insertNodeInto(childNode, parent, parent.getChildCount()); //Make sure the user can see the lovely new node. if (shouldBeVisible) { tree.scrollPathToVisible(new TreePath(childNode.getPath())); } return childNode; }
该代码创建一个节点,将其插入到树模型中,然后(如果适用)请求展开其上方的节点,并滚动树,以便新节点可见。要将节点插入模型中,代码使用DefaultTreeModel
类提供的insertNodeInto
方法。
创建数据模型
如果DefaultTreeModel
不符合您的需求,则需要编写自定义数据模型。您的数据模型必须实现TreeModel
接口。TreeModel
指定了获取树的特定节点、获取特定节点的子节点数量、确定节点是否为叶子节点、通知模型树变化以及添加和移除树模型侦听器的方法。
有趣的是,TreeModel
接口接受任何类型的对象作为树节点。它不要求节点由DefaultMutableTreeNode
对象表示,甚至不要求节点实现TreeNode
接口。因此,如果TreeNode
接口不适合您的树模型,可以自行设计树节点的表示。例如,如果您有一个现有的分层数据结构,您不需要复制它或强制将其转换为TreeNode
模式。您只需实现您的树模型,使其使用现有数据结构中的信息即可。
以下图显示了一个名为 GenealogyExample 的应用程序,显示了特定人的后代或祖先。(感谢教程读者 Olivier Berlanger 提供此示例。)
试一试:
- 点击“启动”按钮以使用Java™ Web Start运行 Genealogy 示例(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
您可以在GenealogyModel.java
中找到自定义树模型实现。因为该模型是作为Object
子类而不是DefaultTreeModel
子类实现的,所以必须直接实现TreeModel
接口。这需要实现获取节点信息的方法,例如根节点是哪个以及特定节点的子节点是什么。在GenealogyModel
的情况下,每个节点由Person
类型的对象表示,这是一个不实现TreeNode
的自定义类。
树模型还必须实现用于添加和移除树模型监听器的方法,并且在树的结构或数据发生变化时向这些监听器发出TreeModelEvent
。例如,当用户指示GenealogyExample
从显示祖先切换到显示后代时,树模型进行更改,然后向其监听器(如树组件)发出事件以通知它们。
如何懒加载子节点
懒加载是应用程序的一个特征,当类的实际加载和实例化延迟到实际使用实例之前的时刻。
通过懒加载它们我们能获得什么?是的,这绝对会增加应用程序的性能。通过懒加载,你可以将内存资源专门用于在实际使用时加载和实例化对象。你还可以加快应用程序的初始加载时间。
你可以利用TreeWillExpandListener
接口懒加载树的子节点之一的方法是。例如,你可以在应用程序中声明并加载树的根、祖父和父节点,如下面的代码所示:
让我们将根、祖父和父节点声明如下:
class DemoArea extends JScrollPane implements TreeWillExpandListener { ....... ....... private TreeNode createNodes() { DefaultMutableTreeNode root; DefaultMutableTreeNode grandparent; DefaultMutableTreeNode parent; root = new DefaultMutableTreeNode("San Francisco"); grandparent = new DefaultMutableTreeNode("Potrero Hill"); root.add(grandparent); parent = new DefaultMutableTreeNode("Restaurants"); grandparent.add(parent); dummyParent = parent; return root; }
你可以像下面的代码所示将上述声明的节点加载到树中:
TreeNode rootNode = createNodes(); tree = new JTree(rootNode); tree.addTreeExpansionListener(this); tree.addTreeWillExpandListener(this); ....... ....... setViewportView(tree);
现在,每当应用程序中可见父节点Restaurants
时,你可以懒加载子节点到应用程序中。为此,让我们在一个单独的方法中声明两个子节点,并按照下面的代码调用该方法:
private void LoadLazyChildren(){ DefaultMutableTreeNode child; child = new DefaultMutableTreeNode("Thai Barbeque"); dummyParent.add(child); child = new DefaultMutableTreeNode("Goat Hill Pizza"); dummyParent.add(child); textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily"); } ....... ....... public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException { saySomething("You are about to expand node ", e); int n = JOptionPane.showOptionDialog( this, willExpandText, willExpandTitle, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, willExpandOptions, willExpandOptions[1]); LoadLazyChildren(); }
请参阅如何编写 Tree-Will-Expand 监听器以获取 Tree-Will-Expand 监听器的描述。
树 API
树 API 非常广泛。以下表格列出了 API 的一部分,重点关注以下类别:
- 与树相关的类和接口
- 创建和设置树
- 实现选择
- 显示和隐藏节点
有关树 API 的更多信息,请参阅JTree
的 API 文档,以及tree package中各个类和接口的文档。还请参阅 JComponent 类以获取有关JTree
继承自其超类的 API 的信息。
与树相关的类和接口
DefaultMutableTreeNode | 默认树模型期望其树节点实现的接口,以及默认树模型使用的实现。
TreeModel DefaultTreeModel | 分别是树模型必须实现的接口和通常使用的实现。 |
TreeCellRenderer DefaultTreeCellRenderer | 分别是树单元渲染器必须实现的接口和通常使用的实现。 |
TreeCellEditor DefaultTreeCellEditor | 分别是树单元编辑器必须实现的接口和通常使用的实现。 |
TreeSelectionModel DefaultTreeSelectionModel | 分别是树选择模型必须实现的接口和通常使用的实现。 |
TreeSelectionListener TreeSelectionEvent | 用于检测树选择更改的接口和事件类型。有关更多信息,请参见入门指南。 |
TreeModelListener TreeModelEvent | 用于检测树模型更改的接口和事件类型。有关更多信息,请参见如何编写树模型监听器。 |
| TreeExpansionListener TreeWillExpandListener
TreeExpansionEvent | 用于检测树展开和折叠的接口和事件类型。有关更多信息,请参见如何编写树展开监听器和如何编写树将展开监听器。
ExpandVetoException | TreeWillExpandListener 可以抛出的异常,指示即将发生的展开/折叠不应发生。有关更多信息,请参阅如何编写 Tree-Will-Expand 监听器。 |
创建和设置树
构造函数或方法 | 目的 |
| JTree(TreeNode) JTree(TreeNode, boolean)
JTree(Vector) | 创建一棵树。TreeNode
参数指定根节点,由默认树模型管理。TreeModel
参数指定提供数据给表格的模型。此构造函数的无参数版本用于构建器中;它创建包含一些示例数据的树。如果您将Hashtable
、对象数组或Vector
作为参数指定,则参数将被视为根节点下的节点列表(不显示),并相应地构建模型和树节点。boolean
参数(如果存在)指定树应如何确定节点是否应显示为叶节点。如果参数为 false(默认值),任何没有子节点的节点都会显示为叶节点。如果参数为 true,则只有当其getAllowsChildren
方法返回 false 时,节点才是叶节点。 |
void setCellRenderer(TreeCellRenderer) | 设置绘制每个节点的渲染器。 |
void setEditable(boolean) void setCellEditor(TreeCellEditor) | 第一个方法设置用户是否可以编辑树节点。默认情况下,树节点不可编辑。第二个方法设置使用哪个自定义编辑器。 |
void setRootVisible(boolean) | 设置树是否显示根节点。如果树是使用一个接受数据结构的构造函数创建的,则默认值为 false,否则为 true。 |
void setShowsRootHandles(boolean) | 设置树是否显示其最左侧节点的句柄,让您可以展开和折叠节点。默认值为 false。如果树不显示根节点,则应调用setShowsRootHandles(true) 。 |
void setDragEnabled(boolean) boolean getDragEnabled() | 设置或获取dragEnabled 属性,该属性必须为 true 才能在此组件上启用拖放处理。默认值为 false。有关更多详细信息,请参阅拖放和数据传输。 |
实现选择
方法 | 目的 |
void addTreeSelectionListener(TreeSelectionListener) | 注册一个监听器以检测节点何时被选中或取消选中。 |
void setSelectionModel(TreeSelectionModel) TreeSelectionModel getSelectionModel() | 设置或获取用于控制节点选择的模型。您可以使用setSelectionModel(null) 完全关闭节点选择。 |
| void setSelectionMode(int) int getSelectionMode() | 设置或获取当前选定节点的路径。
(在TreeSelectionModel
中) | 设置或获取选择模式。该值可以是CONTIGUOUS_TREE_SELECTION
、DISCONTIGUOUS_TREE_SELECTION
或SINGLE_TREE_SELECTION
(均在TreeSelectionModel
中定义)。
获取最后选定的组件对象 | 获取代表当前选定节点的对象。这相当于在tree.getSelectionPath() 返回的值上调用getLastPathComponent 。 |
void setSelectionPath(TreePath) TreePath getSelectionPath() | 设置或获取当前选定节点的路径。 |
void setSelectionPaths(TreePath[]) TreePath[] getSelectionPaths() | 设置或获取当前选定节点的路径。 |
void setSelectionPath(TreePath) TreePath getSelectionPath() | 设置或获取当前选定节点的路径。 |
显示和隐藏节点
方法 | 目的 |
void addTreeExpansionListener(TreeExpansionListener) void addTreeWillExpandListener(TreeWillExpandListener) | 注册监听器以检测树节点何时已展开或折叠,或将要展开或折叠。要否决即将发生的展开或折叠,TreeWillExpandListener 可以抛出ExpandVetoException 。 |
void expandPath(TreePath) void collapsePath(TreePath) | 展开或折叠指定的树路径。 |
void scrollPathToVisible(TreePath) | 确保指定路径的节点可见 - 该路径前面的节点已展开,并且节点在滚动窗格的可视区域内。 |
void makeVisible(TreePath) | 确保指定路径的节点可见 - 该路径前面的节点已展开。该节点可能不会在可视区域内。 |
void setScrollsOnExpand(boolean) boolean getScrollsOnExpand() | 设置或获取树是否尝试滚动以显示先前隐藏的节点。默认值为true 。 |
void setToggleClickCount(int) int getToggleClickCount() | 设置或获取节点展开或关闭前的鼠标点击次数。默认值为两次。 |
TreePath getNextMatch(String, int, Position.Bias) | 返回下一个以特定前缀开头的树元素的TreePath 。 |
使用树的示例
此表列出了使用JTree
的示例以及这些示例的描述位置。
示例 | 描述位置 | 备注 |
树演示 | 创建树, 响应节点选择, 自定义树的显示 | 创建一个响应用户选择的树。还包含用于自定义 Java 外观和感觉线条样式的代码。 |
树图标演示 | 自定义树的显示 | 为 TreeDemo 添加自定义叶子图标。 |
树图标演示 2 | 自定义树的显示 | 自定义某些叶子节点图标,并为某些树节点提供工具提示。 |
动态树演示 | 动态更改树结构 | 演示如何向树中添加和移除节点。还允许编辑节点文本。 |
家谱示例 | 创建数据模型 | 实现自定义树模型和自定义节点类型。 |
树展开事件演示 | 如何编写树展开监听器 | 展示如何检测节点的展开和折叠。 |
树展开事件演示 2 | 如何编写树将展开监听器 | 展示如何否决节点的展开。 |
如果您在 JavaFX 中编程,请参阅树视图。
如何在 Swing 组件中使用 HTML
原文:
docs.oracle.com/javase/tutorial/uiswing/components/html.html
许多 Swing 组件在其 GUI 的一部分中显示文本字符串。默认情况下,组件的文本以单一字体和颜色显示,全部显示在一行上。您可以通过调用组件的setFont
和setForeground
方法来确定组件文本的字体和颜色。例如,以下代码创建一个标签,然后设置其字体和颜色:
label = new JLabel("A label"); label.setFont(new Font("Serif", Font.PLAIN, 14)); label.setForeground(new Color(0xffffdd));
如果您想在文本中混合字体或颜色,或者想要格式化,如多行,您可以使用 HTML。HTML 格式可以在所有 Swing 按钮、菜单项、标签、工具提示以及使用标签呈现文本的组件(如树和表格)中使用。
要指定组件的文本具有 HTML 格式,只需在文本开头放置标记,然后在其余部分使用任何有效的 HTML。这是在按钮文本中使用 HTML 的示例:
button = new JButton("<html><b><u>T</u>wo</b><br>lines</html>");
这是生成的按钮。
一个示例:HtmlDemo
一个名为HtmlDemo
的应用程序允许您通过在标签上设置文本来玩转 HTML 格式。您可以在HtmlDemo.java
中找到此程序的完整代码。这是HtmlDemo
示例的图片。
试一试:
- 单击“启动”按钮以使用Java™ Web Start运行 HtmlDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
- 编辑左侧文本区域中的 HTML 格式,并单击“更改标签”按钮。右侧的标签显示结果。
- 从左侧的文本区域中删除标记。标签的文本将不再被解析为 HTML。
示例 2:ButtonHtmlDemo
让我们看另一个使用 HTML 的示例。ButtonHtmlDemo
为三个按钮添加字体、颜色和其他文本格式。您可以在ButtonHtmlDemo.java
中找到此程序的完整代码。这是ButtonHtmlDemo
示例的图片。
点击“启动”按钮以使用Java™ Web Start运行 ButtonHtmlDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
左右两个按钮具有多行文本和文本样式,并且是使用 HTML 实现的。另一方面,中间的按钮只使用了一行文本、字体和颜色,因此不需要 HTML。以下是指定这三个按钮的文本格式的代码:
b1 = new JButton("<html><center><b><u>D</u>isable</b><br>" + "<font color=#ffffdd>middle button</font>", leftButtonIcon); Font font = b1.getFont().deriveFont(Font.PLAIN); b1.setFont(font); ... b2 = new JButton("middle button", middleButtonIcon); b2.setFont(font); b2.setForeground(new Color(0xffffdd)); ... b3 = new JButton("<html><center><b><u>E</u>nable</b><br>" + "<font color=#ffffdd>middle button</font>", rightButtonIcon); b3.setFont(font);
请注意,我们必须使用标签来使使用 HTML 的按钮中的助记字符“D”和“E”被下划线标记。还要注意,当按钮被禁用时,其 HTML 文本不幸地保持为黑色,而不是变为灰色。(请参考bug #4783068查看是否情况会发生变化。)
本节讨论了如何在普通的非文本组件中使用 HTML。有关主要用于格式化文本的组件的信息,请参阅使用文本组件。
如果你在使用 JavaFX 进行编程,请查看HTML 编辑器。
如何使用模型
原文:
docs.oracle.com/javase/tutorial/uiswing/components/model.html
大多数 Swing 组件都有模型。例如,按钮(JButton
)有一个模型(ButtonModel
对象),用于存储按钮的状态——其键盘助记符是什么,是否启用,选中或按下等。一些组件有多个模型。例如,列表(JList
)使用ListModel
来保存列表的内容,并使用ListSelectionModel
来跟踪列表的当前选择。
通常你不需要了解组件使用的模型。例如,使用按钮的程序通常直接处理JButton
对象,而不处理ButtonModel
对象。
那么为什么模型存在呢?最大的原因是它们让你灵活地确定数据的存储和检索方式。例如,如果你正在设计一个在稀疏填充表中显示数据的电子表格应用程序,你可以创建一个针对这种用途进行优化的自定义表模型。
模型还有其他好处。它们意味着数据不会在程序的数据结构和 Swing 组件的数据结构之间复制。此外,模型会自动将更改传播给所有感兴趣的侦听器,使得 GUI 能够轻松与数据保持同步。例如,要向列表添加项目,可以调用列表模型的方法。当模型的数据发生变化时,模型会向JList
和任何其他已注册的侦听器发送事件,GUI 相应更新。
虽然 Swing 的模型架构有时被称为模型-视图-控制器(MVC)设计,但实际上并不是这样。 Swing 组件通常是这样实现的,即视图和控制器是不可分割的,由外观提供的单个 UI 对象实现。 Swing 模型架构更准确地描述为可分离的模型架构。如果你对了解更多关于 Swing 模型架构感兴趣,请参阅Swing 架构概述,这是Swing 连接中的一篇文章。
一个示例:Converter
本节介绍了一个名为 Converter 的示例,这是一个不断在公制和美制单位之间转换距离测量的应用程序。你可以运行 Converter(下载 JDK 7 或更高版本)。或者,要自己编译和运行示例,请参考示例索引。
如下图所示,Converter 具有两个滑块,每个滑块都与一个文本字段绑定。这些滑块和文本字段都显示相同的数据——一个距离——但使用两种不同的度量单位。
对于这个程序来说,重要的是确保只有一个模型控制数据的值。有各种方法可以实现这一点;我们通过将其推迟到顶部滑块的模型来实现。底部滑块的模型(一个名为FollowerRangeModel
的自定义类的实例)将所有数据查询转发到顶部滑块的模型(一个名为ConverterRangeModel
的自定义类的实例)。每个文本字段通过监听值变化的事件处理程序与其滑块保持同步,反之亦然。确保顶部滑块的模型最终决定显示什么距离。
当我们开始实现自定义滑块模型时,我们首先查看了如何使用滑块的 API 部分。它告诉我们所有滑块数据模型必须实现BoundedRangeModel
接口。BoundedRangeModel
API 文档告诉我们接口有一个名为DefaultBoundedRangeModel
的实现类。DefaultBoundedRangeModel
的 API 文档显示它是BoundedRangeModel
的通用实现。
我们没有直接使用DefaultBoundedRangeModel
,因为它将数据存储为整数,而Converter
使用浮点数据。因此,我们实现了ConverterRangeModel
作为Object
的子类。然后,我们实现了FollowerRangeModel
作为ConverterRangeModel
的子类。
更多信息
要了解各个组件的模型,请参阅各个组件的"How to"页面和 API 文档。以下是一些直接使用模型的示例:
- 除了最简单的表格示例之外,所有示例都实现了自定义表格数据模型。
- 颜色选择器演示在颜色选择器的选择模型上有更改监听器,以便在用户选择新颜色时通知。在 ColorChooserDemo2 中,
CrayonPanel
类直接使用颜色选择模型来设置当前颜色。 - DynamicTreeDemo 示例设置了树模型(为
DefaultTreeModel
的一个实例),直接与其交互,并监听其变化。 - ListDemo 设置列表数据模型(为
DefaultListModel
的一个实例)并直接与其交互。 - SharedModelDemo 定义了一个扩展
DefaultListModel
并实现TableModel
的SharedDataModel
类。一个JList
和一个JTable
共享SharedDataModel
的一个实例,提供模型数据的不同视图。 - 在事件监听器示例中,ListDataEventDemo 直接创建并使用
DefaultListModel
。 - 我们的微调器示例创建微调器模型。
- 正如你已经看到的,转换器示例定义了两个自定义滑块模型。
如何使用图标
原文:
docs.oracle.com/javase/tutorial/uiswing/components/icon.html
许多 Swing 组件,如标签、按钮和选项卡窗格,可以用图标进行装饰 — 一个固定大小的图片。图标是一个遵循Icon
接口的对象。Swing 提供了一个特别有用的Icon
接口实现:ImageIcon
,它可以从 GIF、JPEG 或 PNG 图像绘制图标。
这是一个带有三个标签的应用程序快照,其中两个标签装饰有图标:
该程序使用一个图像图标来包含和绘制黄色斑点。一个语句创建图像图标,另外两个语句将图像图标包含在两个标签中:
ImageIcon icon = createImageIcon("images/middle.gif", "a pretty but meaningless splat"); label1 = new JLabel("Image and Text", icon, JLabel.CENTER); ... label3 = new JLabel(icon);
createImageIcon
方法(在前面的片段中使用)是我们在许多代码示例中使用的方法。它查找指定的文件并为该文件返回一个ImageIcon
,如果找不到该文件则返回null
。以下是一个典型的实现:
/** Returns an ImageIcon, or null if the path was invalid. */ protected ImageIcon createImageIcon(String path, String description) { java.net.URL imgURL = getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL, description); } else { System.err.println("Couldn't find file: " + path); return null; } }
在前面的片段中,ImageIcon
构造函数的第一个参数是相对于当前类位置的,并将解析为绝对 URL。description
参数是一个字符串,允许辅助技术帮助视觉障碍用户理解图标传达的信息。
通常,应用程序提供自己的一组用作应用程序一部分的图像,就像我们许多演示中使用的图像一样。您应该使用Class
的getResource
方法获取图像的路径。这允许应用程序验证图像是否可用,并在图像不可用时提供合理的错误处理。当图像不是应用程序的一部分时,不应使用getResource
,而应直接使用ImageIcon
构造函数。例如:
ImageIcon icon = new ImageIcon("images/middle.gif", "a pretty but meaningless splat");
当您向ImageIcon
构造函数指定文件名或 URL 时,处理将被阻塞,直到图像数据完全加载或数据位置被证明无效为止。如果数据位置无效(但非空),则仍会成功创建ImageIcon
;只是它没有大小,因此不会绘制任何内容。如createImageIcon
方法所示,建议在将 URL 传递给ImageIcon
构造函数之前首先验证 URL 是否指向现有文件。这样可以在文件不存在时进行优雅的错误处理。如果您希望在图像加载时获得更多信息,可以通过调用其setImageObserver
方法在图像图标上注册观察者。
在底层,每个图像图标都使用一个Image
对象来保存图像数据。
本节的其余部分涵盖以下主题:
- 更复杂的图像图标示例
- 使用 getResource 加载图像
- 将图像加载到小程序中
- 提高加载图像图标时的感知性能
- 创建自定义图标实现
- 图像图标 API
- 使用图标的示例
更复杂的图像图标示例
这是一个使用六个图像图标的应用程序。其中五个显示缩略图图像,第六个显示全尺寸照片。
试试这个:
- 单击“启动”按钮以使用 Java™ Web Start 运行 IconDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
- 单击任何缩略图图像以查看全尺寸照片。
- 将鼠标悬停在照片上。将显示一个工具提示,显示照片标题。
IconDemoApp 展示了以下方式中使用的图标:
- 作为附加到按钮的 GUI 元素(按钮上的缩略图图像)。
- 用于显示图像(五张照片)。
照片通过 loadimages.execute
在单独的线程中加载。稍后在本节中显示 loadimages
代码。
ThumbnailAction
类是 IconDemoApp.java
中的一个内部类,是 AbstractAction
的子类,用于管理我们的全尺寸图标、缩略图版本及其描述。当调用 actionPerformed
方法时,全尺寸图像将加载到主显示区域中。每个按钮都有自己的 ThumbnailAction
实例,指定要显示的不同图像。
/** * Action class that shows the image specified in it's constructor. */ private class ThumbnailAction extends AbstractAction{ /** *The icon if the full image we want to display. */ private Icon displayPhoto; /** * @param Icon - The full size photo to show in the button. * @param Icon - The thumbnail to show in the button. * @param String - The description of the icon. */ public ThumbnailAction(Icon photo, Icon thumb, String desc){ displayPhoto = photo; // The short description becomes the tooltip of a button. putValue(SHORT_DESCRIPTION, desc); // The LARGE_ICON_KEY is actually the key for setting the // icon when an Action is applied to a button. putValue(LARGE_ICON_KEY, thumb); } /** * Shows the full image in the main area and sets the application title. */ public void actionPerformed(ActionEvent e) { photographLabel.setIcon(displayPhoto); setTitle("Icon Demo: " + getValue(SHORT_DESCRIPTION).toString()); } }
Java 中文官方教程 2022 版(十九)(4)https://developer.aliyun.com/article/1486748