How to fix JPanel with Grid that occupies full width of frame? - java

I'm working on a layout for a simple login screen. I am using GridLayout in order to manipulate elements, but have came across an issue, It occupies full frame width like this:
Where as I want it to be with a fixed position and width,height and be vertically, horizontally centered inside a frame, but not occupy it's full size.
Possibly make Username and Password labels occupy less space so text fields are actually closer to them. I tried setting main size of my panel like .setMaximumSize(Dimension (200, 150));
But it doesn't seem to work.
//Create the frame.
JFrame frame = new JFrame("Online Shop");
JPanel mainPanel = new JPanel();
JPanel usernamePanel = new JPanel();
JPanel passwordPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JButton loginButton = new JButton("Login");
loginButton.setMaximumSize(new Dimension(100, 50));
JTextField username = new JTextField();
JLabel usernameLabel = new JLabel("Username");
JPasswordField password = new JPasswordField();
JLabel passwordLabel = new JLabel("Password");
//Panel
frame.setContentPane(mainPanel);
usernamePanel.setLayout(new GridLayout(1,2));
usernamePanel.add(usernameLabel);
usernamePanel.add(username);
passwordPanel.setLayout(new GridLayout(1,2));
passwordPanel.add(passwordLabel);
passwordPanel.add(password);
mainPanel.setLayout(new GridLayout(3, 1));
mainPanel.add(usernamePanel);
mainPanel.add(passwordPanel);
mainPanel.add(loginButton);
//Event Listeners
frame.addWindowListener(new MyWindowListener());
loginButton.addActionListener(new MyActionListener());
//Sizes, Positioning
frame.setSize(720, 480);
frame.setLocationRelativeTo(null);
//Show Frame
frame.setVisible(true);

frame.setSize(720, 480);
Don't use the setSize() method.
Instead use:
frame.pack();
Also use:
JTextField username = new JTextField(10);
To give the text fields a preferred number of characters.
Now when the frame is made visible the components will be displayed at their preferred size and the frame will be sized appropriately to fit the components.
If you want a little extra space between the components and the frame then you can do:
mainPanel.setBorder( new EmptyBorder(20, 20, 20, 20) );

Related

Item inside BoxLayout panel not occupying width of JPanel

Below panel has BoxLayout and the button's at the bottom are not occupying width of the panel and instead there is gap on the left and right side.
JPanel panel = new JPanel();
BoxLayout boxlayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
panel.setLayout(boxlayout);
JPanel framesPanel[] = new JPanel[8];
for(int i=0;i<8;i++) {
framesPanel[i] = new JPanel();
framesPanel[i].setLayout(new BoxLayout(framesPanel[i], BoxLayout.X_AXIS));
JButton jb1 = new JButton("Button 1");
jb1.setAlignmentX(Component.LEFT_ALIGNMENT);
JButton jb2 = new JButton("Button 2");
jb2.setAlignmentX(Component.LEFT_ALIGNMENT);
JButton jb3 = null;
framesPanel[i].add(jb1);
framesPanel[i].add(jb2);
if (i < 6) {
jb3 = new JButton("Button 3");
jb3.setAlignmentX(Component.LEFT_ALIGNMENT);
framesPanel[i].add(jb3);
}
panel.add(framesPanel[i]);
}
// Set size for the frame
panel.setSize(300, 300);
frame.setSize(300, 300);
// Set the window to be visible as the default to be false
frame.add(panel);
I have tried with setAlignmentX(Component.LEFT_ALIGNMENT) but this doesn't seem to have any effect.
A BoxLayout respects the maximum size of a component.
The buttons maximum size is the same as its preferred size.
When you create the buttons you could do something like:
JButton button = new JButton(...);
Dimension maximum = button.getMaximumSize();
maximum.width = Integer.MAX_VALUE;
button.setMaximumSize( maximum );
Note:
This is only a quick fix that will work if you never change the Font size of the button. For a proper solution you should really creat a custom button that extends JButton and override the getMaximumSize() method to return the above size. Then this will work if the properties of the button are changed dynamically.

Resizing the panels on gridlayout

