swing的tree

本文介绍了一个使用 Java Swing 实现的自定义树形组件示例,该组件基于 JButton 扩展,并集成了 JTree 的功能。文章展示了如何通过监听事件实现下拉树形菜单效果,以及如何自定义单元格渲染器来改变树节点的表现形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码copy自网上

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.metal.MetalComboBoxIcon;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

public class Test extends JButton {

 /**
  *
  */
 private static final long serialVersionUID = 1L;
 private JTree tree;//
 private JScrollPane js;
 private Popup pop;
 private boolean ispopshow;//
 private int gap;//
 private String curveName;//选择的曲线名字

 public Test(JTree jtree) {
  super(" ", new MetalComboBoxIcon());
  this.setPreferredSize(new Dimension(200, 10));
  gap = this.getIconTextGap();// 返回此按钮中显示的文本与图标之间的间隔量
  ispopshow = false;
  setMargin(new Insets(1, 2, 1, 2));
  this.tree = jtree;
  tree.setEditable(false);
  tree.getSelectionModel().setSelectionMode(1);// 设置选择模型 1表示一次只能选择一个路径
  setTableCellRender(new DefaultTreeCellRenderer());
  tree.setOpaque(false);// 组件不透明的就设置为true
  js = new JScrollPane(tree);
  this.setPreferredSize(new Dimension(js.getPreferredSize().width,
    getPreferredSize().height));
  this.setText(jtree.getPathForRow(0).toString());
  updateUI();
  tree.addTreeSelectionListener(new TreeSelectionListener() {
   public void valueChanged(TreeSelectionEvent treeselectionevent) {
    if (isLeafNode()) {
     String coboBoxContent=getLastSelectedPathComponent().toString();
     setText(coboBoxContent);
     curveName=coboBoxContent;
     setCurveName(curveName);
    } else {
     TreePath treePath = (TreePath) tree.getSelectionPath();
     if (treePath != null) {
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
        .getLastPathComponent();
      JOptionPane.showMessageDialog(null, "请选择"
        + node.toString() + "的子节点", "alert",
        JOptionPane.INFORMATION_MESSAGE);
     }
    }
    if (!ispopshow)
     pophide();
   }
  });
  addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent actionevent) {
    if (!ispopshow) {
     pupshow();
    } else {
     pophide();
    }
   }
  });

  addFocusListener(new FocusAdapter() {
   public void focusLost(FocusEvent focusevent) {
    if (focusevent.getOppositeComponent() != tree)
     pophide();
    else
     requestFocus();
   }
  });
 }

 public boolean isLeafNode() {
  boolean isLeafNode = false;
  TreePath treePath = (TreePath) tree.getSelectionPath();
  if (treePath != null) {
   DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath
     .getLastPathComponent();
   if (node.getChildCount() == 0) {
    isLeafNode = true;
   }
  }
  return isLeafNode;
 }

 private void pupshow() {
  if (pop == null) {
   Point point = new Point(0, getHeight());
   SwingUtilities.convertPointToScreen(point, this);
   int y = tree.getPreferredScrollableViewportSize().height;
   y = y > 220 ? 220 : y;
   js.setPreferredSize(new Dimension(getWidth(), y));
   pop = PopupFactory.getSharedInstance().getPopup(this, js, point.x,
     point.y);
   pop.show();
  }
 }

 private void pophide() {
  if (pop != null) {
   pop.hide();
   pop = null;
  }
 }

 public void setTableCellRender(TreeCellRenderer treecellrenderer) {
  tree.setCellRenderer(treecellrenderer);
  ((JComponent) treecellrenderer).setOpaque(false);
  if (treecellrenderer instanceof DefaultTreeCellRenderer) {
   ((DefaultTreeCellRenderer) treecellrenderer)
     .setTextNonSelectionColor(UIManager
       .getColor("ComboBox.foreground"));
   ((DefaultTreeCellRenderer) treecellrenderer)
     .setBackgroundNonSelectionColor(UIManager
       .getColor("ComboBox.background"));
  }
 }

 public Object getLastSelectedPathComponent() {
  return tree.getLastSelectedPathComponent();// 返回当前选择的第一个节点中的最后一个路径组件。
 }

 protected void paintComponent(Graphics g) {
  super.paintComponent(g);
  if (getLastSelectedPathComponent() != null) {
   Component component = tree.getCellRenderer()
     .getTreeCellRendererComponent(
       tree,
       getLastSelectedPathComponent(),
       false,
       tree.isExpanded(tree.getSelectionPath()),
       tree.getModel().isLeaf(
         getLastSelectedPathComponent()),
       tree.getRowForPath(tree.getSelectionPath()), false);
   component.paint(g);
  }
 }

 public void setBounds(Rectangle rectangle) {
  setBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
 }

 public void setBounds(int rx, int ry, int rw, int rh) {
  super.setBounds(rx, ry, rw, rh);
  Dimension dimension = BasicGraphicsUtils.getPreferredButtonSize(this,
    gap);
  if (rw > dimension.width)
   setIconTextGap((rw - dimension.width) + gap);
  else
   setIconTextGap(gap);
 }

 public void updateUI() {
  super.updateUI();
  setHorizontalTextPosition(SwingConstants.LEFT);
  setText(getText());
 }

 // test
 public static void main(String[] args) {
  JFrame frame = new JFrame();
  JTree tree = new JTree();
  Test tc = new Test(tree);
  tc.setPreferredSize(new Dimension(200, 40));
  Container cc = frame.getContentPane();
  cc.add(tc);
  frame.setSize(200, 60);
  frame.setVisible(true);
  frame.setDefaultCloseOperation(3);
 }

 public String getCurveName() {
  return curveName;
 }

 public void setCurveName(String curveName) {
  this.curveName = curveName;
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值