This is a follow up question from my previous question.
I have two JPanels
that have 5 JLabels
each. When I hove the mouse over one of the JLabels
and press the delete key, I want to print the label's text. Here is what I have tried:
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();
}
});
}
}
I get the following Error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JPanel cannot be cast to javax.swing.JLabel
If I'm understanding this correctly, I have a JPanel
(KeybindExample) that contains two JPanels
, and each of those two JPanels
contain JLabels
. Therefore, when I do getComponentAt(x,y) the component I'm getting is another JPanel
which is causing the issue with the typecasting.
What I believe I need to do is to get the Component At (x,y)'s component, which would be a JLabel
. In other words I need to go one step further. I tried the following, but it only worked for the top panel, and sometimes still returned the same error.
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());
}
}
}
}
How can I have multiple JPanels that contain multiple JLabels but be able to have the JLabel that has the mouse hovered over's text.