-1

As in subject: When i change JPanel in JFrame i lose focus. I have class Game, Action, Button. I have also class Stage when drawing the game stage.

At first in Game i have Action panel, which contains buttons, after push button NewGame i change panel in Game to Stage, but i cant control ship, which i am flying.

How to fix it or how to do it different?

Action.java

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.FileNotFoundException;

import javax.swing.*;


@SuppressWarnings("serial")
public class Action extends JPanel {
    public static final int xxx = 800;
    public static final int yyy = 600;
    private Button buttonPanel;

    public Action(Game game) {
        setLayout(new FlowLayout());
        setPreferredSize(new Dimension(xxx, yyy));

        buttonPanel = new Button(game);
        add(buttonPanel);

        setVisible(true);
    }


}

Button.java

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Button extends JPanel implements ActionListener{

    public static final int xxx = 100;
    public static final int yyy = 300;

    private JButton NewGame;
    private JButton Scores;
    private JButton Exit;

    private Game game;


    public Button(Game game) {
        NewGame = new JButton("NewGame");
        Scores = new JButton("Scores");
        Exit = new JButton("Wyjście");
        this.game=game;

        NewGame.addActionListener(this);


        setLayout(new FlowLayout());
        setPreferredSize(new Dimension(xxx, yyy));
        add(NewGame);
        add(Scores);
        add(Exit);
        setVisible(true);             
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();

        if(source == NewGame){
            game.setPanel("stage");
        }
       ;
    }
}

Game.java

@SuppressWarnings("serial")
public class Game extends JFrame {
    private Action menu;
    private static Stage stage = new Stage();
    public Game() {
        super("Lunar Lander");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(Stage.WIDTH,Stage.HEIGHT);
        setMinimumSize(new Dimension(400,300));
        this.setResizable(true);

        //stage = new Stage(0);
        menu = new Action(this);
        add(menu);
        pack();
        //setPanel("stage");
        setVisible(true);   
    }
    public void setPanel(String panel) {
        if (panel=="stage") {
            remove(menu);
            add(stage);
            pack();
        } else if (panel=="menu") {
            remove(stage);
            add(menu);
            pack();
        }
    }
    public static void main(String[] args) throws FileNotFoundException {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Game();
            }
        });
        Thread a = new Thread(stage);
        a.start();
        while (a.isAlive()) {}
        Scores scores = new Scores();
        scores.changeScores(stage.getPlayer().getName(),stage.getPlayer().getPoints());
    }

}
  • 1
    Why `setVisible(true/false)` for each and every component? Why not simply use [__CardLayout__](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html), instead of adding/removing manually? What is this `Thread` for? Where is this `Stage` Class? Are you using `KeyListener`s, for controlling the said `SHIP` in question? – nIcE cOw Jun 16 '14 at 18:16
  • This Thread is for animation, class Stage implements Runnable. I am using key bindings, which are added to class Stage. CardLayout isn't best solution because i want to do simply menu, which contains buttons: "new game", "exit". After pushed "new game" manu should disapear and Stage appear. Stage is like board when everything in game is drawing. –  Jun 16 '14 at 20:55
  • 1) For many components in one space, use a [`CardLayout`](http://docs.oracle.com/javase/7/docs/api/java/awt/CardLayout.html) as seen in this [short example](http://stackoverflow.com/a/5786005/418556). 2) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). – Andrew Thompson Jun 17 '14 at 01:14

1 Answers1

2

but i cant control ship, which i am flying.

KeyEvents are only passed to the component with focus. When you swap panels the panel no longer has focus.

Don't use a KeyListener. Instead you should be using Key Bindings. Then you can handle the event even if the component doesn't have focus.

See Motion Using the Keyboard for more information and working examples.

Edit:

  1. Don't use "==" for String comparisons. Use the String.equals(...) method.

  2. Variable names should NOT start with an upper case character.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • What does mean root pane? The panel when i am drawing everything in game like ship, ground? –  Jun 16 '14 at 20:57
  • See [Using Top Level Containers](http://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html). If you add the Key Bindings to the root pane, then they should work no matter what panel is being display. I don't know how you created your Key Bindings, so I can't offer any more advice without a proper `SSCCE`. – camickr Jun 16 '14 at 21:04