Java 中文官方教程 2022 版(十九)(1)https://developer.aliyun.com/article/1486740
创建工具栏按钮
工具栏中的按钮是普通的JButton
实例,使用了来自 Java 外观和感觉图形存储库的图像。如果您的工具栏具有 Java 外观和感觉,请使用Java 外观和感觉图形存储库中的图像。
这是创建按钮并将其添加到工具栏的代码。
protected void addButtons(JToolBar toolBar) { JButton button = null; //first button button = makeNavigationButton("Back24", PREVIOUS, "Back to previous something-or-other", "Previous"); toolBar.add(button); //second button button = makeNavigationButton("Up24", UP, "Up to something-or-other", "Up"); toolBar.add(button); *...//similar code for creating and adding the third button...* } protected JButton makeNavigationButton(String imageName, String actionCommand, String toolTipText, String altText) { //Look for the image. String imgLocation = "images/" + imageName + ".gif"; URL imageURL = ToolBarDemo.class.getResource(imgLocation); //Create and initialize the button. JButton button = new JButton(); button.setActionCommand(actionCommand); button.setToolTipText(toolTipText); button.addActionListener(this); if (imageURL != null) { //image found button.setIcon(new ImageIcon(imageURL, altText)); } else { //no image found button.setText(altText); System.err.println("Resource not found: " + imgLocation); } return button; }
第一次调用makeNavigationButton
创建了第一个按钮的图像,使用了图形存储库中的 24x24“返回”导航图像。
除了找到按钮的图像之外,makeNavigationButton
方法还创建按钮,设置其动作命令和工具提示文本的字符串,并为按钮添加动作监听器。如果图像丢失,该方法会打印错误消息并向按钮添加文本,以便按钮仍然可用。
注意:
如果工具栏中的任何按钮重复了其他组件(如菜单项)的功能,您可能应该按照如何使用操作中描述的方式创建并添加工具栏按钮。
自定义工具栏
通过向上述示例添加几行代码,我们可以展示一些更多的工具栏功能:
- 使用
setFloatable(false)
使工具栏无法移动。 - 使用
setRollover(true)
在用户用光标悬停在工具栏按钮上时视觉指示。 - 向工具栏添加分隔符。
- 向工具栏添加非按钮组件。
您可以通过运行 ToolBarDemo2 来查看这些功能。单击“启动”按钮以使用Java™ Web Start运行 ToolBarDemo2(下载 JDK 7 或更高版本)。或者,要自行编译和运行,请参考示例索引。
您可以在ToolBarDemo2.java
中找到此程序的完整代码。下面您可以看到使用这些自定义功能的新 UI 的图片。
因为工具栏不再可以被拖动,所以它的左边缘不再有凸起。以下是关闭拖动的代码:
toolBar.setFloatable(false);
工具栏处于悬停模式,因此光标下的按钮有视觉指示。视觉指示的类型取决于外观和感觉。例如,Metal 外观和感觉使用渐变效果来指示光标下的按钮,而其他类型的外观和感觉使用边框来实现此目的。以下是设置悬停模式的代码:
toolBar.setRollover(true);
上面示例中的另一个明显区别是工具栏包含两个新组件,这些组件之前有一个称为分隔符的空格。这是添加分隔符的代码:
toolBar.addSeparator();
这是添加新组件的代码:
//fourth button button = new JButton("Another button"); ... toolBar.add(button); //fifth component is NOT a button! JTextField textField = new JTextField("A text field"); ... toolBar.add(textField);
通过调用setAlignmentY
方法,您可以轻松地使工具栏组件顶部对齐或底部对齐,而不是居中。例如,要使工具栏中所有组件的顶部对齐,请在每个组件上调用setAlignmentY(TOP_ALIGNMENT)
。类似地,您可以使用setAlignmentX
方法在工具栏垂直时指定组件的对齐方式。这种布局灵活性是可能的,因为工具栏使用BoxLayout
来定位它们的组件。有关更多信息,请参阅如何使用 BoxLayout。
工具栏 API
以下表格列出了常用的JToolBar
构造函数和方法。您可能调用的其他方法在 The JComponent Class 中的 API 表中列出。
方法或构造函数 | 目的 |
JToolBar(String, int) | 创建一个工具栏。可选的 int 参数允许您指定方向;默认为HORIZONTAL
。可选的String
参数允许您指定工具栏窗口的标题,如果它被拖到容器外部。|
Component add(Component) | 将组件添加到工具栏。您可以使用AbstractButton 定义的setAction(Action) 方法将按钮与Action 关联起来。 |
void addSeparator() | 在工具栏末尾添加一个分隔符。 |
void setFloatable(boolean) boolean isFloatable() | 浮动属性默认为 true,表示用户可以将工具栏拖出到单独的窗口中。要禁用工具栏拖动,请使用toolBar.setFloatable(false) 。某些外观和感觉类型可能会忽略此属性。 |
void setRollover(boolean) boolean isRollover() | 默认情况下,rollover 属性为 false。要使工具栏按钮在用户用光标悬停在其上时以视觉方式指示,将此属性设置为 true。某些外观可能会忽略此属性。 |
使用工具栏的示例
此表列出使用 JToolBar
的示例,并指向这些示例所描述的位置。
示例 | 描述位置 | 备注 |
ToolBarDemo |
本页 | 一个只有图标按钮的基本工具栏。 |
ToolBarDemo2 |
本页 | 演示了一个非浮动工具栏处于 rollover 模式,其中包含一个分隔符和一个非按钮组件。 |
ActionDemo |
如何使用 Actions | 使用 Action 对象实现工具栏。 |
如何使用工具提示
原文:
docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html
为任何JComponent
对象创建工具提示很容易。使用setToolTipText
方法为组件设置工具提示。例如,要向三个按钮添加工具提示,只需添加三行代码:
b1.setToolTipText("Click this button to disable the middle button."); b2.setToolTipText("This middle button does not react when you click it."); b3.setToolTipText("Click this button to enable the middle button.");
当程序的用户将光标暂停在程序的任何按钮上时,按钮的工具提示将出现。您可以通过运行ButtonDemo
示例来查看这一点,该示例在如何使用按钮、复选框和单选按钮中有解释。这是当光标暂停在ButtonDemo
示例中的左按钮上时出现的工具提示的图片。
对于诸如选项卡窗格之类具有多个部分的组件,通常可以根据光标下的组件部分变化工具提示文本以反映该部分。例如,选项卡窗格可以使用此功能来解释当单击光标下的选项卡时会发生什么。当您实现选项卡窗格时,可以在传递给addTab
或setToolTipTextAt
方法的参数中指定特定于选项卡的工具提示文本。
即使在没有用于设置特定部分工具提示文本的 API 的组件中,您通常也可以自行完成工作。如果组件支持渲染器,则可以在自定义渲染器上设置工具提示文本。表格和树部分提供了由自定义渲染器确定的工具提示文本示例。适用于所有JComponent
的另一种方法是创建组件的子类并覆盖其getToolTipText(MouseEvent)
方法。
工具提示 API
大多数用于设置工具提示所需的 API 属于JComponent
类,并且因此被大多数 Swing 组件继承。更多工具提示 API 可在诸如JTabbedPane
之类的单独类中找到。一般来说,这些 API 足以指定和显示工具提示;通常不需要直接处理实现类JToolTip
和ToolTipManager
。
以下表格列出了JComponent
类中的工具提示 API。有关各个组件对工具提示的支持信息,请参阅相关组件的操作指南部分。
JComponent
类中的工具提示 API
方法 | 目的 |
setToolTipText(String) | 如果指定的字符串不为 null,则此方法将注册组件具有工具提示,并在显示时为工具提示提供指定的文本。如果参数为 null,则此方法将关闭此组件的工具提示。 |
String getToolTipText() | 返回先前使用setToolTipText 指定的字符串。 |
String getToolTipText(MouseEvent) | 默认情况下,返回与getToolTipText() 返回的相同值。多部分组件如JTabbedPane 、JTable 和JTree 会重写此方法以返回与鼠标事件位置相关联的字符串。例如,选项卡窗格中的每个选项卡可以有不同的工具提示文本。 |
获取工具提示位置(MouseEvent) | 返回组件工具提示的左上角出现的位置(在接收组件的坐标系中)。参数是导致工具提示显示的事件。默认返回值为 null,告诉 Swing 系统选择一个位置。 |
使用工具提示的示例
此表列出了一些使用工具提示的示例,并指向这些示例的描述位置。
示例 | 描述位置 | 注意事项 |
ButtonDemo |
本节和如何使用按钮、复选框和单选按钮 | 使用工具提示为按钮提供说明。 |
IconDemo |
如何使用图标 | 在标签中使用工具提示提供图像的名称和大小信息。 |
TabbedPaneDemo |
如何使用选项卡窗格 | 使用在addTab 方法的参数中指定的选项卡特定工具提示文本。 |
TableRenderDemo |
为单元格指定工具提示 | 使用渲染器为表添加工具提示。 |
TableToolTipsDemo |
为单元格指定工具提示, 为列标题指定工具提示 | 使用各种技术为表添加工具提示。 |
TreeIconDemo2 |
自定义树的显示 | 使用自定义渲染器为树添加工具提示。 |
ActionDemo |
如何使用操作 | 为使用Action 创建的按钮添加工具提示。 |
如何使用树
原文:
docs.oracle.com/javase/tutorial/uiswing/components/tree.html
使用JTree
类,您可以显示分层数据。JTree
对象实际上不包含您的数据;它只是提供数据的视图。以下是一棵树的图片:
如前图所示,JTree
垂直显示其数据。树显示的每一行都包含一个数据项,称为节点。每棵树都有一个根节点,所有节点都是从根节点派生的。默认情况下,树显示根节点,但您可以另行规定。节点可以有子节点,也可以没有。我们将可以有子节点的节点 — 无论它们当前是否有子节点 — 称为分支节点。不能有子节点的节点称为叶节点。
分支节点可以有任意数量的子节点。通常,用户可以通过单击来展开和折叠分支节点 — 使其子节点可见或不可见。默认情况下,除了根节点外,所有分支节点都是折叠的。程序可以通过监听树展开或树将展开事件来检测分支节点展开状态的变化,如如何编写树展开监听器和如何编写树将展开监听器中所述。
树中的特定节点可以通过 TreePath 标识,TreePath 是一个封装节点及其所有祖先的对象,或者通过其显示行标识,其中显示区域中的每一行显示一个节点。
- 展开的节点是一个非叶节点,当其所有祖先都展开时,将显示其子节点。
- 折叠的节点是隐藏的节点。
- 隐藏的节点是位于折叠祖先下的节点。
本节的其余部分讨论以下主题:
- 创建一棵树
- 响应节点选择
- 自定义树的显示
- 动态更改树
- 创建数据模型
- 树 API
- 使用树的示例
创建一棵树
这是一个应用程序的图片,其顶部显示了一个在滚动窗格中的树。
试一试:
- 点击“启动”按钮以使用 Java™ Web Start 运行树演示(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
- 展开一个或多个节点。
通过点击项目左侧的圆圈来执行此操作。 - 折叠一个节点。
通过点击已展开节点左侧的圆圈来执行此操作。
下面的代码取自 TreeDemo.java
,创建了 JTree
对象并将其放入滚动窗格中:
*//Where instance variables are declared:* private JTree tree; ... public TreeDemo() { ... DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series"); createNodes(top); tree = new JTree(top); ... JScrollPane treeView = new JScrollPane(tree); ... }
代码创建了一个 DefaultMutableTreeNode
的实例作为树的根节点。然后创建树中的其余节点。之后,创建树,将根节点作为参数传递给 JTree
构造函数。最后,将树放入滚动窗格中,这是一个常见的策略,因为显示完整展开的树会占用太多空间。
这是创建根节点下节点的代码:
private void createNodes(DefaultMutableTreeNode top) { DefaultMutableTreeNode category = null; DefaultMutableTreeNode book = null; category = new DefaultMutableTreeNode("Books for Java Programmers"); top.add(category); //original Tutorial book = new DefaultMutableTreeNode(new BookInfo ("The Java Tutorial: A Short Course on the Basics", "tutorial.html")); category.add(book); //Tutorial Continued book = new DefaultMutableTreeNode(new BookInfo ("The Java Tutorial Continued: The Rest of the JDK", "tutorialcont.html")); category.add(book); //Swing Tutorial book = new DefaultMutableTreeNode(new BookInfo ("The Swing Tutorial: A Guide to Constructing GUIs", "swingtutorial.html")); category.add(book); *//...add more books for programmers...* category = new DefaultMutableTreeNode("Books for Java Implementers"); top.add(category); //VM book = new DefaultMutableTreeNode(new BookInfo ("The Java Virtual Machine Specification", "vm.html")); category.add(book); //Language Spec book = new DefaultMutableTreeNode(new BookInfo ("The Java Language Specification", "jls.html")); category.add(book); }
DefaultMutableTreeNode
构造函数的参数是用户对象,它是一个包含或指向与树节点关联数据的对象。用户对象可以是一个字符串,也可以是一个自定义对象。如果你实现了一个自定义对象,你应该实现它的 toString
方法,以便返回要为该节点显示的字符串。JTree 默认使用从 toString
返回的值来渲染每个节点,因此 toString
返回有意义的内容很重要。有时,重写 toString
是不可行的;在这种情况下,你可以重写 JTree 的 convertValueToText
方法,将模型中的对象映射为要显示的字符串。
例如,前面代码片段中使用的 BookInfo
类是一个自定义类,保存了两个数据:一本书的名称和描述该书的 HTML 文件的 URL。toString
方法被实现为返回书名。因此,与 BookInfo
对象关联的每个节点显示一个书名。
注意: 你可以通过在节点的字符串中放置 HTML 标签来指定树节点中的文本格式。有关详细信息,请参阅在 Swing 组件中使用 HTML。
总结一下,您可以通过调用JTree
构造函数来创建一棵树,指定实现 TreeNode 的类作为参数。您可能应该将树放在滚动窗格中,以便树不会占用太多空间。您不必做任何事情来使树节点在用户点击时展开和折叠。但是,您必须添加一些代码,以使树在用户选择节点时做出响应 — 例如,通过点击节点。
响应节点选择
响应树节点选择很简单。您实现一个树选择监听器并在树上注册它。以下代码显示了TreeDemo
程序中与选择相关的代码:
*//Where the tree is initialized:* tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION); //Listen for when the selection changes. tree.addTreeSelectionListener(this); ... public void valueChanged(TreeSelectionEvent e) { *//Returns the last path element of the selection.* *//This method is useful only when the selection model allows a single selection.* DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if (node == null) *//Nothing is selected.* return; Object nodeInfo = node.getUserObject(); if (node.isLeaf()) { BookInfo book = (BookInfo)nodeInfo; displayURL(book.bookURL); } else { displayURL(helpURL); } }
前面的代码执行以下任务:
- 获取树的默认
TreeSelectionModel
,然后设置它,以便一次最多只能选择一个树节点。 - 在树上注册一个事件处理程序。事件处理程序是一个实现
TreeSelectionListener
接口的对象。 - 在事件处理程序中,通过调用树的
getLastSelectedPathComponent
方法确定哪个节点被选中。 - 使用
getUserObject
方法获取与节点关联的数据。
有关处理树选择事件的更多详细信息,请参见如何编写树选择监听器。
自定义树的显示
这里是一些树节点的图片,由 Java、Windows 和 Mac OS 外观实现绘制。
如前面的图所示,树通常为每个节点显示一个图标和一些文本。您可以自定义这些内容,我们将很快展示。
一棵树通常还会执行一些特定外观的绘制,以指示节点之间的关系。您可以以有限的方式自定义这种绘制。首先,您可以使用tree.setRootVisible(true)
来显示根节点,或者使用tree.setRootVisible(false)
来隐藏它。其次,您可以使用tree.setShowsRootHandles(true)
来请求树的顶层节点 — 根节点(如果可见)或其子节点(如果不可见) — 具有可展开或折叠的手柄。
如果你正在使用 Java 外观,你可以自定义是否绘制线条以显示树节点之间的关系。默认情况下,Java 外观在节点之间绘制倾斜线。通过设置树的JTree.lineStyle
客户端属性,你可以指定不同的约定。例如,要请求 Java 外观仅使用水平线来分组节点,请使用以下代码:
tree.putClientProperty("JTree.lineStyle", "Horizontal");
要指定 Java 外观不绘制线条,请使用以下代码:
tree.putClientProperty("JTree.lineStyle", "None");
以下快照显示了在使用 Java 外观时设置JTree.lineStyle
属性的结果。
无论外观如何,节点显示的默认图标是由节点是否为叶子以及如果不是叶子,则是否展开决定的。例如,在 Windows 和 Motif 外观实现中,每个叶子节点的默认图标是一个点;在 Java 外观中,默认叶子图标是一个类似纸张的符号。在我们展示的所有外观实现中,分支节点都用类似文件夹的符号标记。一些外观可能对展开的分支和折叠的分支有不同的图标。
你可以轻松更改用于叶子节点、展开的分支节点或折叠的分支节点的默认图标。要做到这一点,首先创建一个DefaultTreeCellRenderer
的实例。你总是可以从头开始创建自己的 TreeCellRenderer 实现,重用你喜欢的任何组件。接下来,通过调用渲染器上的以下一个或多个方法来指定要使用的图标:setLeafIcon
(用于叶子节点)、setOpenIcon
(用于展开的分支节点)、setClosedIcon
(用于折叠的分支节点)。如果你希望树不显示某种类型节点的图标,那么为图标指定null
。设置好图标后,使用树的setCellRenderer
方法指定DefaultTreeCellRenderer
绘制其节点。以下是一个示例,取自TreeIconDemo.java
:
ImageIcon leafIcon = createImageIcon("images/middle.gif"); if (leafIcon != null) { DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); renderer.setLeafIcon(leafIcon); tree.setCellRenderer(renderer); }
这是 TreeIconDemo 的屏幕截图:
试一试:
- 点击“启动”按钮以使用Java™ Web Start运行 TreeIconDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
如果要更精细地控制节点图标或提供工具提示,可以通过创建DefaultTreeCellRenderer
的子类并重写getTreeCellRendererComponent
方法来实现。因为DefaultTreeCellRenderer
是JLabel
的子类,可以使用任何JLabel
方法 — 例如setIcon
— 来自定义DefaultTreeCellRenderer
。
下面的代码来自TreeIconDemo2.java
,创建了一个单元格渲染器,根据节点文本数据中是否包含“教程”一词来变化叶图标。该渲染器也指定了工具提示文本,如粗体行所示。
试试这个:
- 点击“启动”按钮以使用Java™ Web Start运行 TreeIconDemo2(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
*//...where the tree is initialized:* //Enable tool tips. ToolTipManager.sharedInstance().registerComponent(tree); ImageIcon tutorialIcon = createImageIcon("images/middle.gif"); if (tutorialIcon != null) { tree.setCellRenderer(new MyRenderer(tutorialIcon)); } ... class MyRenderer extends DefaultTreeCellRenderer { Icon tutorialIcon; public MyRenderer(Icon icon) { tutorialIcon = icon; } public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus); if (leaf && isTutorialBook(value)) { setIcon(tutorialIcon); setToolTipText("This book is in the Tutorial series."); } else { setToolTipText(null); //no tool tip } return this; } protected boolean isTutorialBook(Object value) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; BookInfo nodeInfo = (BookInfo)(node.getUserObject()); String title = nodeInfo.bookName; if (title.indexOf("Tutorial") >= 0) { return true; } return false; } }
这是结果:
您可能想知道单元格渲染器是如何工作的。当树绘制每个节点时,JTree
及其外观特定实现实际上都不包含绘制节点的代码。相反,树使用单元格渲染器的绘制代码来绘制节点。例如,要绘制一个具有字符串“Java 编程语言”的叶节点,树会要求其单元格渲染器返回一个可以绘制带有该字符串的叶节点的组件。如果单元格渲染器是DefaultTreeCellRenderer
,那么它会返回一个标签,该标签绘制默认叶图标,然后是字符串。
单元格渲染器只负责绘制;它无法处理事件。如果要向树添加事件处理程序,需要在树或者仅在选择节点时发生处理时在树的单元格编辑器上注册处理程序。有关单元格编辑器的信息,请参阅概念:编辑器和渲染器。该部分讨论了类似于树单元格编辑器和渲染器的表单元格编辑器和渲染器。
动态更改树
以下图显示了一个名为 DynamicTreeDemo 的应用程序,允许您向可见树添加节点并删除节点。您还可以编辑每个节点中的文本。
该应用程序基于教程读者 Richard Stanford 提供的示例。
试试这个:
- 点击“启动”按钮以使用Java™ Web Start运行 DynamicTreeDemo(下载 JDK 7 或更高版本)。或者,要自行编译和运行示例,请参考示例索引。
Java 中文官方教程 2022 版(十九)(3)https://developer.aliyun.com/article/1486746