如何在多边形上显示浮动工具提示文本

How to display floating tool tip text on a polygon

我写了一个 Java 代码来在图像上绘制多边形。当我将光标放在多边形内时,它会打印 "Inside",否则显示 "Outside"。因此多边形内点的检测工作正常。

但我想在多边形内部实现setToolTipText的效果,即当鼠标悬停在多边形内部时,它会显示浮动文本"Inside"。

类似于此图中的效果:

http://www.java2s.com/Code/Java/Swing-JFC/WorkingwithTooltipText.htm

要获得预期效果,对以下代码进行哪些最小更改?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.image.*;
import java.awt.Graphics.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

class page1 extends JFrame implements MouseListener,MouseMotionListener ,ActionListener
{
    JFrame f;
    JLabel l;
    JPanel p1;
    ImageIcon ii;
    Image img;
    int height;
    int width;
    Container c;
    int pixels[];
    PixelGrabber pg;
    JPanel panel;
    Graphics2D gg;
    Polygon pp1=new Polygon();
    boolean startHovercurrent,startHoverprev=false;


    page1()
    {
        f=new JFrame("Sample Page");
        ii=new ImageIcon("sample.jpg");
        img=ii.getImage();
        height=ii.getIconHeight();
        width=ii.getIconWidth();
        pixels=new int[ii.getIconWidth()*ii.getIconHeight()];
        pg=new PixelGrabber(img,0,0,ii.getIconWidth(),ii.getIconHeight(),pixels,0,ii.getIconWidth());
        try
        {
            pg.grabPixels();
        }
        catch(InterruptedException k)
        {
        }

        //add points of polygon
        pp1.addPoint(300,300);
        pp1.addPoint(380,300);
        pp1.addPoint(380,220);
        pp1.addPoint(300,220);


        l=new JLabel(ii,JLabel.CENTER);
        c=f.getContentPane();
        JDesktopPane desk = new JDesktopPane();
        JInternalFrame p = new JInternalFrame("Image Frame",false, false, true, false);
        JScrollPane scroll = new JScrollPane(l);
        p.setContentPane(scroll);
        p.setBounds(0, 0, 740, 600);
        desk.add(p);
        p.setVisible(true);
        l.addMouseListener(this);
        l.addMouseMotionListener(this);

        c.add(desk, BorderLayout.CENTER);
        f.setSize(1024,738);
        f.setVisible(true);

    }


    public static void main(String args[])
    {
        new page1();    
    }
    public void mouseClicked(MouseEvent me)
    {
    }
    public void mouseEntered(MouseEvent me)
    {
    }
    public void mouseExited(MouseEvent me)
    {
    }
    public void mousePressed(MouseEvent me)
    {     
    }
    public void mouseReleased(MouseEvent me)
    {   
    }
    public void mouseMoved(MouseEvent me)
    {
        boolean contain1;
        int mx,my;
        gg=(Graphics2D)l.getGraphics();         
        gg.setColor(new Color(255,0,0) );
        gg.fillPolygon(pp1);

        mx = me.getX();
        my = me.getY();

        //check if mouse cursor is inside polygon or not
        // do not print anything if next cursor position is in same state
        contain1=pp1.contains(mx,my);
        if (contain1) {
            startHovercurrent = true;
            if(startHovercurrent!=startHoverprev)
                System.out.println("Inside");

            startHoverprev=startHovercurrent;
         } 
         else {
            startHovercurrent = false;
            if(startHovercurrent!=startHoverprev)
                System.out.println("Outside");

            startHoverprev=startHovercurrent;
         }
    }
    public void mouseDragged(MouseEvent me)
    {   
    }
    public void actionPerformed(ActionEvent ae)
    {  
    }   
}

对于此用法,How to Use Tool Tips suggests overriding the getToolTipText() method of the enclosing JComponent. This answer 概述了 JMapViewerChartPanel 的方法。在下面的示例中,getToolTipText() 只是 returns 任何 Shape 的名称,contains() 触发鼠标事件。相比之下,window 底部的 JLabel 通过 setToolTipText().

获得了传统的提示。

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;

/**
 * @see 
 * @see 
 */
public class ShapeToolTip {

    private static class ShapePanel extends JPanel {

        private final List<Shape> list = new ArrayList<>();

        public ShapePanel() {
            Polygon p = new Polygon();
            p.addPoint(500, 100);
            p.addPoint(500, 400);
            p.addPoint(200, 400);
            list.add(p);
            list.add(new Ellipse2D.Double(100, 100, 200, 200));
            ToolTipManager.sharedInstance().registerComponent(this);
        }

        @Override
        public String getToolTipText(MouseEvent e) {
            for (Shape shape : list) {
                if (shape.contains(e.getX(), e.getY())) {
                    return shape.getClass().getName();
                }
            }
            return "Outside";
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.blue);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setStroke(new BasicStroke(2));
            for (Shape shape : list) {
                g2d.draw(shape);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(640, 480);
        }
    }

    private void display() {
        JFrame f = new JFrame("ShapeToolTip");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new ShapePanel());
        JLabel title = new JLabel("Shape Tool Tip", JLabel.CENTER);
        title.setToolTipText("Title");
        title.setFont(title.getFont().deriveFont(Font.BOLD, 24));
        f.add(title, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new ShapeToolTip()::display);
    }
}