import javax.swing.*;
import java.awt.*;
class MainGui{
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut
Just reading your short descrption, I have no idea what your problem is. But based solely on the question title
"How to give a preffered size to the JButton?"
Don't. Let the the layout manager handle this for you. If you want a bigger button, you can use JButton.setMargins(Insets)
and/or JButton.setFont(Font)
where you specify a bigger font.
If you want you button stretched or not to stretch, You need to select an appropriate layout manager, that will or won't respect the buttons preferred size. For instance, BorderLayout and GridLayout won't respect preferred sizes and will stretch the button the fit, and FlowLayout, BoxLayout, and GridBagLayout will respect the preferred size. As you can see here
See example with GridBagLayout
import javax.swing.*;
import java.awt.*;
class MainGui {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut = new JButton("New Game");
JButton continueBut = new JButton("Continue");
JButton exitBut = new JButton("Exit");
JLabel backImage = new JLabel(new ImageIcon(
getClass().getResource("images.jpg")));
public MainGui() {
backImage.setLayout(new BorderLayout());
frame.setContentPane(backImage);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.setOpaque(false);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
mainPanel.add(newBut, gbc);
gbc.gridy = 1;
mainPanel.add(continueBut, gbc);
gbc.gridy = 2;
mainPanel.add(exitBut, gbc);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.setSize(250, 275);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
MainGui mainGui = new MainGui();
}
});
}
}
And here's with nesting panels which will give the same result
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class MainGui {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JButton newBut = new JButton("New Game");
JButton continueBut = new JButton("Continue");
JButton exitBut = new JButton("Exit");
JLabel backImage = new JLabel(new ImageIcon(
getClass().getResource("images.jpg")));
public MainGui() {
backImage.setLayout(new GridLayout(3,1));
frame.setContentPane(backImage);
JPanel p1= new JPanel(new GridBagLayout());
p1.setOpaque(false);
p1.add(newBut);
JPanel p2 = new JPanel(new GridBagLayout());
p2.setOpaque(false);
p2.add(continueBut);
JPanel p3 = new JPanel(new GridBagLayout());
p3.setOpaque(false);
p3.add(exitBut);
frame.add(p1);
frame.add(p2);
frame.add(p3);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 275);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
MainGui mainGui = new MainGui();
}
});
}
}
You should take a look at A Visual Guide to Layout Managers and choose the most appropriate one for your situation. You should also avoid explicitly setting sizes (ie: setSize
, setMinimumSize
, setMaximumSize
, and setPreferredSize
) because those methods are the responsibility of the layout manager. You may also be interested in reading this question on whether or not the use of the different set size methods should be avoided or not.
Finally, you should not be calling your MainGUI
class outside of the Event Dispatch Thread (EDT). Most Swing GUI-related methods are not thread safe and therefore require being executed in the EDT. Below is a corrected version of your main method:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MainGui mainGui = new MainGui();
}
});
}