您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发
【原】JTree的第三次优化详细教程
不忘初心 2017-11-08 围观() 评论() 点赞() 【JAVA开发】
简介:关于jtree的代码二次优化,开始觉着很完美,可是后来仔细一想,好像还是没有脱离第一次优化时的思路,在渲染当前节点时,恢复之前的节点,为什么非要循环jtree来处理呢?如果说jtree有成百上千个节点,那么每次循环,性能肯定好不到哪里去,所以还需要第三次优化。思路:定义变量来记录之前的节点,每次变动,只更新这两个指定的节点好处:不用每次都刷新整颗jtree,也不需要在自定义node中增加字段来标记
关于jtree的代码二次优化,开始觉着很完美,可是后来仔细一想,好像还是没有脱离第一次优化时的思路,在渲染当前节点时,恢复之前的节点,为什么非要循环jtree来处理呢?
如果说jtree有成百上千个节点,那么每次循环,性能肯定好不到哪里去,所以还需要第三次优化。
思路:定义变量来记录之前的节点,每次变动,只更新这两个指定的节点
好处:不用每次都刷新整颗jtree,也不需要在自定义node中增加字段来标记选中(这个字段开始设计就是为了在循环刷新整颗jtree的时候使用)
前两次优化中,描述已经说得很多了,这次就不再赘述,直接贴代码;
由于只是精简了代码,所以效果图还是一样的。
JTreeFrame.java
package com.wolffy.frame;
import com.wolffy.node.MyTreeNode;
import com.wolffy.ui.MyTreeUI;
import com.wolffy.util.ImgUtils;
import com.wolffy.util.TreeUtils;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
/**
* Created by SongFei on 2017/10/24.
*/
public class JTreeFrame extends JFrame {
private static final long serialVersionUID = 8632851951749045685L;
/**
* 鼠标滑过
*/
private Color HOVER_COLOR = new Color(200, 200, 200, 100);
/**
* 鼠标点击
*/
private Color SELECT_COLOR = new Color(160, 160, 160, 100);
private JPanel jPanel;
private JTree jTree;
private DefaultMutableTreeNode root;
private DefaultTreeModel model;
private MyTreeNode selectNode;
private MyTreeNode hoverNode;
public JTreeFrame() {
initGUI();
}
private void initGUI() {
setSize(700, 575);
//setUndecorated(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jPanel = new JPanel();
getContentPane().add(jPanel, BorderLayout.CENTER);
root = new DefaultMutableTreeNode();
model = new DefaultTreeModel(root);
for (int i = 1; i <= 3; i++) {
MyTreeNode cate = new MyTreeNode(ImgUtils.getIcon("arrow_left.png"), "我的分组" + i);
for (int j = 1; j <= 3; j++) {
MyTreeNode node = new MyTreeNode(ImgUtils.getIcon("avatar.png"), "好友" + i + "-" + j, "人生若只如初见");
cate.add(node);
}
root.add(cate);
}
jTree = new JTree(model);
jTree.setUI(new MyTreeUI());
jTree.addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
if (hoverNode == null) {
return;
}
if (hoverNode != selectNode) {
TreeUtils.restoreNodeColor(model, hoverNode);
}
hoverNode = null;
}
@Override
public void mouseClicked(MouseEvent e) {
TreePath path = jTree.getSelectionPath();
if (path == null) {
return;
}
MyTreeNode node = (MyTreeNode) path.getLastPathComponent();
if (node == null) {
return;
}
// 除了好友节点,其他节点都没有点击选中功能
if (node.getLevel() != 2) {
return;
}
// 避免重复点击
if (node == selectNode) {
return;
}
TreeUtils.restoreNodeColor(model, selectNode);
TreeUtils.setNodeColor(model, node, SELECT_COLOR);
selectNode = node;
}
});
jTree.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
TreePath path = jTree.getPathForLocation(e.getX(), e.getY());
if (path == null) {
return;
}
MyTreeNode node = (MyTreeNode) path.getLastPathComponent();
if (node == null) {
return;
}
// 同一个节点,避免重复hover
if (node == hoverNode) {
return;
}
// 点击了一个节点之后,select == hover,此时再次滑动时就会导致将select的颜色变成hover的颜色了
// select的权重高,已经select了,就不再hover
if (hoverNode != selectNode) {
TreeUtils.restoreNodeColor(model, hoverNode);
}
// hover到了select节点,就不再hover
if (node == selectNode) {
hoverNode = node;// 必须记录一下,否则重复滑动不了
return;
}
TreeUtils.setNodeColor(model, node, HOVER_COLOR);
hoverNode = node;
}
});
jPanel.add(jTree);
}
public static void main(String[] args) {
JTreeFrame jTreeFrame = new JTreeFrame();
jTreeFrame.setVisible(true);
}
}
TreeUtils.java
package com.wolffy.util;
import com.wolffy.node.MyTreeNode;
import javax.swing.JPanel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.Color;
/**
* Created by SongFei on 2017/11/6.
*/
public class TreeUtils {
/**
* 设置Node背景颜色
*
* @param model 模型,需要用它来刷新jtree
* @param node 自定义的MyTreeNode节点
* @param color 颜色
*/
public static void setNodeColor(DefaultTreeModel model, MyTreeNode node, Color color) {
if (model == null || node == null) {
return;
}
JPanel panel = null;
if (node.getLevel() == 1) {
panel = (JPanel) node.getGroupView();
}
if (node.getLevel() == 2) {
panel = (JPanel) node.getBuddyView();
}
if (panel != null) {
panel.setBackground(color);
model.reload(node);
}
}
/**
* 重置Node节点的Color
*
* @param model 模型
* @param node 自定义Node
*/
public static void restoreNodeColor(DefaultTreeModel model, MyTreeNode node) {
if (model == null || node == null) {
return;
}
if (node.getLevel() == 1) {
node.getGroupView().setBackground(null);
}
if (node.getLevel() == 2) {
node.getBuddyView().setBackground(null);
}
model.reload(node);
}
}
MyTreeNode.java
package com.wolffy.node;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Component;
import java.awt.Dimension;
/**
* Created by SongFei on 2017/11/6.
*/
public class MyTreeNode extends DefaultMutableTreeNode {
private static final long serialVersionUID = 1007068847268622569L;
/**
* 图片
*/
private Icon icon;
/**
* 文字
*/
private String name;
/**
* 签名
*/
private String sign;
private JPanel groupPanel;
private JPanel buddyPanel;
private JLabel iconLabel;
private JLabel nameLabel;
private JLabel signLabel;
public MyTreeNode() {
}
/**
* 初始化分组节点
*
* @param name 名称
*/
public MyTreeNode(Icon icon, String name) {
this.icon = icon;
this.name = name;
// 初始化UI
initCateGUI();
}
/**
* 初始化好友节点
*
* @param icon 头像
* @param nick 昵称
* @param sign 签名
*/
public MyTreeNode(Icon icon, String nick, String sign) {
this.icon = icon;
this.name = nick;
this.sign = sign;
// 初始化UI
initNodeGUI();
}
/**
* 自定义分组UI
*/
private void initCateGUI() {
groupPanel = new JPanel();
groupPanel.setLayout(null);
// groupPanel.setOpaque(false);
// 这里大家注意,当我们写好UI之后可能会发现他的颜色不太对,
// 这时候千万不要用上面那句,不然当我们想再次改变其颜色的时候,就生效不了
// 红绿蓝分别为255的这个颜色趋近于透明,我们可以用它来代替setOpaque
// groupPanel.setBackground(new Color(255,255,255));
// 突然发现置成null也可以
groupPanel.setBackground(null);
groupPanel.setPreferredSize(new Dimension(300, 25));
// groupPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
iconLabel = new JLabel(icon);
iconLabel.setBounds(6, 5, 20, 16);
groupPanel.add(iconLabel);
nameLabel = new JLabel(name);
nameLabel.setBounds(23, 0, 132, 28);
groupPanel.add(nameLabel);
}
/**
* 自定义好友UI
*/
private void initNodeGUI() {
buddyPanel = new JPanel();
buddyPanel.setLayout(null);
buddyPanel.setBackground(null);
buddyPanel.setPreferredSize(new Dimension(300, 50));
// buddyPanel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
iconLabel = new JLabel(icon);
iconLabel.setBounds(8, 4, 42, 42);
buddyPanel.add(iconLabel);
nameLabel = new JLabel(name);
nameLabel.setBounds(59, 5, 132, 19);
buddyPanel.add(nameLabel);
signLabel = new JLabel(sign);
signLabel.setBounds(59, 28, 132, 17);
buddyPanel.add(signLabel);
}
/**
* 将自定义UI返回给渲染器 <br/>
* 供渲染器调用,返回的必须是一个Component
*
* @return
*/
public Component getGroupView() {
return groupPanel;
}
/**
* 将自定义UI返回给渲染器 <br/>
* 供渲染器调用,返回的必须是一个Component
*
* @return
*/
public Component getBuddyView() {
return buddyPanel;
}
public JLabel getIconLabel() {
return iconLabel;
}
public JLabel getNameLabel() {
return nameLabel;
}
public JLabel getSignLabel() {
return signLabel;
}
public Icon getIcon() {
return icon;
}
public void setIcon(Icon icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}
几个主要改动点:MouseListener中的逻辑、MyTreeNode的字段精简、TeeUtils代码精简。
MyTreeUI没有改动,大家可以直接用上一篇文章(http://jiweichengzhu.com/article/5ff1be1e8abe463794aa1011b4bcff96)中的代码!
看完文章,有任何疑问,请加入群聊一起交流!!!
很赞哦! ()
相关文章
标签云
猜你喜欢
- IntelliJ IDEA 2019.2已经可以利用补丁永久破解激活了
- IntelliJ IDEA 2019.3利用补丁永久破解激活教程
- IntelliJ IDEA高版本最灵活的永久破解激活方法(含插件激活,时长你说了算)
- Jetbrains全家桶基于ja-netfilter的最新破解激活详细图文教程
- IntelliJ IDEA 2022.1永久破解激活教程(亲测可用,持续更新)
- 分享几个正版 IntelliJ IDEA 激活码(破解码、注册码),亲测可用,持续更新
- ja-netfilter到底需不需要mymap,2021.3.2版本激活失效?
- 如何激活idea2022.1及以上版本中的插件(亲测可用)
- 【史上最全】IntelliJ IDEA最新2022.1版本安装和激活视频教学(含插件)
- IntelliJ IDEA 2022.2 版本最新2099年永久激活方法,亲测可用,也可以开启新UI了。
站点信息
- 网站程序:spring + freemarker
- 主题模板:《今夕何夕》
- 文章统计:篇文章
- 标签管理:标签云
- 微信公众号:扫描二维码,关注我们