这是我之前 question. 的后续问题
我有两个 JPanels
,每个有 5 个 JLabels
。当我将鼠标悬停在其中一个 JLabels
上并按下删除键时,我想打印标签的文本。这是我尝试过的:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class KeybindExample extends JPanel {
public KeybindExample() {
setLayout(new BorderLayout());
add(firstRow(), BorderLayout.NORTH);
add(secondRow(),BorderLayout.SOUTH);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
KeyStroke delKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
String delete = "delete";
inputMap.put(delKeyStroke, delete);
actionMap.put(delete, new DeleteAction());
}
private class DeleteAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent evt) {
PointerInfo pInfo = MouseInfo.getPointerInfo();
Point ptOnScrn = pInfo.getLocation();
int xPanel = getLocationOnScreen().x;
int yPanel = getLocationOnScreen().y;
int x = ptOnScrn.x - xPanel;
int y = ptOnScrn.y - yPanel;
Component component = getComponentAt(x, y);
if (component != null) {
JLabel selectedLabel = (JLabel) component;
System.out.println("Selected Label: " + selectedLabel.getText());
}
}
}
private static JPanel firstRow(){
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
String [] x = {"1","2","3","4","5"};
for(int i = 0; i < 5; i++){
JLabel label = new JLabel(x[i]);
label.setPreferredSize(new Dimension(50,50));
panel.add(label);
}
return panel;
}
private static JPanel secondRow(){
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
String [] x = {"6","7","8","9","10"};
for(int i = 0; i < 5; i++){
JLabel label = new JLabel(x[i]);
label.setPreferredSize(new Dimension(50,50));
panel.add(label);
}
return panel;
}
private static void createAndShowGui() {
KeybindExample mainPanel = new KeybindExample();
JFrame frame = new JFrame("Key Bindings Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
我收到以下错误:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JPanel cannot be cast to javax.swing.JLabel
如果我理解正确的话,我有一个 JPanel
(KeybindExample),它包含两个 JPanel
,而这两个 JPanel
中的每一个包含 JLabels
。因此,当我执行 getComponentAt(x,y) 时,我得到的组件是另一个导致类型转换问题的 JPanel
。
我认为我需要做的是获取 Component At (x,y) 的组件,这将是一个 JLabel
。换句话说,我需要更进一步。我尝试了以下方法,但它仅适用于顶部面板,有时仍会返回相同的错误。
Component component = getComponentAt(x, y);
if (component != null) {
JPanel selectPanel = (JPanel) component;
Component comp = selectPanel.getComponentAt(x,y);
if(comp != null){
JLabel selectLabel = (JLabel) comp;
System.out.println("Selected Label: " + selectLabel.getText());
}
}
}
我怎样才能拥有包含多个 JLabel 的多个 JPanel,但能够让 JLabel 将鼠标悬停在文本上。
最佳答案
关键问题是——如何在某个时间点获取对所需 JLabel 的引用,此时您按下删除键。您当前的解决方案(我之前提出的解决方案)不起作用,因为代码找到了相对于 KeybindExample JPanel 的当前组件,因为这是您调用的组件 getComponentAt()
方法上。一种可能的解决方案是调用 getComponentAt()
在实际持有 JLabel 的 JPanel 上。另一种可能的解决方案是计算鼠标相对于每个 JLabel 的位置,并使用 contains(...)
方法来查看鼠标是否位于 JLabel 之一上。为此,您需要有权访问所有 JLabel,或许可以将它们放在 List<JLabel>
中。 .例如……
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class KeybindExample extends JPanel {
private List<JLabel> labelList = new ArrayList<>();
public KeybindExample() {
setLayout(new BorderLayout());
add(firstRow(), BorderLayout.NORTH);
add(secondRow(), BorderLayout.SOUTH);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
KeyStroke delKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
String delete = "delete";
inputMap.put(delKeyStroke, delete);
actionMap.put(delete, new DeleteAction());
}
private class DeleteAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent evt) {
PointerInfo pInfo = MouseInfo.getPointerInfo();
Point ptOnScrn = pInfo.getLocation();
for (JLabel label : labelList) {
int x = ptOnScrn.x - label.getLocationOnScreen().x;
int y = ptOnScrn.y - label.getLocationOnScreen().y;
if (label.contains(x, y)) {
System.out.println("Selected Label: " + label.getText());
}
}
// int xPanel = getLocationOnScreen().x;
// int yPanel = getLocationOnScreen().y;
// int x = ptOnScrn.x - xPanel;
// int y = ptOnScrn.y - yPanel;
//
// Component component = getComponentAt(x, y);
// if (component != null) {
// JLabel selectedLabel = (JLabel) component;
// System.out.println("Selected Label: " + selectedLabel.getText());
// }
}
}
private JPanel firstRow() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
String[] x = { "1", "2", "3", "4", "5" };
for (int i = 0; i < 5; i++) {
JLabel label = new JLabel(x[i]);
labelList.add(label);
label.setPreferredSize(new Dimension(50, 50));
panel.add(label);
}
return panel;
}
private JPanel secondRow() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
String[] x = { "6", "7", "8", "9", "10" };
for (int i = 0; i < 5; i++) {
JLabel label = new JLabel(x[i]);
labelList.add(label);
label.setPreferredSize(new Dimension(50, 50));
panel.add(label);
}
return panel;
}
private static void createAndShowGui() {
KeybindExample mainPanel = new KeybindExample();
JFrame frame = new JFrame("Key Bindings Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
关于java - 使用 Keybind 和 MouseInfo 获取 Label,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25024996/