当将图形添加到JPanel,然后将其添加到JFrame时,图形未显示出来。

3
我正在为我的计算机科学课程创建一款桥梁过河游戏,我们需要创建问题的图形表示。图形表示是由BridgeCanvas类绘制的。这个类继承了Canvas类,而Canvas类又继承自JComponent类。
我知道BridgeCanvas正确地绘制了图形,因为当我直接将一个BridgeCanvas对象添加到JFrame中时,它能正确地显示出来。但是,当我先将BridgeCanvas放入一个JPanel中,然后再将它添加到JFrame中时,它就不会显示出来(我只得到一个空白的框架)。我的一个同学说这可能是因为我使用的是Mac电脑。另外,我是在NetBeans中进行这项工作。
以下是BridgeCanvas类(main方法也包含在此类中):
public class BridgeCanvas extends Canvas {

// Initializes the background, river, bridge, and character graphics    
public BridgeCanvas(State state) {
    super(state);

    background = new RoundRectangle2D.Double(0, 0, 400, 400, 40, 40);

    bridge = new GeneralPath();
    bridge.moveTo(100, 175);
    bridge.curveTo(200, 120, 200, 120, 300, 175);
    bridge.lineTo(300, 225);
    bridge.curveTo(200, 170, 200, 170, 100, 225);
    bridge.closePath();

    river = new GeneralPath();
    river.moveTo(150, 0);
    river.curveTo(50, 100, 150, 200, 150, 200);
    river.curveTo(225, 300, 150, 400, 150, 400);
    river.lineTo(250, 400);
    river.curveTo(325, 300, 250, 200, 250, 200);
    river.curveTo(150, 100, 250, 0, 250, 0);
    river.closePath();

    AffineTransform transform = new AffineTransform();
    transform.setToTranslation(25, 25);

    // generateShapeFromText is method used to create shapes from numbers.

    P1 = (GeneralPath) generateShapeFromText(new Font(Font.MONOSPACED, Font.BOLD, 32), "P1");
    P1 = (GeneralPath) P1.createTransformedShape(transform);
    P2 = (GeneralPath) generateShapeFromText(new Font(Font.MONOSPACED, Font.BOLD, 32), "P2");
    transform.setToTranslation(25, 100);
    P2 = (GeneralPath) P2.createTransformedShape(transform);
    FL = (GeneralPath) generateShapeFromText(new Font(Font.MONOSPACED, Font.BOLD, 32), "F");
    P5 = (GeneralPath) generateShapeFromText(new Font(Font.MONOSPACED, Font.BOLD, 32), "P5");
    P10 = (GeneralPath) generateShapeFromText(new Font(Font.SANS_SERIF, Font.BOLD, 32), "P10");


}

public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    super.paintComponent(g); 
    g2.setFont(new Font(Font.MONOSPACED, Font.BOLD, 32));
    BridgeState state = (BridgeState) getState();

    g2.setColor(new Color(0, 140, 0));
    g2.fill(background);
    g2.setColor(new Color(0, 0, 200));
    g2.fill(river);
    g2.setColor(new Color(169, 69, 19));
    g2.fill(bridge);
    g2.setColor(Color.BLACK);
    g2.fill(P1);
    g2.fill(P2);

}


private RoundRectangle2D.Double background;
private GeneralPath bridge;
private GeneralPath river;
private GeneralPath P1;
private GeneralPath P2;
private GeneralPath FL;
private GeneralPath P5;
private GeneralPath P10;

public static void main(String[] args) {
    JFrame frame = new JFrame();
    BridgeState state = new BridgeState(Position.WEST, Position.WEST, Position.WEST, Position.WEST, Position.WEST, 0);
    BridgeCanvas canvas = new BridgeCanvas(state);
    JComponent panel = new JPanel();
    panel.add(canvas);
    panel.setLayout(new FlowLayout());
    panel.setOpaque(false);
    panel.setSize(new Dimension(440, 440));

    frame.setPreferredSize(new Dimension(440, 440));
    frame.add(panel);

    frame.setVisible(true);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}
1个回答

3
请查看您的 BridgeCanvas 对象的大小。如果将其添加到 JPanel 上并且 JPanel 使用其默认的 FlowLayout,则 JComponent 导出对象的大小最多为 1x1 像素,因此即使已创建、添加和显示,也不会显示任何有价值的内容。
事实上,可以通过(暂时)在 BridgeCanvas 的 paintComponent(...) 方法中添加 getSize() 方法进行轻松测试,只有在对象被显示时才会调用该方法:
public void paintComponent(Graphics g) {

    // TODO: delete line below!
    System.out.println("BridgeCanvas Size: " + getSize());

    Graphics2D g2 = (Graphics2D) g;
    super.paintComponent(g); 
    g2.setFont(new Font(Font.MONOSPACED, Font.BOLD, 32));

    // .... etc...

}

一种可能的解决方案:覆盖 BridgeCanvas 的 getPreferredSize() 方法,并返回一个包含您希望其实际大小的 Dimension。
注意:您将要避免对任何东西调用 setSize(),并且还要避免(根据 Swing 专家 Jeanette/kleopatra 的notes)调用 setPreferredSize(),因为这个设置可以被使用您的 BridgeCanvas 对象的代码更改。

@BrandonPaulsen:不客气!祝你的项目好运。看起来非常有趣。 - Hovercraft Full Of Eels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接