I'm trying to make a simple ui game with Java swing. Here is my target layout design: (all panels have same width, excuse my drawing)
I need 3 small height panel and 1 large panel
I used GridLayout with 4x1. I added some buttons to first panel.
mainFrame = new JFrame("Basket Game");
mainFrame.setLayout(new GridLayout(4, 1));
options = new JPanel();
options.setLayout(new FlowLayout());
options.setBorder( new TitledBorder("Options Menu") );
options.add(settings);
options.add(start);
options.add(pause);
options.add(reset);
options.add(exit);
mainFrame.add(options);
But it makes the first panel too big.
How can I set a size for these panels or should I use different layout pattern.
With a GridLayout, all cells in the grid have the same size, that's why your panel has 1/4 of the total height.
You may consider using a vertical BoxLayout:
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
// add the panels to mainPanel, then
mainFrame.setContentPane(mainPanel);
Here is an example, with three panels containing one button each, and one panel having a bigger size :
JFrame frame = new JFrame();
JPanel p1 = new JPanel();
p1.add(new JButton("11111"));
JPanel p2 = new JPanel();
p2.add(new JButton("222222"));
JPanel p3 = new JPanel();
p3.add(new JButton("3333"));
JPanel p4 = new JPanel();
p4.setPreferredSize(new Dimension(50, 400));
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.add(p1);
mainPanel.add(p2);
mainPanel.add(p3);
mainPanel.add(p4);
frame.setContentPane(mainPanel);
frame.pack();
frame.setVisible(true);

How do I arrange buttons vertically in a JOptionPane?

I'm trying to make a text-based adventure game where the top of the screen is a JTextArea inside a JScrollPane that shows what is happening, and the bottom is a JOptionPane where you click on a button to make a choice. By default, the buttons are arranged horizontally. The only problem is that if I have too many buttons, there is no room for new ones and they are pushed off the screen. I need them to be arranged vertically since they are fatter than they are tall. The JOptionPane and the JScrollPane are nested in a gridLayout, which is nested in a JFrame. This is the method I am using to make the frame:
/**
* Make the frame and everything in it
*/
private void makeFrame()
{
frame = new JFrame("Adventure!");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
contentPane.setLayout(new GridLayout(0, 1));
textArea = new JTextArea(20, 50);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setFont(new Font("font", Font.BOLD, 15));
JScrollPane scrollPane = new JScrollPane(textArea);
contentPane.add(textArea);
optionPane = new JOptionPane("", JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION, null, null);
contentPane.add(optionPane);
frame.pack();
// place the frame at the center of the screen and show
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
Instead of using a JOptionPane, use JButtons in a GridLayout. You can specify how many components you want across and down upon creation like this: new GridLayout(0, 3). This would result in 3 buttons stacked on top of each other, the first int being how many you want across, and the second, how many you want down. Try this:
/**
* Make the frame and everything in it
*/
private void makeFrame()
{
frame = new JFrame("Adventure!");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
contentPane.setLayout(new GridLayout(0, 1));
textArea = new JTextArea(20, 50);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setFont(new Font("font", Font.BOLD, 15));
JScrollPane scrollPane = new JScrollPane(textArea);
contentPane.add(textArea);
//This replaces your JOptionPane block
buttonPane = new JPanel();
buttonPane.setLayout(new GridLayout(0, 1));
contentPane.add(buttonPane);
frame.pack();
// place the frame at the center of the screen and show
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}

How to re-size JButton

I've bee teaching myself java and following along with the problems in the book. I'm trying to make a display for my calculator. In the example(I did not attach this) the buttons were a smaller size than what mine are and I can't figure out how to reformat them. I tried using the dimension class but it had no affect. Also, I can't get my text at the top of the calculator to align left.
Here is my code:
public class Calculator extends JFrame {
public Calculator() {
setTitle("Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(300, 300);
setLayout(new BorderLayout());
JPanel numberPanel = new JPanel();
add(numberPanel, BorderLayout.CENTER);
numberPanel.setLayout(new GridLayout(4, 3, 3, 3));
for(int i = 1; i < 10; i++) {
JButton button = new JButton(String.valueOf(i));
numberPanel.add(button);
}
JButton zero = new JButton("" + 0);
JButton dot = new JButton(".");
JButton clear = new JButton("C");
numberPanel.add(zero);
numberPanel.add(dot);
numberPanel.add(clear);
JPanel keyPanel = new JPanel();
add(keyPanel, BorderLayout.EAST);
keyPanel.setLayout(new GridLayout(4, 1, 3, 3));
JButton plus = new JButton("+");
JButton minus = new JButton("-");
JButton times = new JButton("*");
JButton divide = new JButton("/");
keyPanel.add(plus);
keyPanel.add(minus);
keyPanel.add(times);
keyPanel.add(divide);
JPanel equalsPanel = new JPanel();
add(equalsPanel, BorderLayout.SOUTH);
equalsPanel.setLayout(new GridLayout(1, 1));
JButton equals = new JButton("=");
equalsPanel.add(equals);
JPanel textPanel = new JPanel();
add(textPanel, BorderLayout.NORTH);
JTextField inputBox = new JTextField("0.0");
inputBox.setHorizontalAlignment(JTextField.LEFT);
inputBox.setEditable(false);
Font font = new Font("MonoSpaced", Font.BOLD, 20);
inputBox.setFont(font);
textPanel.add(inputBox);
setVisible(true);
}
public static void main(String[] args) {
new Calculator();
}
}
Imports were left off for brevity
GridLayout will laugh at you when you try and set a dimension. It does respect preferred sizes. You should select a layout manager that will respect preferred sizes. Or you can simply pack() (after you add all your components) your frame instead of setSize() and all the components preferred sizes will kick in. (Disclaimer - because of GridLayout though, if you try and resize the frame after that, you components will resize again)
See more at How to use Layout Managers. For a quick view of which layout managers respect preferred sizes and which ones don't, have a look at this post.
A common approach is to nest panels with different layout managers also, as seen here
UPDATE
As mentioned preciously, you should just call pack on the frame instead of set size. With your current code, this would cause the frame to be very small because of the preferred sizes of the components. If you want the buttons to have a bigger preferred size, you can set the font to a bigger font and/or use button.setMargins(new Insets(w,x,y,x)); to make the margins bigger. But it is preferred to pack the frame.
I would recommend using the Window Builder add-on if you’re using Eclipse. This tool will help you with many aspects of Swing. Learn by doing.
WindowBuilder Dowload Link

Adding JPanel to JFrame?

I'm trying to add a JLabel to a JPanel to a JFrame. I set the border for the JPanel, but all I see on the JFrame is a small black square in the center of my frame. Whatever I do I can't change the size or location of it. Please help.
Start main = new Start();
Random random = new Random();
JFrame mainFrame = new JFrame("MainFrame");
JPanel mainPanel = new JPanel();
JLabel welcomeLabel = new JLabel();
mainFrame.add(main);
mainFrame.setLayout(new GridBagLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setTitle(names[random.nextInt(names.length)]);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setSize(mainFrameX, mainFrameY);
mainFrame.setResizable(false);
mainFrame.setLocationRelativeTo(null);
mainFrame.add(mainPanel);
mainPanel.add(welcomeLabel);
mainPanel.setBorder(new LineBorder(Color.BLACK));
mainPanel.setSize(new Dimension(200, 200));
welcomeLabel.setFont(new Font("Verdana", 1, 20));
welcomeLabel.setLocation(100, 100);
main.start();
Suggestions:
You will want to read the tutorial, Laying out Components, as it will explain how to code with the Swing layout managers, and this information is essential to solve your current problem.
One caveat: I urge you to avoid the temptation to use the null layout as use of it will lead to creation of code that is very hard to maintain or upgrade.
Your JLabel, welcomeLabel, will of course need some text to be visible.
Don't set it's location via setLocation(...) but again use the layout managers to do the dirty work of placing and sizing your components.
You will also want to call pack() and setVisible(true) on your JFrame after adding all initial components.
Hovercraft is right (+1), make sure you understand how the layout managers are working.
The order in which you do things are important, especially when dealing with the top level containers...
Start main = new Start();
Random random = new Random();
JFrame mainFrame = new JFrame("MainFrame");
JPanel mainPanel = new JPanel();
JLabel welcomeLabel = new JLabel();
welcomeLabel.setFont(new Font("Verdana", 1, 20));
mainPanel.add(welcomeLabel);
mainPanel.setBorder(new LineBorder(Color.BLACK));
// Do this first
mainFrame.setLayout(new GridBagLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setTitle(names[random.nextInt(names.length)]);
// Add your components
mainFrame.add(main);
mainFrame.add(mainPanel);
// Prepare the window for showing, now you have some content.
mainFrame.setResizable(false);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setLocationRelativeTo(null);
main.start();
This will still only produce a small black square in the window, because the JLabel has no content and therefore it's preferred size is going to be (something like) 2x2 (because of the border).
Try adding some text to...
welcomeLabel.setText("Welcome");
And then see the difference

Categories

Resources