2016-07-25 6 views
0

私はカスタムJLayeredPaneを持っています。私はゲームのループでそれを再ペインティングしています。 JLayeredPaneには2つのカスタムJPanelが追加されています。これらは、前景と背景のJPanelです。フォアグラウンドJPanelを絶えず更新し続けながら、システムリソースへの影響を減らすために、バックグラウンドJPanelを一度しか描画しないでください(ウィンドウがサイズ変更されたときや他の理由で再描画する方法)。バックグラウンドJPanelを一度正しく描画し、フォアグラウンドJPanelを常に更新する方法はありますか?

繰り返しを繰り返すには、バックグラウンドのJPanelをループで常に再描画したくありません。背景が変わらないので、私はそれが必然的であるときだけそれを再塗りたい。大きいです。

私の試みでは、私はバックグラウンドを一度しか描いていません。しかしながら。背景JPanelは単に表示されません。フォアグラウンドJPanelは通常どおりに更新されます。 JPanelの背景をJPanelで塗りつぶすのとほぼ同じです。JPanelsを両方とも設定していますが、setOpaque(false)

私は、背景をJPanelで描画しようとしています。フォアグラウンドJPanelは絶えず前景です。

私のコードの問題は、背景JPanelが表示されないことです。

今すぐ。もし私がそれを絶えず描くならば、それは明らかになるだろう。しかし、それは私がやろうとしていることの目的を破るものです。私はそれを一度しか描画しようとしておらず、同時に見ています

私のコードはJPanelを一度しか描画しません。問題はJPanelの背景が表示されないことです。私はこの問題に

import javax.swing.*; 

import java.awt.*; 
import java.awt.event.*; 

public class Main extends JLayeredPane { 
    static JFrame frame; 
    static Main main; 
    static Dimension screenSize; 
    public Main() {  
     JPanel backPanel = new BackPanel(); 
     JPanel frontPanel = new FrontPanel(); 
     add(backPanel, new Integer(7)); 
     add(frontPanel, new Integer(8)); 

     new Thread(() -> { 
      while (true){ 
       repaint(); 
      } 
     }).start(); 

    } 

    public static void main(String[] args) { 
     screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 

     frame = new JFrame("Game"); // Just use the constructor 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     main = new Main(); 
     frame.add(main, BorderLayout.CENTER); 

     frame.pack(); 
     frame.setSize(screenSize); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

    } 
    public class BackPanel extends JPanel{ 
     public boolean drawn = false; 
     public BackPanel(){ 
      setVisible(true); 
      setOpaque(false); 
      setSize(screenSize); 
      JLabel test1 = new JLabel("Test1"); 
      JLabel test2 = new JLabel("Test2"); 
      add(test1); 
      add(test2); 
     } 
     @Override 
     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      drawOnce(g); 
     } 
     public void drawOnce(Graphics g){ 
      if (!drawn){ 
       g.setColor(Color.red); 
       g.fillRect(0, 0, screenSize.width, 200); 
       drawn=true; 
      } 

     } 
    } 
    public class FrontPanel extends JPanel{ 

     public FrontPanel(){ 
      setVisible(true); 
      setOpaque(false); 
      setSize(screenSize); 
      JLabel test = new JLabel("Test"); 
      add(test); 
     } 
     @Override 
     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      g.setColor(Color.blue); 
      g.fillRect(0+screenSize.width/2, 0, screenSize.width/4, 300); 
     } 
    } 
} 
+0

'FPSを高めるために'なぜあなたはフレームレートを上げる必要がありますか?特定のフレームレート(60fps - 言い換えれば、fpsを上げることは必ずしも有利ではない)でfpsとリフレッシュをより良く制御するためにjavax.swing.Timerを使用することを検討してください。 – copeg

+0

@copeg私の実際のプロジェクトでは、最高のFPSが可能で、毎秒60ティックでゲームを更新し続けます。 FPSを増やすのではなく、より少ないシステムリソースを使用するように答えを書き直しました。 – Colourfit

+1

Swingペインティングシステムは、必要に応じて再ペイントするように設計されています。ペイントルーチンが複雑で一度だけ実行したい場合は、初めてBufferedImageに描画し、JPanelに画像を描画します。 – copeg

答えて

0

を修正するにはどうすればよいRepaintManager.currentManager(コンポーネント).markCompletelyClean(コンポーネント)を試してみてください。コンポーネントが再描画されないようにします。新しいコンポーネントを追加するたびにこれを行う必要があります。

http://docs.oracle.com/javase/6/docs/api/javax/swing/RepaintManager.html#markCompletelyClean%28javax.swing.JComponent%29

+0

なぜコンポーネントが再描画されないようにしたいのですか?どのようにこれは背中の問題を解決するJPanelは一度だけ描画され、正面JPanelの背後にあるときに表示されていない、常に再塗りつぶされて – Colourfit

+0

私はそれが正常に再塗りつぶしを作った!それは私の問題ではありません!私が問題にしているのは、一度それを再描画すれば表示されます。 – Colourfit

+0

答えを教えていただけますか? – Colourfit

0

私はコード

super.paintComponent(g); 
drawOnce(g); 

のこの2行は、問題の根であれば、私はsincerly paintComponentは(テストは助けることができる)どのように動作するか覚えていない知っているが、しようとしないでくださいそれらを交換する:多分

drawOnce(g); 
super.paintComponent(g); 

を、あなたの元のバージョンに、あなたが使用して、AWTEventがDRAに、キューに追加された後にのみ、全体のコンポーネントをペイントするためにJVMに指示し、 wあなたが必要とするもの。 私はawtのドキュメンテーションがそれを説明すると思います。

関連する問題