0

私は次のバグ/問題を抱えており、ウェブ上または同様の問題を抱えている人の例でまだ解決策を見つけることができませんでした.基本的に、同じサイズのパネル(メインパネルとして機能する)を含むメインフレームがあります。 "Enter" を押すと、インベントリとして機能する内部フレーム (playersprite がある場所の上) がポップアップし、コントロールがそれに渡されます。もう一度 "Enter" を押すと、インベントリが破棄され、コントロールがに渡されます。メインパネル。

再描画機能が呼び出され、キャラクターとマップが再描画され、これは約 90% の時間で機能します。残りの 10% 以下の時間は、インベントリが破壊されるたびに再描画が呼び出されて機能するように見えますが、何もありません。メインパネル(画面)で再描画を呼び出すデバッグキープレスを追加すると、すべてが正常に戻るため、破壊されたパネルに描画するかのように描画されます。

もちろん、run() メソッドのループごとにキャラクターを再ペイントすることもできますが、何かが変更された場合 (つまり、移動した場合) にのみ再ペイントするので、それはひどいことです。

move やその他のコードは役に立たず、以下のコードでも問題が発生するため、すべて削除しました。 Character クラスは、単純な四角形として考えることができます。

public class main extends JFrame implements Runnable{
    private boolean gameRunning=true;
    private Character Link;
    private MainScreen theScreen;
    public final int ScreenHeight=500;
    public final int ScreenWidth=500;
    public boolean inMenu=false;
    Block ablock=new Block(200,200);
    public class Inventory extends JInternalFrame{
        public Inventory(){
            setBounds(25,25,300,300);
            setDefaultCloseOperation(HIDE_ON_CLOSE);
            setVisible(true);
            addKeyListener(new KeyAdapter() {
                public void keyPressed(KeyEvent e){
                    int key=e.getKeyCode();
                    if(key==KeyEvent.VK_ENTER){
                    try{                                    
                        setClosed(true);
                        theScreen.requestFocusInWindow();
                        theScreen.repaint();
                        inMenu=false;
                    }                               
                    catch(Exception ex){}
                    }
            }});
        }
    }
    class MainScreen extends JPanel{
        MainScreen(){
            super();
            setIgnoreRepaint(true);
            setFocusable(true);
            setBounds(0,0,ScreenWidth,ScreenHeight);
            setVisible(true);
            setBackground(Color.white);
        }
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            Link.draw(g);
            g.drawImage(ablock.getImg(),ablock.getX(), ablock.getY(),null);
        }
    }
    main(){
        super();
        final JDesktopPane desk = new JDesktopPane();
        theScreen=new MainScreen();
        add(theScreen);
        theScreen.addKeyListener(new KeyAdapter() {
            public  void keyPressed(KeyEvent e){
                int key=e.getKeyCode();
                if(key==KeyEvent.VK_ENTER){
                    inMenu=true;
                    Inventory myInventory=new Inventory();
                    desk.add(myInventory);
                    myInventory.requestFocusInWindow();
                }
            }   
    });
        add(desk);
        try {
            UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());

            }
        catch (Exception e) {}
        setTitle("Project X");
        setResizable(false);
        Link=new Character();
        setSize(500,500);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        main Game=new main();
        new Thread(Game).start();
    }
    public void run(){
            //omitted/irrelevant only contains  a FPS count
          }
    }

}
4

1 に答える 1

3

KeyListeners を使用しないでください。キーバインディングを使用します。

スレッドを使用しないでください。アニメーションに Swing Timer を使用して、更新が EDT で行われるようにします。

ポップアップ ウィンドウに内部フレームを使用しないでください。JDialog を使用します。

JDesktopPane ではなく、JPanel でカスタム ペイントを行います。

setIgnoreRepaints() を使用しないでください。これは、アクティブ レンダリングに使用されます。

空の catch 句を使用しないでください。

標準の Java 命名規則を使用します。クラスは大文字で始まりますが、変数名は大文字ではありません。

setBounds() を使用しないでください。レイアウト マネージャーを使用します。

于 2013-03-29T03:48:33.637 に答える