当前位置: 代码迷 >> java >> 绘画组件似乎导致标签的光标和鼠标侦听器不起作用
  详细解决方案

绘画组件似乎导致标签的光标和鼠标侦听器不起作用

热度:98   发布时间:2023-07-31 11:09:29.0

使用LayerUI将标签添加到选项卡式窗格的右上角。 想要允许这些标签显示为超链接,因此我将颜色设置为蓝色,将光标设置为手,并添加了mouselistener

但是,当我绘制组件时,光标自定义和鼠标侦听器无法正常工作。

样本图片

样例应用:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.LayerUI;

public class TopRightCornerLabelLayerUITest {
    public static JPanel makeUI() {
        JPanel resultPanel = new JPanel();
        resultPanel.setLayout( new BorderLayout());
        resultPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add("Tab 1", new JPanel());  
        tabbedPane.add("Tab 2", new JPanel());  

        resultPanel.add(new JLayer<JComponent>(tabbedPane, new TopRightCornerLabelLayerUI()), BorderLayout.CENTER);

        return resultPanel;
    }

    private static void initandShow()
    {
        JDialog dialog = new JDialog();
        dialog.getContentPane().add(makeUI());
        dialog.setSize(520, 240);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                initandShow();
            }
        });

    }
}

class TopRightCornerLabelLayerUI extends LayerUI<JComponent> {
    private JPanel rubberStamp = new JPanel();

    @Override public void paint(Graphics g, JComponent c) {
        super.paint(g, c);

        JLabel layoutHyperlink = new JLabel("<html><a href=''>File Layout and Descriptions</a></html>");
        JLabel templateHyperlink = new JLabel("<html><a href=''>Download Template</a></html>");

        layoutHyperlink.setForeground(Color.BLUE.darker());
        layoutHyperlink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        layoutHyperlink.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // the user clicks on the label
                System.err.println("clicked");
            }
       });

        templateHyperlink.setForeground(Color.BLUE.darker());
        templateHyperlink.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        templateHyperlink.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                // the user clicks on the label
                System.err.println("clicked");

            }
       });

        // Add components
        Dimension templateDimension = templateHyperlink.getPreferredSize();
        int x = c.getWidth() - templateDimension.width - 5;
        SwingUtilities.paintComponent(g, templateHyperlink, rubberStamp, x, 2, templateDimension.width , templateDimension.height);

        Dimension layoutDimension = layoutHyperlink.getPreferredSize();
        x = c.getWidth() - layoutDimension.width - 15 - templateDimension.width;
        SwingUtilities.paintComponent(g, layoutHyperlink, rubberStamp, x, 2, layoutDimension.width, templateDimension.height);

    }
}

在阅读您的问题之前,我实际上并不知道JLayer类。 我没有完整的答案,但我认为这足以使您朝正确的方向前进。 Oracle Java教程中的课程为我提供了帮助: 。 该课程的一节名为“ 响应事件” ,它帮助我弄清楚了如何部分解决您的问题。 基本上,您只是在绘制标签,而没有将它们实际添加为组件,因此它们不会响应鼠标事件。 由于标记可以被认为是部分JLayer 添加的成分组成,可以配置JLayer以响应鼠标事件。 如本教程课程所述,您需要在TopRightCornerLabelLayerUI类中覆盖其他一些方法。 下面的代码包含其中两个方法。 将它们添加到您的代码中,看看它们是否能给您预期的结果。

public void installUI(JComponent c) {
    super.installUI(c);
    ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
}

protected void processMouseEvent(MouseEvent e, JLayer l) {
    if (e.getID() == MouseEvent.MOUSE_CLICKED) {
        Point pt = e.getPoint();
        if (pt.x >= xTemplateHyperlink  &&  pt.x <= (xTemplateHyperlink + widthTemplateHyperlink)) {
            System.out.println("clicked");
        }
    }
}

编辑:忘记提及我将以下成员添加到您的TopRightCornerLabelLayerUI类中...

private int xTemplateHyperlink;
private int yTemplateHyperlink;
private int widthTemplateHyperlink;
private int heightTemplateHyperlink;

像这样在方法paint()设置它们的值...

Dimension templateDimension = templateHyperlink.getPreferredSize();
xTemplateHyperlink = c.getWidth() - templateDimension.width - 5;
yTemplateHyperlink = 2;
widthTemplateHyperlink = templateDimension.width;
heightTemplateHyperlink = templateDimension.height;

解释了processMouseEvent()方法中的代码。

  相关解决方案