问题
I am using a JFrame
to set up a game of Solitaire, using Cards that extend JLabel
so that they can be dragged around the screen. However, one of my requirements is that I be able to double click a card and it snaps up to the 4 stacks of aces. This is not a problem. what is causing problems is that I set this up in an array, so that the aces would go to the spot that corresponds with the suit of the ace, then I have the spots rearrange if a card is dragged up there. If it is double clicked, the aces must go to the first spot (from the left) then the second, and so on. I had planned to use getComponentAt()
to find out what was at the first spot and if I could place the ace there, if not then i move on to the second and so on. For some reason though, even if I hard code in the parameters into getComponentAt()
to spots I know have a component, it is still returning null.
this is the relevant portion of my code:
Container contentPane = getContentPane();
contentPane.setLayout(null);
...
for(int i = 0; i < 4; i++)
{
aces[i] = new Card();
aces[i].setBounds((i * 75) + 475, 25, 75, 100);
contentPane.add(aces[i]);
aces[i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
aces[i].setSuit(i + 1);
}
System.out.println(contentPane.getComponentAt(475, 25));
This is returning null
every time, no matter where in the component i put the coordinates.
Any explanations?
*Updated SSCCE: This is the main class, solitaire:
import java.util.*;
import javax.swing.*;
import java.awt.*;
public class Solitaire extends JFrame
{
private Container contentPane;
private Card aces[];
public static void main(String args[])
{
Solitaire frame = new Solitaire();
frame.setVisible(true);
}
public Solitaire()
{
super();
contentPane = getContentPane();
contentPane.setLayout(null);
contentPane.setBackground(Color.GREEN.darker().darker());
setTitle("Solitaire");
setSize(800,800);
setResizable(false);
setLocation(250, 50);
setDefaultCloseOperation(EXIT_ON_CLOSE);
play();
}
public void play()
{
contentPane.removeAll();
aces = new Card[4];
for(int i = 0; i < 4; i++)
{
aces[i] = new Card(0,i + 1);
aces[i].setBounds((i * 75) + 475, 25, 75, 100);
contentPane.add(aces[i]);
aces[i].setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
}
for(int i = 0; i < contentPane.getComponents().length; i++)
System.out.println(contentPane.getComponents()[i]);
System.out.println(contentPane.getComponentAt(475, 25));
repaint();
}
}
and this is Class Card:
import javax.swing.*;
public class Card extends JLabel
{
private int numb;
private int value;
private int suit;
public Card(int n, int s)
{
super();
numb = n;
suit = s;
}
}
This ran for me, comment if you need more to solve the problem.
回答1:
There are lots of problems with using getComponentAt
The first is, the parent container must actually be realized and sized. If not, it will return null
. The method is capable of returning the container itself if no children exist at the location.
I then child Component#contains
to test to see if the given point feel within the child components directly, but this wants the point to be translated into the child's coordinate space...
So instead, I simply went straight to getBounds
...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Point;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestComponentLocation {
public static void main(String[] args) {
new TestComponentLocation();
}
public TestComponentLocation() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.pack();
frame.setLocationRelativeTo(null);
Container contentPane = frame.getContentPane();
contentPane.setLayout(null);
for (int i = 0; i < 4; i++) {
JPanel panel = new JPanel();
panel.setBounds((i * 75) + 475, 25, 75, 100);
System.out.println(panel.getBounds());
contentPane.add(panel);
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 3));
}
System.out.println(getComponentAt(contentPane, new Point(475, 25)));
System.out.println(getComponentAt(contentPane, new Point(100, 25)));
frame.setVisible(true);
}
});
}
public Component getComponentAt(Container parent, Point p) {
Component comp = null;
for (Component child : parent.getComponents()) {
if (child.getBounds().contains(p)) {
comp = child;
}
}
return comp;
}
}
来源:https://stackoverflow.com/questions/16074116/getcomponentat-not-finding-a-component