2011-09-04 87 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在這裏一無所獲,我從來沒有遇到過這樣的問題。 :/ –