0

アプレット ゲームを作成しています。このゲームでは、アプレットのサイズを変更してブラウザ ウィンドウ全体に表示させたいと考えています。これが HTML で可能であることは理解しています。今のところ、サイズ変更が強制されることがあるアプレットがあると想定しています。

GridBagLayout を使用すると、サイズ変更中に多くのちらつきが発生するという問題がありました (再描画中に各 JPanel をクリアしているようです - 各 JPanel の update() メソッドをオーバーライドしようとしました)。ウィンドウのサイズ変更が完了するまで、ゲームのサイズ変更を遅らせることにしました - ちらつきを避けるためと、ゲーム コードで多くの迅速で小さなサイズ変更を処理する必要がないようにするためです。

私はこれのための作業コードを持っています。以下に添付します (少し簡略化されています)。ただし、これは、ウィンドウが両方向に大きく引き伸ばされている場合にのみ機能します。幅または高さが一瞬でも縮小すると、ゲームはすぐに左上隅の小さな正方形に折りたたまれます。

ゲームは正常に動作し続けますが、サイズ変更中に画像が一時的に覆われるようにするにはどうすればよいですか?

コードを説明すると、ゲーム レイアウト全体を GridBagLayout の最上位の位置 0,0 に重みなしで含む 1 つの JPanel があります。各方向の重みが 1.0 の位置 1,1 に空のラベル (emptySpace と呼ばれる) があります。

レイアウト

次のコードを使用して、サイズ変更中を除いて、ゲーム ウィンドウがスペース全体を占有するようにします。

public class Isometric extends Applet {

//last measured width/height of the applet
public int APPWIDTH;
public int APPHEIGHT;

boolean resizing = false;
int resizeNum = 0;

//Game extends JPanel
Game game;
JPanel window;
JLabel emptySpace;

//one-time startup
public void init(){
    APPWIDTH = this.getWidth();
    APPHEIGHT = this.getHeight();

    addComponents();

    //calls checkSize() every 200ms
    Timer timer = new Timer();
    timer.schedule(new TimerTask(){
          public void run(){
              checkSize();
          }
    },200, 200);
}

private void checkSize(){
    //if the dimensions have changed since last measured
    if(APPWIDTH != this.getWidth() || APPHEIGHT != this.getHeight()){
        APPWIDTH = this.getWidth();
        APPHEIGHT = this.getHeight();
        resizing = true;
    }
    else if(resizeNum > 2){ //didn't resize in last 400ms
        resizing = false;
        resizeNum = 0;
        resize();
    }
    if(resizing){
        resizeNum++;
    }
}

private void resize(){
    APPWIDTH = this.getWidth();
    APPHEIGHT = this.getHeight();

    //set new preferred size of game container
    window.setPreferredSize(new Dimension(APPWIDTH, APPHEIGHT));

    GridBagConstraints c = new GridBagConstraints();
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 1.0;
    c.weighty = 1.0;
    this.remove(emptySpace); //remove empty space to allow container to stretch to preferred size
    this.add(emptySpace, c); //add empty space again now with zero width/height

    validate(); //recalculates everything so changes occur properly
}

private void addComponents(){
    setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    window = new JPanel();
    window.setLayout(new GridBagLayout());

    window.setPreferredSize(new Dimension(APPWIDTH, APPHEIGHT));

    c.anchor = GridBagConstraints.NORTHWEST;
    c.fill = GridBagConstraints.BOTH;

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.0;
    c.weighty = 0.0;
    this.add(window,c);

    emptySpace = new JLabel();
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 1.0;
    c.weighty = 1.0;
    this.add(emptySpace, c);
}

//app close
public void destroy(){
    System.exit(0);
}

}
4

2 に答える 2

1

原則として、古いヘビーウェイトAWTと新しいライトウェイトSwingコンポーネントを混在させない方がよいでしょう。AWTコンポーネントは、ネイティブシステムにそのペイントを実行するように要求し、多くの場合、アプリケーションで使用される可能性のあるSwingコンポーネントを「ペイントオーバー」します。

Swingには、ちらつきが少ない強化されたペイントモデルがあります。

JAppletここでは、古いものではなく、を使用できますjava.awt.Applet。Swing'sJAppletを使用すると、サイズ変更時にスムーズに再描画できます。

別の注意点System.exit()として、アプレットから電話をかけないでください。これにより、ブラウザ全体が閉じられる可能性があります(!)

于 2012-11-08T20:39:08.420 に答える