简体   繁体   English

Java paint()仅从paintAll()调用一次

[英]Java paint() Only Called Once From paintAll()

I have the following code being called: 我有以下代码被调用:

    while(true){
        view.onTick();

        trySleep(55);
    }

The onTick() method is described as such: onTick()方法的描述如下:

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

Here is where I set up my JFrame and JPanels etc (mainFrame is a JFrame): 这是我设置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);
}

Now here is my problem. 现在这是我的问题。 Everything repaints when repaintAll() is called EXCEPT mapPanel's overridden paint(Graphics g) method: 当repaintAll()称为mapPanel的覆盖paint(Graphics g)方法时,所有东西都会重新绘制:

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

It is only called once. 它仅被调用一次。 That is it. 这就对了。 However, every other component continues to repaint. 但是,所有其他组件继续重绘。 It is only mapPanel that paints once. 仅mapPanel绘制一次。 Here is what is even more strange. 这是更奇怪的地方。 I am running on Ubuntu and get this problem. 我在Ubuntu上运行并遇到此问题。 The rest of my team is running on Macs and they do not have this problem. 我团队的其余成员都在Mac上运行,他们没有这个问题。 The only way I have been able to solve this is to replace onTick() with two paint calls: 我能够解决此问题的唯一方法是用两个绘画调用替换onTick():

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

This is all that has worked for me. 这就是为我工作的全部。 I need both calls. 我需要两个电话。 Neither works alone. 两者都不行。 I don't like doing this though obviously because of inefficiency.. :/ Any ideas? 我显然不喜欢这样做,因为效率低下..:/有什么想法吗?

Thanks! 谢谢!

you should be overriding JPanel's 你应该重写JPanel的

paintComponent(Graphics g)

not paint 不上漆

The reason mainFrame.repaint() forces the map to refresh is because repaint() calls repaint(0, 0, 0, width, height) , which marks the entire mainFrame 's area to be marked as "dirty" for the RepaintManager . mainFrame.repaint()强制刷新地图的原因是因为repaint()调用repaint(0, 0, 0, width, height) ,这将整个mainFrame的区域标记为RepaintManager标记为“脏”。 This is designed this way on purpose, because you usually do not want to repaint every pixel in the JFrame just to update a component. 这是有意设计的,因为您通常不希望为更新组件而重新绘制JFrame中的每个像素。 So, in onTick() , when mainFrame.paintAll() is being called, my guess is that the mapPanel 's area has not been marked dirty, so the RepaintManager skips it, to save processing time. 因此,在onTick() ,当调用mainFrame.paintAll()时,我的猜测是mapPanel的区域尚未标记为脏,因此RepaintManager跳过了该区域,以节省处理时间。 If you are very sure that you want to repaint the whole mapPanel every time onTick() is called, the simplest way would be to call mapPanel.repaint() inside of your onTick() method. 如果您确定每次调用onTick()都希望重新绘制整个mapPanel,则最简单的方法是在onTick()方法内部调用mapPanel.repaint() This will mark the whole mapPanel as dirty so it will be redrawn asap. 这会将整个mapPanel标记为脏,因此将尽快重绘。 Also, if your menuPanel is just using regular swing JComponents, you don't need to manually cause them to repaint, they will be repainted when their values change, if you are using the API correctly. 另外,如果您的menuPanel仅使用常规的swing JComponents,则无需手动使它们重新绘制,如果正确使用API​​,则它们的值更改时将重新绘制它们。

I know this is a kind of old question, but I figured I'd answer in case anyone else runs into something similar. 我知道这是一个古老的问题,但是我想我会回答,以防其他人遇到类似问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM