2011-09-04 59 views
1

在我回到高中之前,我正在创建一个服务器/客户端mmo作为夏季项目,并且我选择使用Reddwarf和swing为我的客户端。我创建了一个扩展(你猜对了)Canvas的GameCanvas对象,并且覆盖了paint方法。自定义画布对象不自动重新绘制

这是我的涂料方法:

/** 
* Base for drawing the map, player, etc. 
*/ 
@Override 
public void paint(Graphics graphics) { 
    graphics.dispose(); 
    if(strat == null) { 
     return; 
    } 
    Graphics2D g = (Graphics2D) strat.getDrawGraphics(); 
    g.drawString(String.valueOf(System.currentTimeMillis()), 200, 200); 
    g.dispose(); 
    strat.show(); 
} 

斯特拉特是两层BufferStrategy中,并从含有的JFrame(其具有许多许多其他组件)被拉

的的GameCanvas也是JPanel的内除了GameCanvas本身以外没有其他内容。

我运行我的程序,我可以看到我现在的时间在millis中,并且结尾有一些乱七八糟的数字,整个JFrame和所有包含的组件都是灰色的并且出了问题。

发生了什么事? O-o我之前用帆布做了很多东西,之前没有发生过这样的事情。 :/

回答

2

如果我不得不猜测发生了什么,我会说你在绘制文本之前没有绘制背景。

你说这是一个Swing问题,但你使用了一个Canvas。 Swing在默认情况下是双缓冲的,我没有理由使用具有缓冲状态的AWT组件。

我从未创建过MMO,但我猜测互联网响应时间将远远低于Swing绘画时间。所以我建议你只需要使用JPanel,如果你需要自定义绘画并重写paintComponent()方法来做绘画。不要忘记在开始时调用super.paintComponent()。

+0

不幸的是,这仍然不能解决问题。我在面板上设置了边框,并且完全按照您所描述的方式进行操作并不能解决问题。它绘制了绘图的第一个“循环”,然后再也不会重绘。 –

+0

@BitCrash,另外,由于面板需要使用该对象来绘制边框,所以在方法的开始处处理Graphics对象并没有任何意义。 – camickr

2

你知道你在做什么没有任何意义吗?

油漆画布您绘制您(您STRAT),而不是在画布上。

忘记BufferStrategy而不是创建它,然后画到各自的组件,让JFrame担心处理双缓冲。

/** 
* Base for drawing the map, player, etc. 
*/ 
@Override 
public void paint(Graphics graphics) { 
    Graphics g = graphics.create(); 
    g.drawString(String.valueOf(System.currentTimeMillis()), 200, 200); 
    g.dispose(); 
} 

我也同意camickr在画布是不是最好的东西来绘制,使用JPanel。我知道,如果你只看类的名字就没有什么意义,但它确实能够更好地发挥作用。

此外,它不会重新绘制,除非您给它一个重绘的理由。尝试从您的游戏主题中调用myJFrame.repaint();


这是一个SSCCE工作正常。

这就是为什么SSCCE很重要。我不得不做出假设,当我将你的pastebin片段放入其中时,没有任何问题,所以我不能就如何解决问题给出建设性的建议。

import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class DrawFrame extends JFrame { 
    DrawPanel drawPanel; 
    static boolean running = false; 
    public DrawPanel getDrawPanel() { return drawPanel; } 

    public DrawFrame() { 
     drawPanel = new DrawPanel(); 
     add(drawPanel); 
    } 

    public static void main(String[] args) { 
     final DrawFrame mainGui = new DrawFrame(); 
     final DrawPanel drawPanel = mainGui.getDrawPanel(); 

     Timer timer = new Timer(0, new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       mainGui.setSize(300, 200); 
       mainGui.setVisible(true); 
       mainGui.createBufferStrategy(2); 
       running = true; 
      } 
     }); 
     timer.setRepeats(false); 
     timer.start(); 

     while (true && (!running || mainGui.isVisible())) { 
      drawPanel.repaint(); 
     } 
    } 

    public class DrawPanel extends JPanel { 

     @Override 
     public void paintComponent(Graphics graphics) { 
      super.paintComponent(graphics); 
      Graphics g = graphics.create(); 
      g.drawString(String.valueOf(System.currentTimeMillis()), 100, 100); 
      g.dispose(); 
     } 
    } 

} 
+0

其实我不知道甚至有可能画到JPanel,我从来没有尝试过。我使用JPanel获得了更好的结果,并且它正确地绘制了所有内容,但它只绘制一次,然后不刷新。当我使用JPanel时,是否需要修改某些内容? –

+0

如果您可以发布[SSCCE](http://sscce.org/),它可以帮助我们指出您做错了什么。 –

+0

我的整个drawpanel以及我暗示它的方式都在这个pastebin中:http://pastebin.com/apUadmnc Im在这里一无所获,我从来没有遇到过这样的问题。 :/ –