0

問題: Main.repaint() が機能しません。repaint() は Main のペイント メソッドを呼び出しません。再描画する前に検証を呼び出してみましたが、成功しませんでした。メインは最初またはサイズ変更時に完全にペイントしますが、コードで repaint() を呼び出しても何も起こりません。

これまでのプログラムの外観は次のとおりですリンク

Javaでゲームのレベル選択画面を作成しようとしています。私のゲームは JApplet です。私は次のような構造を持っています:

  1. JApplet を拡張し、LevelScreen クラスのオブジェクトを含むメイン クラス

    LevelScreen には、Main が呼び出すペイント メソッドがあります。

レイアウトマネージャーがデザインに問題を抱えていたので、Swing の使用を避けようとしました。そこで、よりシンプルで自分のニーズにより適した構造を作ろうとしました。

Main.java の paint()

public class Main extends JApplet {

    public static final int WIDTH = 700, HEIGHT = 500;
    private static Main instance;

    private LevelScreen levelScreen = new LevelScreen();
    private View view = View.LEVELSCREEN;

    public static Main getInstance() {
        if (instance == null)
            instance = new Main();
        return instance;
    }

    @Override
    public void init() {
        setSize(WIDTH, HEIGHT);
        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                Point p = e.getPoint();
                if (view == View.LEVELSCREEN) {
                    levelScreen.mouseMoved(p);
                }
            }
        });
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        if (view == View.LEVELSCREEN) 
            levelScreen.paint(g2);
    }

    public enum View {
        GAME, LEVELSCREEN;
    }
}

私のボタンのコードでは、マウスがボタンを離れたときにフェードアウトアニメーションを作成したいので、メインを再描画しようとしています。私の問題は、メインで repaint() を使用してペイント(Graphics g)を呼び出すことができないことです

ここで repaint() を呼び出します:

public void mouseExited() {
        //start new thread to make fade out animation when mouse leave
        mouseOver = false;
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                while (!mouseOver && opacity > 0.6) {
                    opacity -= 0.02;
                    //set level to 999 so i can see if the game repaints()
                    level = 999;
                    Main.getInstance().repaint();  //this doesnt work!!
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        new Thread(task).start();
}
4

2 に答える 2

1

これは、シングルトン デザイン パターンを実装する方法に問題があります。この方法は、アプレット コンテナーによってインスタンスが作成されるアプレットでは機能しません。getInstance次のように変更することで修正できます。

public Main getInstance() {
    return instance;
}

そして、次の行をinitメソッドに追加します。

instance = this;

ちなみに、paintSwing コンポーネントではオーバーライドしないでくださいJAppletpaintComponent代わりにオーバーライドsuper.paintComponent(g)し、最初の行として呼び出す必要があります。これで問題は解決するはずです。

于 2013-10-20T22:36:47.680 に答える
1
Main.getInstance().repaint();  //this doesnt work!!

私は驚かない。のインスタンスを作成するのはあなたではなく、JAppletブラウザです。

これを呼び出すと...

public static Main getInstance() {
    if (instance == null)
        instance = new Main();
    return instance;
}

実際には、アプレットの 2 番目のインスタンスを作成していますが、これは画面に表示されているものではないため、 を呼び出すとrepaint、Swing は「意味がありません。表示することさえできません」と言って何もしません。

コードのコンテキストがこれ以上ない場合はgetInstance、代わりに を使用して現在のインスタンスを参照する必要さえない場合がありますMain.this

Performing Custom Paintingも参照してください。

のような最上位のコンテナJAppeltはダブル バッファリングされていないため、コンテナに直接ペイントする作業が多くなります。代わりに、アプリケーションを a のようなものに基づいて移動し、代わりにそのメソッドJPanelをオーバーライドします。paintComponent

絵画も複雑で多層的なスキームです。super.paintXxxペイント チェーンを保持し、発生する可能性のある問題を回避するには、呼び出す必要があります。

于 2013-10-20T22:40:58.810 に答える