最近笔者在写一个用来Json格式化的IDEA插件,因为Swing的资料相对比较少,自己也没怎么学过,最后实现起来属实费了一些功夫,在此记录一下。
创建
public static void main(String[] args) {
//创建节点
DefaultMutableTreeNode defaultMutableTreeNode = new DefaultMutableTreeNode("this is parent");
DefaultMutableTreeNode childrenNode = new DefaultMutableTreeNode("son");
DefaultMutableTreeNode grandChildrenNode = new DefaultMutableTreeNode("grandson");
DefaultMutableTreeNode anotherNode = new DefaultMutableTreeNode("this is another node");
//添加子节点
defaultMutableTreeNode.add(childrenNode);
//子节点添加孙节点
childrenNode.add(grandChildrenNode);
defaultMutableTreeNode.add(anotherNode);
JTree jTree = new JTree(defaultMutableTreeNode);
JFrame jFrame = new JFrame();
jFrame.add(jTree);
jFrame.setVisible(true);
jFrame.setSize(840, 270);
//关闭窗口自动结束程序
jFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
通过上面的代码,就可以快速创建一个JTree了,启动之后就是下面这个样子
展开合并监听事件
可以通过添加展开合并的监听事件(树膨胀监听器?)来实现展开或者合并树时,增加一些自定义功能
jTree.addTreeExpansionListener(new TreeExpansionListener() {
//展开事件
@Override
public void treeExpanded(TreeExpansionEvent event) {
System.out.println("我展开的是" + event.getPath().getLastPathComponent());
}
//收起事件
@Override
public void treeCollapsed(TreeExpansionEvent event) {
System.out.println("我收起的是" + event.getPath().getLastPathComponent());
}
});
event.getPath().getLastPathComponent()
可以获取到当前展开的节点
刷新UI
有时我们需要动态添加节点,在添加之后需要调用刷新UI的api才会生效
defaultMutableTreeNode.add(new DefaultMutableTreeNode("i am a new one "));
//只有加上这行代码,才会显示出新的节点
jTree.updateUI();
⚠️ 注意:如果调用updateUI()
是在其他线程中,需要使用SwingUtilities.invokeLater()
jTree.addTreeExpansionListener(new TreeExpansionListener() {
@Override
public void treeExpanded(TreeExpansionEvent event) {
System.out.println("我展开的是" + event.getPath().getLastPathComponent());
//这里不会报错
SwingUtilities.invokeLater(() -> jTree.updateUI());
}
@Override
public void treeCollapsed(TreeExpansionEvent event) {
System.out.println("我收起的是" + event.getPath().getLastPathComponent());
//这里会抛出空指针异常
jTree.updateUI()
}
});
换皮肤
如果不满足于默认的样式,比如节点的默认图标,怎么看怎么像一个文件管理系统,当我用来做一个json格式化工具时,就会怪怪的,这个时候就可以用到自定义渲染
创建自定义渲染器
继承DefaultTreeCellRenderer
后,重写getTreeCellRendererComponent这个方法。此时,如果不想要这个很像文件管理器的图标,就可以像下面这样把图标取消掉
class MyRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component component = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
setIcon(null);
return component;
}
}
如果只是用来去除图标的话,还是有些大材小用了。上面的方法返回了一个Compnent,这时就可以制作一些自定义组件了
比如,可以返回一些按钮
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component component = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
setIcon(null);
return new JButton(value.toString());
}
一些文本框
又或是。。。一些五颜六色的东西
本文的内容到这就结束了,如果觉得有帮助别忘了点个赞呀!