1

デフォルトの「X」ボタンをクリックしても、JFrame はシャットダウンしません。この問題は、メインスレッドが読み取られていないことに関係していると思いますが、swing の複雑さや正直なところ、一般的なスレッドは理解できません。「ウィンドウ」は JFrame の拡張であり、「ボックス」はプログラムを駆動します。プログラムは初期段階のみです。また、ループオーバーごとにメインスレッドを実行する方法を知りたいです。他の質問ではこれについて何も見つかりませんでした。

public class Window extends JFrame implements KeyListener{
    private static final long serialVersionUID = 1L;
JPanel panel;
public Window(){
    super("FileTyper");
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setSize(200,100);
    super.setResizable(false);
    panel = new JPanel();
    super.getContentPane().add(panel);
    super.setFocusable(true);
    addKeyListener(this);

    super.setVisible(true);
}
public void update(){

}
public void render(Graphics2D g){

}
@Override
public void keyPressed(KeyEvent e) {

}
@Override
public void keyReleased(KeyEvent e) {
    switch(e.getKeyCode()) {
    case KeyEvent.VK_F9:
        break;
    case KeyEvent.VK_F10:
        break;
    }

}
@Override
public void keyTyped(KeyEvent arg0) {

}

}

public class Boxy {
public Window window;

public static void main (String args[]){
    start();
}
public Boxy(){
    init();
    boolean forever = true;
    while(forever){
        update();
        render();
        delay();
    }
}
private void init(){
    window = new Window();
}
private void update(){
    window.update();
}
private void render(){
    Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();
    window.render(g2);
    g2.fillRect(0, 0, 100, 100);
}
private void delay(){
    try {Thread.sleep(20);} catch (InterruptedException ex) {System.out.println("ERROR: Delay compromised");}
}
public static void start(){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            Boxy box = new Boxy();
        }
    });
}
}
4

2 に答える 2

4

あなたのプログラムの「ゲーム」ループは正しくありません:

while(forever){
    update();
    render();
    delay();
}

プログラムをループするのではなく、Swing イベント スレッドまたは EDT (イベント ディスパッチ スレッドの場合) を結び付けてプログラムフリーズます。この機能には、代わりに Swing Timer を使用する必要があります。

于 2013-10-25T01:08:53.860 に答える
4

イベントディスパッチスレッドをブロックすることをお勧めします

while(forever){
    update();
    render();
    delay();
}

これにより、イベント キューがウィンドウを閉じるイベントを処理できなくなります。

Concurrency in Swingを見てみましょう。最初は次のようなものを見てみたいと思うかもしれませんがjavax.swing.Timer、フレームレートをより細かく制御したい場合は、何らかのThread. ただし、Swing は、すべての更新がイベント ディスパッチ スレッドのコンテキスト内から実行されることを想定していることに注意してください。

Swingでのカスタムペイントは、次のようなものを使用して行われません...

Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();

コンテキストのGraphics寿命は短く、(このメソッドを使用して) ペイントしたものは次のペイント サイクルで破棄されます。

代わりに、JPanelペイントのベースとしてa のようなものを使用し、そのpaintComponentメソッドをオーバーライドして、呼び出されるたびにその中から状態をレンダリングする必要があります。

repaintコンポーネントを更新したいときに呼び出すだけです。

詳細については、カスタム ペインティングの実行を参照してください。

また、キーバインディングの代替手段としての使用方法をご覧になることをお勧めしますKeyListener

于 2013-10-25T01:11:04.757 に答える