Java 使用键绑定和鼠标信息获取标签
这是我上一次提问的后续问题 我有两个Java 使用键绑定和鼠标信息获取标签,java,swing,jpanel,jlabel,key-bindings,Java,Swing,Jpanel,Jlabel,Key Bindings,这是我上一次提问的后续问题 我有两个jpanel,每个都有5个jlabel。当我将鼠标放在其中一个jlabel上并按delete键时,我想打印标签文本。以下是我尝试过的: import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.MouseInfo; import java.awt.Point; im
jpanel
,每个都有5个jlabel
。当我将鼠标放在其中一个jlabel
上并按delete键时,我想打印标签文本。以下是我尝试过的:
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();
}
});
}
}
如果我理解正确,我有一个JPanel
(KeybindExample),它包含两个JPanel
,这两个JPanel
都包含jlabel
。因此,当我使用getComponentAt(x,y)时,我得到的组件是另一个JPanel
,这导致了类型转换的问题
我认为我需要做的是在(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。关键问题是——如何在某个时间点(这里是按delete键时)获取对所需JLabel的引用。您当前的解决方案(我之前提出的解决方案)不起作用,因为代码找到了相对于KeybindExample JPanel的当前组件,因为这是您正在调用getComponentAt()
方法的组件。一种可能的解决方案是在实际包含JLabel的JPanel上调用getComponentAt()
。另一种可能的解决方案是计算鼠标相对于每个JLabel的位置,并使用contains(…)
方法查看鼠标是否位于其中一个JLabel上。要做到这一点,您需要访问所有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.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.MouseInfo;
导入java.awt.Point;
导入java.awt.PointerInfo;
导入java.awt.event.ActionEvent;
导入java.awt.event.KeyEvent;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.*;
@抑制警告(“串行”)
公共类KeybindExample扩展了JPanel{
私有列表标签列表=新的ArrayList();
公钥绑定示例(){
setLayout(新的BorderLayout());
添加(firstRow(),BorderLayout.NORTH);
添加(secondRow(),BorderLayout.SOUTH);
int condition=JComponent.WHEN在聚焦窗口中;
InputMap InputMap=getInputMap(条件);
ActionMap ActionMap=getActionMap();
KeyStroke delKeyStroke=KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0);
String delete=“delete”;
inputMap.put(delKeyStroke,delete);
put(delete,newdeleteAction());
}
私有类DeleteAction扩展了AbstractAction{
@凌驾
已执行的公共无效操作(操作事件evt){
PointerInfo pInfo=MouseInfo.getPointerInfo();
点ptOnScrn=pInfo.getLocation();
用于(JLabel标签:labelList){
int x=ptOnScrn.x-label.getLocationOnScreen().x;
int y=ptOnScrn.y-label.getLocationOnScreen().y;
if(标签包含(x,y)){
System.out.println(“所选标签:+Label.getText());
}
}
//int xPanel=getLocationOnScreen().x;
//int yPanel=getLocationOnScreen().y;
//intx=ptOnScrn.x-xPanel;
//int y=ptOnScrn.y-yPanel;
//
//组件=getComponentAt(x,y);
//如果(组件!=null){
//JLabel selectedLabel=(JLabel)组件;
//System.out.println(“所选标签:+selectedLabel.getText());
// }
}
}
私有JPanel firstRow(){
JPanel面板=新的JPanel(新的FlowLayout(FlowLayout.LEFT));
字符串[]x={“1”、“2”、“3”、“4”、“5”};
对于(int i=0;i<5;i++){
JLabel标签=新的JLabel(x[i]);
标签列表。添加(标签);
label.setPreferredSize(新尺寸(50,50));
面板。添加(标签);
}
返回面板;
}
私人JPanel secondRow(){
JPanel面板=新的JPanel(新的FlowLayout(FlowLayout.LEFT));
字符串[]x={“6”、“7”、“8”、“9”、“10”};
对于(int i=0;i<5;i++){
JLabel标签=新的JLabel(x[i]);
标签列表。添加(标签);
label.setPreferredSize(新尺寸(50,50));
面板。添加(标签);
}
返回面板;
}
私有静态void createAndShowGui(){
KeybindExample主面板=新建KeybindExample();
JFrame=newjframe(“键绑定示例”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(主面板);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}
关键问题是——当按下delete键时,如何在特定时间点获取对所需JLabel的引用。您当前的解决方案(我之前提出的解决方案)不起作用,因为代码找到了相对于KeybindExample JPanel的当前组件,因为这是您正在调用getComponentAt()
方法的组件。一种可能的解决方案是在实际包含JLabel的JPanel上调用getComponentAt()
。另一种可能的解决方案是计算鼠标相对于每个JLabel的位置,并使用contains(…)
方法查看鼠标是否位于其中一个JLabel上。要做到这一点,您需要访问所有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.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.FlowLayout;
我