自定义JComponent未添加到JPanel

时间:2014-03-12 20:05:25

标签: java swing jcomponent

对于我认为非常简单的问题,我有点坚持不懈。

我有一个自定义的JComponent Ball,它只不过是一个简单的椭圆形。我试图将球添加到JPanel,我已将其设置为JFrame的默认内容窗格(通过frame.setContentPane(mainPanel))。除了球,我还有另外两个类Paddle的组件,我创建了另一个自定义JComponent。奇怪的是,桨可以添加得很好。

有问题的小组故意使用绝对布局来定位元素,因为这应该是Pong游戏的简单再现。

我在将球和两个拨片添加到JPanel后运行了一个简单的测试,发现组件数组只返回了两个:paddles。添加所有这些并初始化JPanel和JFrame的完整代码如下:

public Pong()
{
    frame = new JFrame("Pong");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    mainPanel = new JPanel(null);

    mainPanel.setBackground(Color.black);
    mainPanel.setPreferredSize(new Dimension(500, 500));

    player = new Paddle(20, 100);
    enemy = new Paddle(20, 100);
    ball = new Ball(5, Color.GREEN);

    mainPanel.add(player);
    mainPanel.add(enemy);
    mainPanel.add(ball);
    enemy.setColor(Color.RED);

    frame.setContentPane(mainPanel);
    frame.pack();

    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    int x = screen.width/2 - frame.getWidth()/2;
    int y = screen.height/2 - frame.getHeight()/2;
    frame.setLocation(x, y);

    mainPanel.addKeyListener(mc);

    frame.setVisible(true);

    mainPanel.repaint();

    x = mainPanel.getWidth()/2 - ball.getWidth()/2;
    y = mainPanel.getHeight()/2 - ball.getHeight()/2;
    System.out.println("X: " + x + ", Y: " + y);
    ball.setLocation(x, y);

    x = 0;
    y = mainPanel.getHeight()/2 - player.getHeight()/2;
    System.out.println("X: " + x + ", Y: " + y);
    player.setLocation(x, y);

    x = mainPanel.getWidth() - enemy.getWidth();
    y = mainPanel.getHeight()/2 - enemy.getHeight()/2;
    System.out.println("X: " + x + ", Y: " + y);
    enemy.setLocation(x, y);

    System.out.println(Arrays.deepToString(mainPanel.getComponents()));

    mainPanel.repaint();

    frame.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mousePressed(MouseEvent e)
        {
            mainPanel.requestFocus();
        }
    });

    dm.start();
    mainPanel.requestFocus();
}

球的代码如下[注意:球是私有的,因为它是类Pong的内部类,它不会扩展任何东西]:

private class Ball extends JComponent
{
    private int radius;
    private Color color;

    public Ball(int size, Color c)
    {
        if(size > 0)
            radius = size;
        else
            radius = 1;
        this.setPreferredSize(new Dimension(radius, radius));
        color = c;
    }

    public Ball(int size)
    {
        this(size, Color.RED);
    }

    //Getters and Setters...

    @Override
    public void paintComponent(Graphics g)
    {
        System.out.println("Radius: " + radius);
        g.setColor(color);
        g.fillOval(0, 0, radius, radius);
    }
}

这不是我在处理项目时第一次遇到此问题,而且当我使用自定义JComponents以及JPanel上的绝对定位时,似乎总是会出现这种情况,尽管还有其他项目,我似乎没有这个问题。这可能是我忽略的非常简单的东西,但我无法想到它是什么,对我来说是生活。任何答案都将不胜感激。

如果绝对必要,all the lines of code for this project can be found here(总共超过300行)。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

使用null布局向面板添加组件时,您负责设置组件的sizelocation

如果你没有设置大小,那么它将为零,因此没有任何东西可以绘画。

答案 1 :(得分:0)

解决方案很愚蠢。

在Ball类中添加以下调用构造函数和setRadius方法:

this.setSize(new Dimension(radius, radius));

一切都应该好。基本上,首选大小不会强制执行,因此要明确:设置大小。否则,重新绘制JPanel时,此组件的大小为0并被跳过。

(根据评论编辑,谢谢,我的Swing生锈了)