java - 绘制组件似乎导致光标和标签的鼠标侦听器不起作用
问题描述
用于将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
作为组件添加的组件的一部分,因此您可以配置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()
。
推荐阅读
- spring-boot - 无法加载类 javax.xml.ws.Service
- java - @CacheResult 与 Panache 存储库
- jenkins - 如何将 Jenkins Artifacts 位置更改为另一个驱动器?
- python - 当 Selenium 中的相同元素应该遍历所有元素时,代码会对其进行迭代
- node.js - 将 sql server 转换为 jsom 的数据库语法问题
- javascript - 循环到前 15 分钟 javascript
- visual-studio-code - VS Code - 在两个文件中搜索两个不同的东西
- react-admin - 在操作列和每一行中添加图标 - 反应管理员
- asp.net-core - System.Diagnostics.Trace.TraceError 调用的应用服务日志记录
- android-studio - 立式圆柱android studio