Java Swing - uaktywnienie drugiego okna

0

Witam serdecznie. Mam napisaną grę której główna klasa dziedziczy po Canvas, a konstruktor wygląda tak:

public Gra() {
        spriteCache = new SpriteCache();
        JFrame okno = new JFrame(".: D-Wade :.");
        JPanel panel = (JPanel)okno.getContentPane();
        setBounds(0,0,Boisko.SZEROKOSC,Boisko.WYSOKOSC);
        panel.setPreferredSize(new Dimension(Boisko.SZEROKOSC,Boisko.WYSOKOSC));
        panel.setLayout(null);
        panel.add(this);
        okno.setBounds(0,0,Boisko.SZEROKOSC,Boisko.WYSOKOSC);
        okno.setVisible(true);
        okno.addWindowListener( new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        okno.setResizable(false);
        okno.requestFocus();
        createBufferStrategy(2);
        strategia = getBufferStrategy();
        requestFocus();
        addKeyListener(this);
    }

Chciałbym stworzyć początkowe osobne okienko które będzie miało przycisk, który uruchomi moją grę.

Mam taką oto klasę i JFrame:

package dwade;

public class Okno {
      public static void main(String[] args) {
      Frame f = new Frame();
      f.setVisible(true);     
      }
}

JFrame.java:
package dwade;

public class Frame extends javax.swing.JFrame{

    public Frame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")                        
    private void initComponents() {

        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(800, 800));

        jButton1.setText("Graj");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(163, 163, 163)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(174, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(356, 356, 356)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(407, Short.MAX_VALUE))
        );

        pack();
    }                       

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        Gra inv = new Gra();
        inv.game();
    }                                        

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Frame().setVisible(true);
            }
        });
    }                   
    private javax.swing.JButton jButton1;                  

}

Przycisk uruchamia moją grę lecz nie reaguje ona na przyciski klawiatury ani nie można zamknąć okna przyciskiem X. Próbowałem ustawiać Focus w różnych miejscach albo dodawać do klasy Okna KeyListenery które uruchamiają Listenery mojej gry lecz nic to nie dało. Będę wdzięczny za szybką odpowiedź, termin goni;) Z góry wielkie dzięki.

0

Podaj trochę szczegółów na temat metody game w klasie Gra.

0

Zgaduję że wątek gry jest tym samym co wątek GUI i w efekcie pętla w "grze" powoduje zablokowanie GUI na amen. Tak sie nie robi...

0

Metoda gra wygląda następująco:

public void game() {
        usedTime=1000;
        initWorld(); //zainicjowanie gracza i kilku przeciwników
        while (isVisible() && !gameEnded) { //gameEnded = true gdy gracz utraci wszystkie życia
            long startTime = System.currentTimeMillis();
            updateWorld(); //przesuniecie postaci
            checkCollisions(); //sprawdzenie kolizji postaci
            paintWorld(); //wyrzucenie na ekran
            usedTime = System.currentTimeMillis()-startTime; //to do liczenia fps
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {}
        }
        paintGameOver(); //wyświetlenie napisu "koniec gry"
    }
1

A no widzisz. Toteż GUI nie da rady się odrysować ani przetworzyć żadnego eventa póki nie wyjdzie z tej metody. W związku z tym musisz to odpalić w osobnym wątku.

0

Dzięki wielkie!:) Dodałem do klasy DWade implements Runnable i w metodzie run() jest samo game(). Przycisk tworzy nową Grę, nowy wątek i startuje go i postacie już śmigają aż miło. Tylko jeden problem się pojawił. Gdy zamykam okno z grą X'em to zamykają się oba okienka. Zmieniłem tego ActionListenera z System.exit(0); na okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ale dalej jest to samo;/

0

To teraz łaskawie użyj mózgu zamiast wklejać kawalki kodu których nie rozumiesz. System.exit(0) zabija JVMa, tak samo zresztą jak EXIT_ON_CLOSE.
Jak chcesz tylko zamknąć okienko to daj DISPOSE_ON_CLOSE...

0

Mam pytanie czy:

catch(InterruptedException e) {}

Ma zostać bez wartości ? nie lepiej wyłapywac tutaj wyjątek i drukować, do lepszej analizy błedów

1 użytkowników online, w tym zalogowanych: 0, gości: 1