简体   繁体   English

工具提示中的可单击缩略图图像

[英]Clickable thumbnail image in a tooltip

I would like to have a special sort of tooltip appear when a user hovers the mouse cursor over a specific item in a treetable. 当用户将鼠标光标悬停在treetable中的特定项目上时,我希望出现一种特殊的工具提示。 This tooltip will be a thumbnail of a PDF that corresponds to the item in the treetable that the cursor is pointing at. 此工具提示将是PDF的缩略图,对应于光标指向的treetable中的项目。 In addition, I'd like the user to be able to then move the cursor over the thumbnail and click it, which should open up the full PDF in their system's default PDF reader (Acrobat, Adobe Reader, etc.). 此外,我希望用户能够将光标移动到缩略图上并单击它,这将在其系统的默认PDF阅读器(Acrobat,Adobe Reader等)中打开完整的PDF。

I realize this is a tall order, but I've already done most of the work. 我意识到这是一项艰巨的任务,但我已经完成了大部分工作。 I've discovered exactly where in my huge program that I need to have the setToolTip() method so that it can retrieve the appropriate thumbnail. 我已经发现我的庞大程序中确切地需要setToolTip()方法,以便它可以检索适当的缩略图。 In addition, since I've discovered that having Java create thumbnails from a PDF on the fly is far too difficult, I've already got things set up so there will be thumbnail JPGs pre-made. 另外,由于我发现让Java在运行中创建缩略图非常困难,我已经设置了一些内容,因此会预先制作缩略图JPG。 Thus, all the setToolTip() command will need to do is somehow retrieve the appropriate JPG. 因此,所有setToolTip()命令都需要以某种方式检索相应的JPG。 Now comes the hard part. 现在来了困难的部分。

At first, it seemed easy. 起初,这似乎很容易。 I tried this really convenient hack for putting an image in a tooltip , and it definitely gets the thumbnail showing up properly. 我尝试了这个非常方便的黑客将图像放在工具提示中 ,它肯定会让缩略图正确显示。 However, surrounding the <img> tag with an anchor tag ( <a href="...">...</a> ) doesn't quite seem to work. 但是,使用锚标记( <a href="...">...</a> )围绕<img>标记似乎不起作用。 The thumbnail is surrounded by the tell-tale blue border, alright, but the image remains un-clickable. 缩略图被告诉蓝色边框包围,好吧,但图像仍然无法点击。 In addition, the tooltip sometimes just disappears before it's image can be clicked upon. 此外,工具提示有时会在点击图像之前消失。

So I thought I might need to do something more deep than a simple html hack. 所以我认为我可能需要做一些比简单的html黑客更深入的事情。 I tried this more involved way of putting an image in a tooltip , but it seems that will only work for a static image. 我尝试了将图像放在工具提示中的更多参与方式 ,但似乎只适用于静态图像。 I need the image to be different depending on what's being hovered over with the mouse cursor. 我需要根据鼠标光标悬停的图像来区分图像。 In addition, how do I set my method to use this 'custom version of a tooltip' rather than the built-in one? 另外,如何设置我的方法来使用这个“工具提示的自定义版本”而不是内置的?

To give a bit more context, the location where the setToolTip() method seems to work is inside of a getTreeCellRendererComponent() method, a part of a custom class that extends JPanel and implements TreeCellRenderer . 为了让更多的情况下,其中的位置setToolTip()方法似乎工作是内部getTreeCellRendererComponent()方法,扩展的自定义类的一部分JPanel并实现TreeCellRenderer I'll post the code if asked, but it will might be rather complicated and hard to follow. 如果被问到我会发布代码,但它可能会相当复杂并且难以理解。 Any thoughts? 有什么想法吗?

