【问题标题】:Java JPanel paintComponent(Graphics g) not called未调用 Java JPanel paintComponent(Graphics g)
【发布时间】:2013-11-18 06:02:53
【问题描述】:

我有一个 JPanel,它的 paintComponent(Graphics g) 方法没有被调用。我知道这是一个常见问题,但到目前为止我发现的任何建议都无法解决它。这是 JPanel 的代码:

import javax.swing.*;
import java.awt.*;

public class Grid extends JPanel

{
    Candy[][] gridRep = new Candy[8][8];
    public Grid()

    {
        this.setLayout(new GridLayout(8,8));
        this.populateRandom();
        this.repaint();
    }

    ...

    public void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        for (int r = 0; r<8; r++){
            for (int c = 0; c<8; c++){
                g2.setColor(gridRep[r][c].getColor());
                g2.drawOval(getXCoordinate(gridRep[r][c])*15, getYCoordinate(gridRep[r][c])*15, 10, 10);
                System.out.println("repainting");
            }
        }
    }

}

如您所见,我在构造函数中调用了 repaint(),但它什么也没做。我还在创建此类对象的 JFrame 类中随意调用它:

import javax.swing.*;
import java.awt.*;

public class Game
{
    private Grid grid;
    private JFrame frame;
public Game(){
this.makeFrame();
}

private void makeFrame(){
    grid = new Grid();
    frame = new JFrame ("Frame");
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new FlowLayout());
    //grid.paint(grid.getGraphics());
    grid.repaint();
    frame.add(grid);
    grid.repaint();
    frame.pack();
    grid.repaint();
    frame.setVisible(true);
    grid.repaint();
}

【问题讨论】:

  • 在Swing中绘画是一个复杂的方法类链,必须调用super.paintXxx否则会遇到随机且难以重复绘画的问题。更多详情请关注Painting in AWT and Swing

标签: java swing graphics jpanel paintcomponent


【解决方案1】:

如你所见,我在构造函数中调用了 repaint(),但什么也没做

您不需要调用 repaint()。 Swing 将决定何时需要重新绘制。

无论如何,在这种情况下它什么都不做,因为组件还没有被添加到 GUI 中。

 contentPane.setLayout(new FlowLayout());

您正在使用符合组件大小的 FlowLayout。您在其中进行绘画的自定义组件没有首选大小,因此其大小为 (0, 0),因此无需绘画。

重写getPreferredSize() 方法以返回组件的大小。看起来每个网格都是 (15, 15),所以你应该使用:

@Override Dimension getPreferredSize()
{
    return new Dimension(120, 120);
}

当然,最好为您的类定义变量以包含网格大小和网格数量,而不是在代码中硬编码 8 和 15。

【讨论】:

    【解决方案2】:

    您遇到了布局问题。您正在使用 FlowLayout 并添加一个 preferredSize 为 0,0 的组件。要么使用 BorderLayout 要么给 Grid 一个获取首选大小的方法:

    public Dimension getPreferredSize() {
       return new Dimension(somethingWidth, somethingHeight);
    }
    

    【讨论】:

      【解决方案3】:

      你错过了这一行:

      super.paintComponent(g);
      

      【讨论】:

      • 这是很好的建议,会引起问题,但不是问题的根本原因......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      相关资源
      最近更新 更多