I have added buttons and text fields to a panel, but when I try to add the panel to the MenuItem nothing happens. I have defined an ActionListener for the MenuItem in which I am adding the JPanel. No error is detected by the compiler, but nothing happens when I click the MenuItem. How can I resolve this issue?
public class MenuFrame extends JFrame {
private JMenu customers;
private JMenu purchase;
private JPanel panel1 = new JPanel();
public MenuFrame() {
JButton button = new JButton();
panel1.add(button);
customers = new JMenu("Customers");
JMenuItem createInvoice = new JMenuItem("Create");
JMenuItem updateInvoice = new JMenuItem("Update");
JMenuItem deleteInvoice = new JMenuItem("Delete");
sales.add(createInvoice);
PanelHandler p = new PanelHandler(panel1);
createInvoice.addActionListener(p);
}
private class PanelHandler implements ActionListener {
private JPanel panel;
public PanelHandler(JPanel p) {
this.panel = p;
}
public void actionPerformed(ActionEvent e) {
// getContentPane().removeAll();
// getContentPane().setVisible(true);
// JButton b=new JButton("Enter");
// panel.add(b);
panel.setVisible(true);
add(panel, BorderLayout.SOUTH);
getContentPane().doLayout();
// update(getGraphics());
}
}
}
Don't invoke doLayout() directly.
When add (or remove) components from a visible GUI the basic code is:
panel.add(...);
panel.realidate(); // to invoke the layout manager
panel.repaint(); to repaint components
Related
I will have a menu bar in which I can select multiple choices, in which will display a different JPanel for me onto my JFrame. Whenever I choose another option from my menu bar, a different JPanel will occupy the JFrame's space.
However, with this code, every time I issue the following code frame.getJPanelOne();, it creates a new JFrame, which I don't want. I only want the panel to be displayed on my existing JFrame.
Keep in mind, when my program starts, a JFrame is created from the JFrameTest class and also displays my menu bar at the top so I can select between Panel one and Panel two.
How can I successfully do this with the following code?
public class MenuActionListener implements ActionListener {
private MyFrame frame;
public MenuActionListener (MyFrame frame) {
this.frame = frame;
}
public void displayPanelOne() {
JFrameTest frame = new JFrameTest();
frame.getJPanelOne();
}
public void displayPanelTwo() {
JFrameTest frame = new JFrameTest();
frame.getJPanelTwo();
}
#Override
public void actionPerformed(final ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
//Display panel one when I select the option on the menu bar
case "Panel One":
displayPanelOne();
break;
//Display panel two when I select the option on the menu bar
case "Panel Two":
displayPanelTwo();
break;
default:
}
}
}
Here is my JFrameTest class:
public class JFrameTest extends JFrame {
private JPanel panelMain;
private JPanelOne panel1;
private JPanelTwo panel2;
private JMenuBar menuBar;
public JFrameTest() {
MenuBar menuBarInstance = new MenuBar();
frame = new JFrame();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setPreferredSize(new Dimension(720, 480));
setJMenuBar(menuBarInstance.getMenuBar());
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
pack();
setLocationRelativeTo(null);
setVisible(true);
panelMain = new JPanel();
panelMain.setBounds(0, 0, 420, 90);
panelMain.setPreferredSize(new Dimension(200, 40));
add(panelMain);
}
public JPanel getJPanelOne() {
panel1 = new JPanelOne();
panelMain.add(panel1);
return panelMain;
}
public JPanel getJPanelTwo() {
panel2 = new JPanelTwo();
panelMain.add(panel2);
return panelMain;
}
}
Here is both my JPanel classes in which will be added whenever I select the appropriate item from the menu bar:
public class JPanelOne extends JPanel
{
public JPanelOne()
{
// setting up black JPanel
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
JLabel label = new JLabel("Panel One");
// adding button to the black JPanel
panel.add(label);
// adding blackJPanel
add(panel);
}
}
And a separate class for my other panel.
public class JPanelTwo extends JPanel
{
public JPanelTwo()
{
// setting up black JPanel
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.RED);
JLabel label = new JLabel("Panel One");
// adding button to the black JPanel
panel.add(label);
// adding blackJPanel
add(panel);
}
}
Create menu action listener and add it to my GUI:
public class MenuBar {
private JMenuBar menuBar;
private MyFrame frame;
public MenuBar() {
System.out.println("menuBar");
//Creates a menubar for a JFrame
menuBar = new JMenuBar();
//Define addMenu items
JMenuItem addPanelOneItem = new JMenuItem("Panel One");
addPanelOneItem.setActionCommand("Panel One");
//Define addMenu items
JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
addPanelTwoItem.setActionCommand("Panel Two");
JMenu menu = new JMenu("Test");
menuBar.add(menu);
menu.add(addPanelOneItem);
menu.add(addPanelOneItem);
public JMenuBar getMenuBar()
{
return menuBar;
}
}
My question is, how can I successfully display multiple JPanel's from different classes onto my main JFrame without creating new instances of said JFrame?
Thank you in advance.
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
It's creating a new JFrame each time because you are telling it to (new JFrameTest();). Instead, do something like:-
JFrameTest frame = new JFrameTest();
public void displayPanelOne() {
// todo - remove existing panel if required?
frame.getJPanelOne();
}
your MenuActionListener class should look like this:
public class MenuActionListener implements ActionListener {
private JFrameTest frame;
public MenuActionListener(JFrameTest frame){
this.frame=frame;
}
public void displayPanelOne() {
frame.getJPanelOne();
}
public void displayPanelTwo() {
frame.getJPanelTwo();
}
#Override
public void actionPerformed(final ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
//Display panel one when I select the option on the menu bar
case "Panel One":
displayPanelOne();
break;
//Display panel two when I select the option on the menu bar
case "Panel Two":
displayPanelTwo();
break;
default:
}
}
}
and again we are missing the crucial part of the code, on which you create the MenuActionListener and add it to your GUI. if you post that code, we can solve your question. And also don't make a new question to the exact same problem as before
Copy the following code of your MenuBar
public class MenuBar {
private JMenuBar menuBar;
private MyFrame frame;
public MenuBar() {
System.out.println("menuBar");
//Creates a menubar for a JFrame
menuBar = new JMenuBar();
//Define addMenu items
JMenuItem addPanelOneItem = new JMenuItem("Panel One");
addPanelOneItem.setActionCommand("Panel One");
//Define addMenu items
JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
addPanelTwoItem.setActionCommand("Panel Two");
JMenu menu = new JMenu("Test");
menuBar.add(menu);
menu.add(addPanelOneItem);
menu.add(addPanelOneItem);
}
public JMenuBar getMenuBar()
{
return menuBar;
}
}
and in your JFrameTest class you then after
setJMenuBar(menuBarInstance.getMenuBar());
add these lines of code:
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
public JFrameTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setPreferredSize(new Dimension(720, 480));
menuBar=new MenuBar().getMenuBar();
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
pack();
setLocationRelativeTo(null);
setVisible(true);
panelMain = new JPanel();
panelMain.setBounds(0, 0, 420, 90);
panelMain.setPreferredSize(new Dimension(200, 40));
add(panelMain);
setJMenuBar(menuBar);
}
I'm working on a text editor using Java (Swing). So far I have made the body. I'm having problem with this feature:
New (JMenuItem) (empties the content of the JTextArea).
When the user clicks on the button, the JTextArea content should be replaced with an empty string.
This is my code (I'm ommiting code that's not relevant to the problem, such as menu creation, menu items addition, only adding the classes.)
This is the TextArea class:
class MyTextArea extends JTextArea implements ActionListener {
JTextArea myTextArea;
public MyTextArea() {
init();
}
public void init(){
setLineWrap(true);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
(Empty, as you can see.)
This is the MenuBar class:
class MyMenuBar extends JMenuBar implements ActionListener {
private JMenu mArchivo;
private JMenuItem mNuevo;
public MyMenuBar(){
init();
add(mArchivo);
}
private void init() {
mArchivo = settingUpMenus("Archivo", "Archivo", 'A');
mNuevo = settingUpMenuItems("Nuevo", "Nuevo", 'N');
mArchivo.add(mNuevo);
}
private JMenu settingUpMenus(String mTitle, String mDescription,
char mMnemonic) {
JMenu mMenu;
mMenu = new JMenu(mTitle);
mMenu.setMnemonic(mMnemonic);
mMenu.getAccessibleContext().setAccessibleDescription(mDescription);
mMenu.setActionCommand(mTitle);
mMenu.addActionListener(this::actionPerformed);
return mMenu;
}
private JMenuItem settingUpMenuItems(String mTitle, String
mDescription, char mMnemonic) {
JMenuItem mMenuItem;
mMenuItem = new JMenuItem(mTitle);
mMenuItem.setMnemonic(mMnemonic);
mMenuItem.getAccessibleContext().
setAccessibleDescription(mDescription);
mMenuItem.setActionCommand(mTitle);
mMenuItem.addActionListener(this::actionPerformed);
return mMenuItem;
}
#Override
public void actionPerformed(ActionEvent e) {
switch(e.getActionCommand()) {
case "Nuevo":
onNew();
break;
}
}
private void onNew() {
}
}
And this is the class constructor where I add the JTextArea and the JMenu with it's items and all.
public Editor() {
JScrollPane myScrollPane = new JScrollPane(new MyTextArea(),
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
systemLook();
setTitle("Text editor");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(new Dimension(800, 700));
setVisible(true);
setJMenuBar(new MyMenuBar());
add(myScrollPane);
}
However, I have tried many ways for my new button to get access to the current instance of JTextArea and to modify it, such as getting the parent classes with the ActionEvent object in the actionPerformed method inside the JMenu class. But none of the intents I have done can access to the JTextArea. Any ideas? Should I implement it another way?
Just pass it as a parameter in the constructor of the menu bar like
...
private JTextArea myTextArea;
public MyMenuBar(MyTextArea myTextArea){
init();
add(mArchivo);
this.myTextArea = myTextArea;
}
...
and in the main would look like
MyTextArea myTextArea = new MyTextArea();
JScrollPane myScrollPane = new JScrollPane(myTextArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
systemLook();
setTitle("Text editor");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(new Dimension(800, 700));
setVisible(true);
setJMenuBar(new MyMenuBar(myTextArea));
I am making a program which displays 3 buttons, and when user clicks on "single player", it activates mouse listener which creates new panel, and is supposed to replace the existing panel with that newly created panel. But all I get after I click "single player" is the new window with white empty background. Here is the code:
public class UserInterface extends JFrame {
private JLabel singlePlayer,multiPlayer,quit;
private Container menu;
public JPanel mainPanel,fieldPanel;
private Field field;
private Snake snake1,snake2;
private Food food;
public UserInterface(){
// Adjust window
mainPanel=new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
mainPanel.setSize(700, 500);
setSize(710, 510);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setTitle("Snake");
//add(mainPanel);
setVisible(true);
this.getContentPane().setBackground(Color.ORANGE);
//mainPanel.setBackground(Color.GREEN);
// Instantiate buttons
singlePlayer=new JLabel();
multiPlayer=new JLabel();
quit=new JLabel();
singlePlayer.setIcon(new ImageIcon("files/singleplayer.jpg"));
multiPlayer.setIcon(new ImageIcon("files/multiplayer.jpg"));
quit.setIcon(new ImageIcon("files/quit.jpg"));
quit.addMouseListener(new Mouse());
singlePlayer.addMouseListener(new Mouse());
multiPlayer.addMouseListener(new Mouse());
// Create menu panel
menu=new JPanel(new GridLayout(3,1,0,0));
menu.setBackground(Color.ORANGE);
menu.add(singlePlayer);
menu.add(multiPlayer);
menu.add(quit);
menu.setMaximumSize(new Dimension(164,150));
// Insert menu to the center
mainPanel.add(menu, gbc);
add(mainPanel);
}
public void singlePlayer(){
field=new Field("single player");
snake1=new Snake();
food=new Food();
setVisible(false);
removeAll();
mainPanel=field.getFieldPanel();
add(mainPanel);
//setContentPane(mainPanel);
invalidate();
validate();
setVisible(true);
Thread fieldThread=new Thread(field, "Field thread");
//fieldThread.start();
Thread snake1Thread=new Thread(snake1, "Snake thread");
//snake1Thread.start();
}
private class Mouse implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
if(e.getSource()==quit){
System.exit(0);;
} else if(e.getSource()==singlePlayer){
singlePlayer();
} else if(e.getSource()==multiPlayer){
}
}
and here is the field class:
public class Field extends JFrame implements Runnable {
private JPanel fieldPanel;
private JPanel leftPanel;
private JPanel centralPanel;
private JPanel rightPanel;
private String type;
private JLabel leftScore,rightScore;
private int score;
private int foodX,foodY;
private JLabel [][] field;
private final int FIELD_WIDTH=50,FIELD_HEIGHT=50;
private static final long serialVersionUID = 1L;
public JPanel getFieldPanel(){return fieldPanel;}
public Field(String type){
fieldPanel=new JPanel(new GridLayout(1,3,0,0));
fieldPanel.setPreferredSize(new Dimension(700,500));
this.type=type;
// Adjust playground and score tables
leftPanel=new JPanel();
centralPanel=new JPanel();
rightPanel=new JPanel();
leftPanel.setMaximumSize(new Dimension(100,500));
leftPanel.setPreferredSize(new Dimension(100,500));
centralPanel.setMaximumSize(new Dimension(500,500));
centralPanel.setPreferredSize(new Dimension(500,500));
rightPanel.setMaximumSize(new Dimension(100,500));
rightPanel.setPreferredSize(new Dimension(100,500));
// Set leftPanel
score=0;
leftScore=new JLabel("Score:\n"+score);
leftPanel.add(leftScore);
// Adjust field
field=new JLabel[FIELD_WIDTH][FIELD_HEIGHT];
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
field[i][j]=new JLabel("");
field[i][j].setSize(new Dimension(10,10));
field[i][j].setOpaque(true);
field[i][j].setBackground(Color.LIGHT_GRAY);
}
}
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
if(i==0)
field[i][j].setBackground(Color.BLACK);
else if(j==0)
field[i][j].setBackground(Color.BLACK);
else if(i==FIELD_WIDTH-1)
field[i][j].setBackground(Color.BLACK);
else if(j==FIELD_HEIGHT-1)
field[i][j].setBackground(Color.BLACK);
}
}
// Adjust centralPanel
centralPanel.setLayout(new GridLayout(50,50,0,0));
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
centralPanel.add(field[i][j]);
}
}
// Adjust rightPanel
rightPanel.add(new JLabel("Player 2 score: "));
fieldPanel.setLayout(new BoxLayout(fieldPanel,BoxLayout.Y_AXIS));
fieldPanel.add(leftPanel);
fieldPanel.add(centralPanel);
fieldPanel.add(rightPanel);
}
", it activates mouse listener which creates new panel,
It won't solve your problem, but don't use a MouseListener. A JButton is designed to be used with an ActionListener.
after I click "single player" is the new window with white empty background.
When creating a GUI that is designed to share the same space with multiple panels then you should be using a CardLayout to control the visible panel. Read the section from the Swing tutorial on How to Use a CardLayout for more information and examples.
Otherwise if you attempt to mange the swapping of panels manually then the basic code should be:
panel.remove(...);
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to repaint the components
I have an internal frame which has my customer JPanel. In my customer JPanel, I added two panels which is from the outside source.
One of these has button to close the panel. However when I clicked it, it is no effect. How can I make the action listener on the button?
public class MyInternalFrame extends JInternalFrame{
private PDFJPanel panel=null;
public MyInternalFrame(File file) {
super("Test" + file.getName(), true, true, true, true);
panel=new PDFJPanel(file);
this.add(panel, BorderLayout.CENTER);
}
}
There is my customer JPanel
public class PDFJPanel extends JPanel {
private JPanel jpAnnotation=null;
private JScrollPane scrollPane = new JScrollPane();
private File thisFile=null;
private PDFNotesBean bean=null;
private CommentPanel commentPane=null;
public PDFJPanel(File file) {
thisFile=file;
getJPanel();
}
public void getJPanel() {
this.setLayout(new BorderLayout());
this.add(getPDFNotesBean(), BorderLayout.CENTER);
commentPane= bean.getCommentPanel();
bean.getCommentPanelNotes().getjcbHideComments().setVisible(false);
//this code can get the button
bean.getCommentPanelNotes().getToolbar().getCloseButton();
//Right size of the Panel
JPanel rightPanel=new JPanel();
rightPanel.setLayout(new BorderLayout());
rightPanel.setBackground(Color.GREEN);
jpAnnotation=new JPanel();
JButton btnUnderline =new JButton(new ImageIcon ("../UnderlineIcon.gif"));
btnUnderline.setSize(50, 260);
btnUnderline.setAlignmentX(JButton.LEFT_ALIGNMENT);
jpAnnotation.add(btnUnderline);
rightPanel.add(jpAnnotation, BorderLayout.NORTH );
rightPanel.add((Component) commentPane, BorderLayout.CENTER );
this.add(rightPanel, BorderLayout.EAST );
}
}
I'll take a shot in the dark.
jpAnnotation.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
JFrame myInternalFrame= (JFrame)SwingUtilities.getWindowAncestor(this);
myInternalFrame.remove(PDFJPanel.this);
myInternalFrame.invalidate();
myInternalFrame.validate();
myInternalFrame.repaint();
}
});
I am implementing changes to a minesweeper game. One of these things is the difficulty. I have managed to do this and its working, but as the game board (in its own Jpanel) gets bigger & smaller (depending on the difficulty), I cannot get the JFrame to resize automatically. I am using:
setPreferredSize(new Dimension(WIDTH, HEIGHT));
to set the initial size of the window, but this makes it REALLY tiny, as in only showing the word 'File' from the JMenuBar. I have to resize it manually.
I tried setSize() and things like frame.pack() on the ActionListener event, but I cannot seem to get it to resize.
Any tips on what code/methods to use.
edit: code posted
package mines;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SetupFrame extends JFrame {
private final int WIDTH = 600;
private final int HEIGHT = 500;
public JFrame frame;
public JMenuBar menubar;
public JMenu file;
public JMenu levels;
public JMenu help;
public JMenuItem login;
public JMenuItem save;
public JMenuItem resume;
public JMenuItem exit;
public JMenuItem easy;
public JMenuItem medium;
public JMenuItem hard;
private JLabel statusbar;
public JPanel main;
public JPanel buttonPanel;
public JPanel saved;
public JPanel game;
public Board mineGame;
public JButton ngButton;
public JButton undoButton;
public JButton redoButton;
public JTabbedPane tp;
public String[] levelPicker;
public JComboBox levelSelect;
public JFileChooser chooser;
public String filename;
public int difficulty;
public SetupFrame(){
frame = new JFrame();
String filename = JOptionPane.showInputDialog(frame, "Enter Your Name.");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("Minesweeper");
//menubar, menus, menu items
menubar = new JMenuBar();
setJMenuBar(menubar);
file = new JMenu("File");
help = new JMenu("Help");
menubar.add(file);
menubar.add(help);
login = new JMenuItem("Login..");
save = new JMenuItem("Save..");
resume = new JMenuItem("Resume..");
exit = new JMenuItem("Exit");
file.add(login);
file.add(save);
file.add(resume);
file.addSeparator();
file.add(exit);
statusbar = new JLabel("");
chooser = new JFileChooser(); // new File Chooser for saved tab
undoButton = new JButton(" Undo "); //undo Button for game panel
ngButton = new JButton(" New Game ");//new game Button for game panel
redoButton = new JButton(" Redo");//redo Button for game panel
main = new JPanel(new BorderLayout()); //new panel for main game
//main.add(mineGame, BorderLayout.CENTER); //add instance mineGame to main panel
game = new JPanel(new BorderLayout());// new panel for game tab
main.add(game, BorderLayout.CENTER); //add the mineGames panel to game panel
game.add(statusbar, BorderLayout.SOUTH); //add statusbar to bottom of game panel
//game.add(button, BorderLayout.NORTH); // add buttons (eventually be redo, undo, new game)
saved = new JPanel(); // create new panel for the saved tab
saved.add(chooser);//add the File Chooser to the saved tab
String[] levelPicker = {"Easy", "Medium", "Hard"};
levelSelect = new JComboBox(levelPicker);
levelSelect.setSelectedIndex(0);
//levelSelect.addActionListener(this);
buttonPanel = new JPanel();
buttonPanel.add(undoButton);
buttonPanel.add(ngButton);
buttonPanel.add(redoButton);
buttonPanel.add(levelSelect);
main.add(buttonPanel, BorderLayout.NORTH);
//create & add the tabs
tp = new JTabbedPane();
tp.addTab ("Game", main);
tp.addTab ("Saved", saved);
tp.addTab ("Statistics", null);
add(tp);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setResizable(true);
setVisible(true);
frame.pack();
class listener implements ActionListener{
public void actionPerformed (ActionEvent e)
{
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
}
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker == "Easy"){
difficulty = 0;
newMineGame();
}
if (picker == "Medium"){
difficulty = 1;
newMineGame();
frame.pack();
}
if (picker == "Hard"){
difficulty = 2;
newMineGame();
frame.pack();
}
}
private void newMineGame() {
game.removeAll();
mineGame = new Board(statusbar, difficulty);
game.add(mineGame, BorderLayout.CENTER);
game.add(statusbar, BorderLayout.SOUTH);
repaint();
}
}
ngButton.addActionListener(new listener());
undoButton.addActionListener(new listener());
redoButton.addActionListener(new listener());
levelSelect.addActionListener(new listener());
}
public static void main(String[] args) {
new SetupFrame();
}
One of these things is the difficulty. I have managed to do this and
its working, but as the game board (in its own Jpanel) gets bigger &
smaller (depending on the difficulty), I cannot get the JFrame to
resize automatically.
and
tried setSize() and things like frame.pack() on the ActionListener
event, but I cannot seem to get it to resize.
JFrame.pack() works in case
that all JComponents representing mines (there is best of ways to use JToggleButton) returns properly PreferredSize back to its parent (JPanel)
parent (JPanel) laid by GridLayout (very simple)
and there are two ways how, when, where to JFrame.pack()
use CardLayout, the next code line after swithching Card is JFrame.pack()
remove old JPanel (from JFrame) and replace with new, then you need to call JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines
maybe there is another issue, important is code ordering in the case that is there settings for JFrame.setResizable(false);
after your edit
use Cardlayout
there you miss code lines (don't to extends JFrame, create this Object as Local variable) JFrame.(re)validate(), JFrame.repaint() and JFrame.pack() as last code lines in private void newMineGame() {
but I dont understand what you mean by: "there you miss code lines
(don't to extends JFrame, create this Object as Local variable) ;
code could be
import javax.swing.*;
public class SetupFrame {
private JFrame frame;
private JMenuBar menubar = new JMenuBar();
private Board mineGame;
public SetupFrame() {
//there add required JComponents
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setTitle("Minesweeper");
frame.setJMenuBar(menubar);
frame.add(mineGame);
//frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
//frame.setResizable(true);//not neccessary
frame.pack();
frame.setVisible(true);
}
private void newMineGame() {
//remove old Board
//add a new Board
frame.validate();
frame.repaint();
frame.pack();
}
private static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SetupFrame();
}
});
}
}
Here is your mistake:
frame.pack();
Why do you need frame if your SetupFrame actually extends from JFrame? Change this line by just pack() and it will work.
#mKorbel already posted a complete and very useful explanation about pack() behavior (thank you).
Update
Also in your listener class you'll get this exception when a JButton is pressed:
java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox
You need make this little change to avoid this:
class listener implements ActionListener{
public void actionPerformed (ActionEvent e) {
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
} else if(e.getSource() instanceof JComboBox){ // add this else-if block
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker.equals("Easy")){ // <-- picker == "Easy" is not the proper way to compare string, use equals() method instead
difficulty = 0;
newMineGame();
}
if (picker.equals("Medium")){
difficulty = 1;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
if (picker.equals("Hard")){
difficulty = 2;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
}
}
Or even better, implement an ItemListener to listen JComboBox selection changes instead using an ActionListener