getComponentAt()没有找到组件?

时间:2013-04-18 03:45:20

标签: java swing jframe contentpane

我正在使用JFrame设置纸牌游戏,使用扩展JLabel的卡片,以便可以在屏幕上拖动它们。但是,我的一个要求是我可以双击一张卡片,它可以快速连接到4个A盘。这不是问题。造成问题的原因是我把它设置在一个数组中,这样aces会到达与ace的套装相对应的位置,然后如果卡被拖到那里,我会重新排列。如果双击,则A必须转到第一个点(从左侧)然后转到第二个点,依此类推。我本来打算用getComponentAt()找出第一个位置的内容,如果我可以将ace放在那里,如果没有,那么我继续前进到第二个等等。但是出于某些原因,即使我将参数硬编码到getComponentAt()到我知道有一个组件的点,它仍然返回null。

这是我的代码的相关部分:

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));

每次都返回null,无论我在组件的哪个位置放置坐标。 有什么解释吗?

*更新了SSCCE: 这是主要类,单人纸牌:

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();
    }
}

这是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;
    }
}

如果你需要更多来解决这个问题的话,这就适合我。

1 个答案:

答案 0 :(得分:3)

使用getComponentAt

时遇到很多问题

首先,必须实际实现父容器的大小。如果没有,它将返回null。如果该位置不存在子项,则该方法能够返回容器本身。

然后我的孩子Component#contains进行测试以查看给定点是否直接感受到子组件内部,但是这需要将该点转换为子的坐标空间......

相反,我只是直接进入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;
    }
}