Java paint()只调用一次来自paintbAll()

时间:2012-04-13 03:13:25

标签: java canvas jframe jpanel paint

我调用了以下代码:

    while(true){
        view.onTick();

        trySleep(55);
    }

onTick()方法描述如下:

    public void onTick() {
    mainFrame.paintAll(mainFrame.getGraphics());
}

这是我设置JFrame和JPanels等的地方(mainFrame是一个JFrame):

    private void runProgramSetup(){
    JPanel canvas = new JPanel();
    canvas.setLayout(new BoxLayout(canvas, BoxLayout.Y_AXIS));
    mainFrame.getContentPane().add(canvas);

    //create the main game panel
    mapPanel = new MapPanel(model, this);
    mapPanel.setPreferredSize(new Dimension(TOTAL_FRAME_WIDTH, MAP_PANEL_HEIGHT));
    mapPanel.setBackground(Color.cyan);

    //create the menu panel
    menuPanel = new MenuPanel(model, this);
    menuPanel.setLayout(new BoxLayout(menuPanel, 0));
    menuPanel.setPreferredSize(new Dimension(TOTAL_FRAME_WIDTH, MENUS_PANEL_HEIGHT));

    //add the panels to the window
    canvas.add(mapPanel);
    canvas.add(menuPanel);

    //make both panels visible
    mapPanel.setVisible(true);
    menuPanel.setVisible(true);
}

现在这是我的问题。当repaintAll()被调用时,一切都重新绘制了EXCEPT mapPanel的重写绘制(Graphics g)方法:

    @Override
public void paint(Graphics g) {
    transformedImages.transformAndStoreImages(model);
    paintGrid(g);
    paintScenery(g);
    paintElements(g);
    paintDraggedElement(g);
    paintUIOverlay(g);
}

只召唤一次。这就对了。但是,每个其他组件都会继续重新绘制。只绘制一次的mapPanel。这是更奇怪的事情。我在Ubuntu上运行并解决了这个问题。我团队的其他成员在Mac上运行,他们没有这个问题。我能够解决这个问题的唯一方法是用两个绘图调用替换onTick():

    public void onTick() {
    mainFrame.repaint();
    mainFrame.paintAll(mainFrame.getGraphics());
}

这一切对我有用。我需要两个电话。两者都没有。我不喜欢这样做,但显然是因为效率低下..:/ 有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

你应该重写JPanel的

paintComponent(Graphics g)

不画画

答案 1 :(得分:0)

mainFrame.repaint()强制地图刷新的原因是因为repaint()调用repaint(0, 0, 0, width, height),这标志着整个mainFrame的区域被标记为“脏” RepaintManager。这是故意设计的,因为您通常不想重新绘制JFrame中的每个像素来更新组件。所以,在onTick()中,当mainFrame.paintAll()被调用时,我的猜测是mapPanel的区域没有标记为脏,所以RepaintManager跳过它,以便保存处理时间。如果您非常确定每次调用onTick()时都要重新绘制整个mapPanel,最简单的方法是在mapPanel.repaint()方法中调用onTick()。这会将整个mapPanel标记为脏,因此会尽快重绘。此外,如果您的menuPanel只是使用常规摆动JComponents,则无需手动使它们重新绘制,如果您正确使用API​​,它们将在值更改时重新绘制。

我知道这是一个古老的问题,但我想我会回答以防其他人碰到类似的东西。