我调用了以下代码:
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());
}
这一切对我有用。我需要两个电话。两者都没有。我不喜欢这样做,但显然是因为效率低下..:/ 有什么想法吗?
谢谢!
答案 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,它们将在值更改时重新绘制。
我知道这是一个古老的问题,但我想我会回答以防其他人碰到类似的东西。