1

我正在使用 aJFrame设置纸牌游戏,使用扩展的卡片,JLabel以便可以在屏幕上拖动它们。但是,我的一个要求是我能够双击一张牌,它可以捕捉到 4 叠 A。这不是问题。造成问题的原因是我将它设置在一个数组中,以便 A 会到达与 A 的花色相对应的位置,然后如果将一张牌拖到那里,我会重新排列这些位置。如果双击,则 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();
    }
}

这是班级卡:

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

这是为我运行的,如果您需要更多来解决问题,请发表评论。

4

1 回答 1

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;
    }
}
于 2013-04-18T04:10:47.007 回答