Reputation: 1264
I'm having trouble adding a JPanel class I created to my container class. To be honest, I'm not sure if this is even the best method to go about creating my menu. I've asked professors, and TA's and they all tell me different things.
EDIT: To clarify, the problem is that the main menu made in the JPanel class isn't shown. I think I added it properly within the container class, but I'm not entirely sure.
This is my JPanel class that I'm trying to add to the container:
package.model;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class MainMenu extends JPanel {
private static MainMenu instance;
private JPanel mainMenu;
private JButton btnSinglePlayer, btnMultiPlayer, btnScoreBoard, btnQuit;
private MainMenu() {
mainMenu();
singlePlayer();
multiPlayer();
scoreBoard();
quit();
}
public static MainMenu getMenuInstance() {
if (instance == null) {
instance = new MainMenu();
}
return instance;
}
public void construct() {
mainMenu();
singlePlayer();
multiPlayer();
scoreBoard();
quit();
}
private JPanel mainMenu() {
mainMenu = new JPanel();
mainMenu.setLayout(null);
return mainMenu;
}
private JButton singlePlayer() {
btnSinglePlayer = new JButton("SinglePlayer");
btnSinglePlayer.setBounds(365, 210, 170, 55);
mainMenu.add(btnSinglePlayer);
return btnSinglePlayer;
}
private JButton multiPlayer() {
btnMultiPlayer = new JButton("MultiPlayer");
btnMultiPlayer.setBounds(365, 300, 170, 55);
mainMenu.add(btnMultiPlayer);
return btnMultiPlayer;
}
private JButton scoreBoard() {
btnScoreBoard = new JButton("ScoreBoards");
btnScoreBoard.setBounds(365, 411, 170, 55);
mainMenu.add(btnScoreBoard);
return btnScoreBoard;
}
private JButton quit() {
btnQuit = new JButton("Quit");
btnQuit.setBounds(365, 500, 170, 55);
mainMenu.add(btnQuit);
return btnQuit;
}
}
And here is my container class:
package view;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import model.MainMenu;
@SuppressWarnings("serial")
public class MainFrame extends JFrame {
private static JFrame mainContainer = new JFrame("Checkers");
private JPanel card = new JPanel(new CardLayout());
private CardLayout cardLayout = (CardLayout) (card.getLayout());
private JPanel homeCard, singlePlayerCard, multiPlayerCard, scoreBoardCard;
private JPanel mainMenu = MainMenu.getMenuInstance();
public MainFrame() {
}
private void addComponentToPane(Container pane) {
//mainMenu.construct();
homeCard = new JPanel();
singlePlayerCard = new JPanel();
multiPlayerCard = new JPanel();
scoreBoardCard = new JPanel();
homeCard.add(mainMenu);
card.add(homeCard, "homeCard");
cardLayout.show(card, "homeCard");
pane.add(card);
}
public static void createAndShowGUI() {
MainFrame frame = new MainFrame();
frame.addComponentToPane(mainContainer.getContentPane());
mainContainer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainContainer.pack();
mainContainer.setSize(920, 650);
mainContainer.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
mainContainer.setLocation(dim.width / 2 - mainContainer.getSize().width
/ 2, dim.height / 2 - mainContainer.getSize().height / 2);
}
}
The reason I want to have a JPanel class, and I'll have more than one btw, is because I want that class to launch my game thread. And I don't wish to launch the game thread through the view. If this is a bad design please let me know.
I do btw, have a launcher class, which I think is irrelevant to post. I know I did it right though, the error which I and abut 3-4 TA's at my university can't seem to find.
Upvotes: 0
Views: 12749
Reputation: 11
private JPanel mainMenu = MainMenu.getMenuInstance();
in MainFrame gets the MainMenu instance variable from the MainMenu Class.
The constructor or construct() method in MainMenu add components to the mainMenu JPanel in MainMenu which is never referred to again.
Also, it is bad practice to set a JPanel's layout to null as you did in MainMenu's mainMenu() method. It sets the size of the JPanel component to 0x0 pixels and you won't see the components inside of the JPanel when you add them.
I could mention another thing or two about refactoring your code properly into methods and ask questions about how the rest of the project works, but this post is 8 years old at the time of this writing. I'm writing these statements to point people in the right direction if they are still curious about why the code doesn't work.
Upvotes: 1
Reputation: 70899
JFrame
has a few side-effects that exist outside of the Java program space, like the frame decorators that the operating system provides (usually edge handles, close buttons, and os driven drop down menus to hide / show / etc.)
As such, typically you cannot use classical composition and inheritance for driving JFrames
at the same time.
If you inherit, you can call the class's own getContentPane()
to get the container which then can be used such as
getContentPane().add(jpanel);
If you perfer composition, then you basically do the same thing, but with your member variable holding the JFrame.
frame.getContentPane().add(jpanel);
Note that unlike many containers, JFrame
only supports adding one item. So, if you want to add multiple items, you need to add a JPanel
, and the add the interior items to the JPanel
.
Upvotes: 1