2014-10-09 70 views
1

我想在用户将鼠标光标悬停在treetable中的特定项目上时出现特殊类型的工具提示。此工具提示将是与光标指向的treetable中的项目对应的PDF的缩略图。另外,我希望用户能够将光标移动到缩略图上并单击它,这应该在系统的默认PDF阅读器(Acrobat,Adobe Reader等)中打开完整的PDF。可点击的工具提示中的缩略图图片

我意识到这是一项艰巨的任务,但我已经完成了大部分工作。我发现我的巨大程序中究竟有哪些地方需要使用setToolTip()方法,以便它可以检索合适的缩略图。另外,由于我发现使用Java在PDF上动态创建缩略图非常困难,我已经设置了一些东西,所以会预先制作缩略图JPG。因此,所有setToolTip()命令将需要做的是以某种方式检索适当的JPG。现在是困难的部分。

起初,它似乎很容易。我尝试this really convenient hack for putting an image in a tooltip,它肯定会得到正确显示的缩略图。但是,使用锚标记(<a href="...">...</a>)包围<img>标记似乎并不奏效。缩略图被蓝色的边框包围着,没问题,但图片仍然不可点击。另外,工具提示有时会在图像被点击之前消失。

所以我想我可能需要做一些比简单的html hack更深的东西。我试过this more involved way of putting an image in a tooltip,但它似乎只适用于静态图像。我需要图像根据鼠标光标悬停的内容而不同。另外,如何设置我的方法来使用这个'定制版本的工具提示'而不是内置的?

为了让更多的背景,其中setToolTip()方法似乎工作的位置是getTreeCellRendererComponent()方法,扩展JPanel并实现TreeCellRenderer的自定义类的一部分内。如果被问到,我会发布代码,但这可能会相当复杂且难以遵循。有什么想法吗?

编辑10/09/2014,4:57 pm:大部分代码可能令人困惑,为此,我表示歉意。只需说明它与在JXTreeTable中放置三态复选框有关。无论如何,重要的部分应该很容易挑选出来,我希望。正如你所看到的,这个类已经延伸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; 
    } 

} 

,我感到我需要莫名其妙 JToolTip的延伸,而这SkyCheckTreeCellRenderer类需要莫名其妙参考的自定义工具提示。我想所有这些都变得如此复杂,以至于我的简单大脑在整个过程中都遇到了麻烦。我很抱歉。

回答

1

这听起来像你需要建立一个自定义工具提示,如detailed in JToolTip

单击时,应该使用运行系统从命令行打开文件。在Windows中这样做的方式发布为here。在Ubuntu上做到这一点的方式发布here

2

如何设置我的方法来使用此'定制版本的工具提示'而不是内置的?

如示例所示,您需要扩展组件以使用自定义工具提示。

我需要的图像是根据不同的什么正在上空盘旋,鼠标光标

然后,你将需要重写getToolTipText(MouseEvent)方法返回一个字符串来表示你想要的形象显示。

然而,与周围的锚标记(...)的标签并不完全似乎工作

您需要,如果你想以超链接响应使用一个JEditorPane。阅读JEditorPane API的示例。

所以基本上我会建议你需要使用自定义的JToolTip,它使用JEditorPane来显示适当的超链接相应的图像。以下是一个示例,显示如何将JLabel用作工具提示的附加组件。您应该可以修改代码以使用JEditorPane。

此外,您需要扩展您的树表以使用此自定义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); } 
      } 
     }); 
    } 
} 
+0

我看到你要去哪里,但相关的类我已经扩展了'JPanel'。看我的编辑,了解我来自哪里。任何想法,@camickr或@ControlAltDel? – Sturm 2014-10-09 21:12:16

+0

@Sturm'正如你所看到的,这个类已经扩展了JPanel,所以我也不能扩展JToolTip。“我从来没有说过你必须扩展JToolTip。在我给你的例子中,“ToolTipImage”类是一个独立的类。 – camickr 2014-10-09 23:50:05