EDIT 10/09/2014, 4:57pm: Much of this code may be confusing, and for that, I apologize. 编辑10/09/2014,下午4:57:这些代码大部分可能令人困惑,为此,我道歉。 Suffice it to say that it has to do with putting a tri-state checkbox inside of a JXTreeTable. 我只想说它与在JXTreeTable中放置一个三态复选框有关。 Anyway, the parts that are important should be easy enough to pick out, I hope. 无论如何,重要的部分应该很容易挑出来,我希望。 As you can see, this class already extends JPanel , so I cannot have it extend JToolTip as well. 正如您所看到的,这个类已经扩展了JPanel ,所以我不能让它扩展JToolTip

package info.chrismcgee.sky.treetable;

import info.chrismcgee.beans.OrderDetail;
import info.chrismcgee.components.ImageToolTip;
import info.chrismcgee.components.TristateCheckBox;
import info.chrismcgee.components.TristateState;
import info.chrismcgee.enums.OSType;

import java.awt.BorderLayout;
import java.io.File;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JToolTip;
import javax.swing.JTree;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;

public class SkyCheckTreeCellRenderer extends JPanel implements
        TreeCellRenderer {
    /**
     * 
     */
    private static final long serialVersionUID = -2728513730497144120L;
    private SkyCheckTreeSelectionModel selectionModel;
    private TreeCellRenderer delegate;
    private boolean showRootNodeCheckBox;
    private TristateCheckBox checkBox = new TristateCheckBox("");
    protected SkyCheckTreeManager.CheckBoxCustomizer checkBoxCustomer;
    private String jobsFolderStr = OSType.getOSType() == OSType.MAC
            ? "/Volumes/ArtDept/ArtDept/JOBS"
            : "//SKYFS/ArtDept/ArtDept/JOBS";

    public SkyCheckTreeCellRenderer(TreeCellRenderer delegate,
            SkyCheckTreeSelectionModel selectionModel,
            boolean showRootNodeCheckBox) {
        this.delegate = delegate;
        this.selectionModel = selectionModel;
        this.showRootNodeCheckBox = showRootNodeCheckBox;
        setLayout(new BorderLayout());
        setOpaque(false);
        checkBox.setOpaque(false);
    }

    public JToolTip createToolTip() {
        return new ImageToolTip();
    }

    private String getToolTipText(DefaultMutableTreeTableNode node)
    {
        if (node.getUserObject() instanceof OrderDetail)
        {
            OrderDetail od = (OrderDetail) node.getUserObject();
            String thousandsFolderStr = jobsFolderStr + "/"
                    + od.getOrderId().substring(0, 3) + "000-"
                    + od.getOrderId().substring(0, 3) + "999/";

            String productFolderStr = thousandsFolderStr + od.getOrderId()
                    + " Folder/";
            if (!od.getProductDetail().equals(""))
                productFolderStr = thousandsFolderStr + od.getOrderId() + "/";

            String img = productFolderStr + od.getOrderId() + "_THUMB.jpg";
            if (!od.getProductDetail().equals(""))
                img = productFolderStr + od.getOrderId() + "_" + od.getProductDetail() + "_THUMB.jpg";

            if (new File(img).exists())
                return "<html><img src=\"file://" + img + "\"></html>";
        }
        return null;
    }

    public JComponent getTreeCellRendererComponent(JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus)
    {
        JComponent renderer = (JComponent) delegate.getTreeCellRendererComponent(tree, value,
                selected, expanded, leaf, row, hasFocus);

        if (!showRootNodeCheckBox && tree.getModel().getRoot() == value)
        {
            renderer.setToolTipText(getToolTipText((DefaultMutableTreeTableNode)value));
            return renderer;
        }

        TreePath path = tree.getPathForRow(row);
        if (path != null) {
            if (checkBoxCustomer != null && !checkBoxCustomer.showCheckBox(path))
            {
                renderer.setToolTipText(getToolTipText((DefaultMutableTreeTableNode)value));
                return renderer;
            }
            if (selectionModel.isPathSelected(path, selectionModel.isDigged()))
                checkBox.getTristateModel().setState(TristateState.SELECTED);
            else
                checkBox.getTristateModel().setState(selectionModel.isDigged()
                        && selectionModel.isPartiallySelected(path)
                            ? TristateState.INDETERMINATE
                            : TristateState.DESELECTED);
        }
        removeAll();
        add(checkBox, BorderLayout.WEST);
        add(renderer, BorderLayout.CENTER);
        setToolTipText(getToolTipText((DefaultMutableTreeTableNode)value));
        return this;
    }

}

