문제

I'm new to Swing and I'm having trouble replacing an existing JFrame. I initialize the first JFrame without a problem...

Main:

public static JFrame jf;
public static int state = 0;

public static void main(String args[]) {
    jf = new MainMenu();
    jf.setVisible(true);
    while (state != -1) {}  
}

MainMenu:

public MainMenu() {
    setTitle("Battleship");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);

    JButton btnSinglePlayer = new JButton("Single Player - Easy");
    btnSinglePlayer.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {
            GameDriver gd = new GameDriver(1);
        }
    });

    JButton btnSplitScreenMultiplayer = new JButton("Split Screen Multiplayer");
    btnSplitScreenMultiplayer.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {
            GameDriver gd = new GameDriver(0);
        }
    });

    JButton btnOnlineMultiplayer = new JButton("Online Multiplayer");
    btnOnlineMultiplayer.setEnabled(false);

    JButton btnHowToPlay = new JButton("How to Play");
    btnHowToPlay.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (Desktop.isDesktopSupported()) {
                try {
                     //Set your page url in this string. For eg, I m using URL for Google Search engine
                     String url = "http://www.hasbro.com/common/instruct/battleship.pdf";
                     java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
                   }
                   catch (java.io.IOException e2) {
                       System.out.println(e2.getMessage());
                   }
            }
        }
    });
    GroupLayout gl_contentPane = new GroupLayout(contentPane);
    gl_contentPane.setHorizontalGroup(
        gl_contentPane.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()
                .addContainerGap(128, Short.MAX_VALUE)
                .addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false)
                    .addComponent(btnHowToPlay, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnOnlineMultiplayer, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnSinglePlayer, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(btnSplitScreenMultiplayer, Alignment.LEADING))
                .addGap(121))
    );
    gl_contentPane.setVerticalGroup(
        gl_contentPane.createParallelGroup(Alignment.LEADING)
            .addGroup(Alignment.TRAILING, gl_contentPane.createSequentialGroup()
                .addContainerGap(89, Short.MAX_VALUE)
                .addComponent(btnSinglePlayer)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(btnSplitScreenMultiplayer)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(btnOnlineMultiplayer)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(btnHowToPlay)
                .addGap(45))
    );
    contentPane.setLayout(gl_contentPane);
}

But once I enter GameDriver and try to initialize a different JFRame...

GameDriver:

//Stuff Happens
ProgramShell.jf.setVisible(false);
ProgramShell.jf = new PlacementWindow(currentPlayer, otherPlayer, curShip);
ProgramShell.jf.setVisible(true);

I get a blank JFrame without all of it's components (It is created properly when I use PlacementWindow's main to initialize)

PlacementWindow:

private JPanel contentPane;
private GameBoard gbCur;
private GameBoard gbOth;
private int curPlacement;
private String title;
private int sqSize = 21;
private int xOffset = 27;
private int yOffset = 27;
private int divOffset = 283;

public PlacementWindow(GameBoard cur, GameBoard oth, int curShip) {
    this.gbCur = cur;
    this.gbOth = oth;
    this.curPlacement = curShip;
    title = "Battleship! " + cur.getName() + ", place your ships";

    setTitle(title);
    setBounds(100, 100, 518, 389);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);

    //Stuff added to Content Pane

    ImagePanel leftBoard = new ImagePanel("graphicsAssets/boardGraphic.png");
    leftBoard.setBounds(6, 6, 250, 250);
    getContentPane().add(leftBoard);

            //More stuff added to Content Pane

    contentPane.setLayout(null);
}

I recognize my approach is a little unconventional, but I'm trying to work within the limitations of code not designed for swing (and must remain, for the most part, intact). Any help would be greatly appreciated!

EDIT

I've modified my code to mimic Vince's along with the following function:

public static void update(/*New Values*/) {
   frame.remove(pp);
   secondPanel = new SecondPanel(/*New Values*/);
   frame.add(pp, "secondPanel");
   switchPanel("secondPanel");

Unfortunately The frame doesn't switch from the original MainMenu Frame upon calling update. Any Ideas?

도움이 되었습니까?

해결책

Don't initialize new Frames. If you want to switch from one panel to another, set your frame's layout to CardLayout, and add JPanels.

class MyFrame {

    static CardLayout cl = new CardLayout(); //handles panel switching

    static JFrame frame; //init swing on EDT
    static FirstPanel firstPanel;
    static SecondPanel secondPanel;

    public static void main(String[] args) {
         initFrame();
    }

    public static void initFrame() {
         SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                   frame = new JFrame();
                   frame.setDefaultCloseOperation(3);
                   frame.setLayout(cl);

                   firstPanel = new FirstPanel();
                   secondPanel = new SecondPanel();


                   //first panel added to frame will always show first
                   frame.add(firstPanel, "first");
                   frame.add(secondPanel, "second");
                   frame.pack(); //sizes frame to fit the panel being shown

                   setVisible(true);
              }
         });
    }

    public static void switchPanel(String name) {
         cl.show(frame.getContentPane(), name);
         frame.pack();
    }
}   

class FirstPanel extends JPanel { }
class SecondPanel extends JPanel { }

You use panels so if needed, you can switch/dispose/create panels instead of the entire frame.

BUT, as for games, they don't use the panel approach. Games use 1 panel, and instead. If this doesn't make sense to you, I answered another question with a simple game design: JFrame, JPanel, KeyListener questions

I also suggest looking into Game States. This is another big deal when it comes to games. It allows you to render/update depending on what state the game is at (menu, game, pause, ect..)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top