将过渡添加到JTree句柄 [英] Add rollover to JTree handles

查看:77
本文介绍了将过渡添加到JTree句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在

I am trying to make a custom rollover effect on the Collapsed Icon for a JTree. However, I am unsure how to target an individual handle instead of all the handles.

如果运行下面的代码,您将看到,将鼠标悬停在JTree的任何句柄,节点或叶上时,所有折叠的句柄都将变为翻转.这是不希望的.因此,当我将鼠标悬停在该手柄上时,如何只改变一个手柄,而当悬停在其旁边的节点上时,最好不改变它呢?

If you run the code below, you will see that when you hover over any handle, node, or leaf of the JTree all the collapsed handles will change to the rollover. This is not desired. So how can I change just a single handle when I am hovering over that handle, and preferably not when hovering over the node next to it?

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.plaf.basic.*;

@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
    private DirectoryExplorer() {
        super("Directory Explorer");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        setSize(800,600);
        setVisible(true);
    }

    private void createPanel() {
        JPanel panel = new JPanel(new GridLayout(1, 1));

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Hello");
        root.add(new DefaultMutableTreeNode("1"));
        root.add(new DefaultMutableTreeNode("2"));
        root.add(new DefaultMutableTreeNode("3"));

        JTree tree = new JTree();
        BasicTreeUI tUI = (BasicTreeUI) tree.getUI();
        tUI.setCollapsedIcon(new ImageIcon("resources/closed.png"));
        tUI.setExpandedIcon(new ImageIcon("resources/open.png"));
        tree.setShowsRootHandles(true);
        tree.addMouseMotionListener(new MouseHandler(tree));

        panel.add(new JScrollPane(tree));
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        new DirectoryExplorer();
    }

    private class MouseHandler implements MouseMotionListener {
        JTree t = null;
        BasicTreeUI tUI = null;

        public MouseHandler(JTree tree) {
            t = tree;
            tUI = (BasicTreeUI) tree.getUI();
        }

        @Override
        public void mouseDragged(MouseEvent e) {

        }

        @Override
        public void mouseMoved(MouseEvent e) {
            TreePath selPath = t.getPathForLocation(e.getX(), e.getY());
            if(selPath != null) 
                tUI.setCollapsedIcon(new ImageIcon("resources/rollover.png"));
            else
                tUI.setCollapsedIcon(new ImageIcon("resources/closed.png"));
            t.repaint();
        }
    }
}

推荐答案

为了获得所需的结果,您需要覆盖BasicTreeUI.paintExpandControl()BasicTreeUI.MouseHandler.mouseMoved().您还需要创建一些方法,例如setRolloverIcon().

In order to achieve the desired result you need to override BasicTreeUI.paintExpandControl() and BasicTreeUI.MouseHandler.mouseMoved(). You will also need to create a few methods such as setRolloverIcon().

一个可行的例子可能像这样

A working example of this might look like this

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
    private DirectoryExplorer() {
        super("Directory Explorer");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        setSize(800,600);
        setVisible(true);
    }

    private void createPanel() {
        JPanel panel = new JPanel(new GridLayout(1, 1));

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Hello");
        root.add(new DefaultMutableTreeNode("1"));
        root.add(new DefaultMutableTreeNode("2"));
        root.add(new DefaultMutableTreeNode("3"));

        JTree tree = new JTree();

        //UI Stuff//
        TreeHandleUI tUI = new TreeHandleUI(tree);
        tree.setUI(tUI);
        try {
            tUI.setCollapsedIcon(new ImageIcon(new URL("https://i.stack.imgur.com/nKJFv.png")));
            tUI.setExpandedIcon(new ImageIcon(new URL("https://i.stack.imgur.com/NJvcp.png")));
            tUI.setRolloverIcon(new ImageIcon(new URL("https://i.stack.imgur.com/jN6uX.png")));
        } catch(MalformedURLException e) {
            System.out.println("Bad URL / URLs");
        }
        ////////////

        tree.setShowsRootHandles(true);

        panel.add(new JScrollPane(tree));
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new DirectoryExplorer());
    }

    private class TreeHandleUI extends BasicTreeUI {
        ///Variables
        private JTree t = null;
        private Icon rolloverIcon = null;
        private boolean rolloverEnabled = false;
        private UpdateHandler uH = null;

        private boolean isLeftToRight( Component c ) {
            return c.getComponentOrientation().isLeftToRight();
        }

        public TreeHandleUI(JTree tree) {
            t = tree;
            uH = new UpdateHandler(t);
            t.addMouseMotionListener(uH);
        }

        public void setRolloverIcon(Icon rolloverG) {
            Icon oldValue = rolloverIcon;
            rolloverIcon = rolloverG;
            setRolloverEnabled(true);
            if (rolloverIcon != oldValue) {
                t.repaint();
            }
        }

        private void setRolloverEnabled(boolean handleRolloverEnabled) {
            boolean oldValue = rolloverEnabled;
            rolloverEnabled = handleRolloverEnabled;
            if (handleRolloverEnabled != oldValue) {
                t.repaint();
            }
        }

        @Override
        protected void paintExpandControl(Graphics g,
                                          Rectangle clipBounds, Insets insets,
                                          Rectangle bounds, TreePath path,
                                          int row, boolean isExpanded,
                                          boolean hasBeenExpanded,
                                          boolean isLeaf) {
            Object value = path.getLastPathComponent();

            if (!isLeaf && (!hasBeenExpanded || treeModel.getChildCount(value) > 0)) {
                int middleXOfKnob;
                if (isLeftToRight(t)) {
                    middleXOfKnob = bounds.x - getRightChildIndent() + 1;
                } else {
                    middleXOfKnob = bounds.x + bounds.width + getRightChildIndent() - 1;
                }
                int middleYOfKnob = bounds.y + (bounds.height / 2);

                if (isExpanded) {
                    Icon expandedIcon = getExpandedIcon();
                    if(expandedIcon != null)
                      drawCentered(tree, g, expandedIcon, middleXOfKnob, middleYOfKnob );
                } else if(isLocationInExpandControl(path, uH.getXPos(), uH.getYPos()) && !isExpanded && rolloverEnabled) {
                    if(row == uH.getRow()) {
                        if(rolloverIcon != null)
                            drawCentered(tree, g, rolloverIcon, middleXOfKnob, middleYOfKnob);
                    } else {
                        Icon collapsedIcon = getCollapsedIcon();
                        if(collapsedIcon != null)
                          drawCentered(tree, g, collapsedIcon, middleXOfKnob, middleYOfKnob);
                    }
                } else {
                    Icon collapsedIcon = getCollapsedIcon();
                    if(collapsedIcon != null)
                      drawCentered(tree, g, collapsedIcon, middleXOfKnob, middleYOfKnob);
                }
            }
        }

        private class UpdateHandler extends BasicTreeUI.MouseHandler {
            private JTree t = null;
            private int xPos = 0;
            private int yPos = 0;

            private boolean leftToRight(Component c) {
                return c.getComponentOrientation().isLeftToRight();
            }

            public UpdateHandler(JTree tree) {
                t = tree;
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();
                t.repaint();
            }

            public int getXPos() {
                return xPos;
            }

            public int getYPos() {
                return yPos;
            }

            public int getRow() {
                return getRowForPath(t, getClosestPathForLocation(t, xPos, yPos));
            }
        }
    }
}

代码将在不下载图像的情况下运行,但是可以在下面使用它们

closed.png

open.png

rollover.png

这篇关于将过渡添加到JTree句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