I get that I need to somehow extend JToolTip, and that this SkyCheckTreeCellRenderer class needs to somehow reference that custom tooltip. 我知道我需要以某种方式扩展JToolTip,并且这个SkyCheckTreeCellRenderer类需要以某种方式引用该自定义工具提示。 I guess all of this is just getting so involved and complex that my simple brain is having trouble wrapping around it all. 我想所有这些只是变得如此复杂,以至于我的简单大脑无法绕过它。 My apologies. 我很抱歉。

how do I set my method to use this 'custom version of a tooltip' rather than the built-in one? 如何设置我的方法来使用这个“工具提示的自定义版本”而不是内置的?

As the example shows you need to extend the component to use the custom tool tip. 如示例所示,您需要扩展组件以使用自定义工具提示。

I need the image to be different depending on what's being hovered over with the mouse cursor 我需要根据鼠标光标悬停的图像来区分图像

Then you will need to override the getToolTipText(MouseEvent) method to return a text string to represent the image you want to display. 然后,您需要覆盖getToolTipText(MouseEvent)方法以返回文本字符串以表示要显示的图像。

However, surrounding the tag with an anchor tag (...) doesn't quite seem to work 但是,使用锚标记(...)包围标记似乎不起作用

You would need to use a JEditorPane if you want to respond to a hyperlink. 如果要响应超链接,则需要使用JEditorPane。 Read the JEditorPane API for an example. 阅读JEditorPane API以获取示例。

So basically I would suggest that you need to use a custom JToolTip, that uses a JEditorPane to display the appropriate Image with an appropriate Hyperlink. 所以基本上我建议您需要使用自定义JToolTip,它使用JEditorPane来显示具有适当超链接的相应图像。 Here is an example that shows how to use a JLabel as an added component to a tool tip. 下面是一个示例,说明如何将JLabel用作工具提示的附加组件。 You should be able to modify the code to use a JEditorPane. 您应该能够修改代码以使用JEditorPane。

Also, you need to extend your tree table to use this custom JToolTip. 此外,您需要扩展树表以使用此自定义JToolTip。

import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ToolTipImage extends JToolTip
{
    private Image image;

    public ToolTipImage(Image image)
    {
        this.image = image;

        setLayout( new BorderLayout() );
        add( new JLabel( new ImageIcon( image) ) );
    }

    @Override
    public Dimension getPreferredSize()
    {
        return new Dimension(image.getWidth(this), image.getHeight(this));
    }

    private static void createAndShowGUI() throws Exception
    {
        final BufferedImage testImage = ImageIO.read(new File("dukewavered.gif"));

        String[] columnNames = {"Column 0", "Column 1"};

        Object[][] data =
        {
            {"Cell 0,0", "Cell 0,1"},
            {"Cell 1,0", "Cell 1,1"}
        };

        JTable table = new JTable(data, columnNames)
        {
            public JToolTip createToolTip()
            {
                return new ToolTipImage( testImage );
            }
        };

        // Set tool tip text so that table is registered w/ tool tip manager
        table.setToolTipText(" ");

        JFrame frame = new JFrame("Tool Tip Image");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new JScrollPane(table) );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    createAndShowGUI();
                }
                catch(Exception e) { System.out.println(e); }
            }
        });
    }
}

It sounds like you need to build a custom tooltip, as detailed in JToolTip . 听起来你需要构建一个自定义工具提示,如JToolTip中所述

When clicked, you should use Runtime to open your file from the commandline. 单击时,应使用Runtime从命令行打开文件。 The way to do this in windows is posted here . 在Windows中这样做的方法发布在这里 The way to do this on ubuntu is posted here 在ubuntu上执行此操作的方法发布在此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM