I have a question on my GUI. after I ran my codes. my GUI will display like the picture shown below
But when I enlarged it to full screen. it will become like this.
How do I keep in the center and just like the size in picture one only when enlarged to full screen?
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GuiTest {
JFrame frame = new JFrame("Gui Test");
JPanel panel = new JPanel(new GridLayout(4,0));
JPanel panelTwo = new JPanel(new BorderLayout());
JLabel labelOne = new JLabel("Text One:");
JLabel labelTwo = new JLabel("Text Two:");
JTextField textFieldOne = new JTextField(15);
JTextField textFieldTwo = new JTextField(15);
JTextField textFieldThree = new JTextField(15);
public GuiTest() {
panel.add(labelOne);
panel.add(textFieldOne);
panel.add(labelTwo);
panel.add(textFieldTwo);
panelTwo.add(panel, BorderLayout.CENTER);
frame.add(panelTwo);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.getPreferredSize();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//frame.setResizable(false);
}
public static void main(String[]args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GuiTest();
}
});
}
}
Yet another GridLayout confusion!
It is stretching its children and there is nothing that we can do about it.
GridLayout is a very simple manager with very limited practical
usage. Skip it and skip BorderLayout as well. The only thing that
you need to know about BorderLayout is that it is the default manager
of the frame's content pane.
Layout management is a complex thing -- there not shortcuts. One has to
put some effort to learn it. The good news is that there are some very capable
layout managers. I recommend the following two:
MigLayout
GroupLayout
JGoodies' FormLayout is a good option too. These managers are doing
it properly. Study them carefully and choose your favourite.
I provide two solutions, one with MigLayout, one with GroupLayout.
MigLayout solution
MigLayout is a third-party layout manager for which we need to dowload
a single jar file.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutEx extends JFrame {
public MigLayoutEx() {
initUI();
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout("ins dialog, center, "
+ "center, wrap"));
pnl.add(new JLabel("Text one"));
pnl.add(new JTextField(15));
pnl.add(new JLabel("Text two"));
pnl.add(new JTextField(15));
add(pnl);
pack();
setTitle("MigLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutEx ex = new MigLayoutEx();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout is a built-in layout manager.
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.LEADING;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class GroupLayoutEx extends JFrame {
public GroupLayoutEx() {
initUI();
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JLabel lbl1 = new JLabel("Text one");
JLabel lbl2 = new JLabel("Text two");
JTextField field1 = new JTextField(15);
JTextField field2 = new JTextField(15);
gl.setAutoCreateGaps(true);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createParallelGroup(LEADING)
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createSequentialGroup()
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
pack();
setTitle("GroupLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GroupLayoutEx ex = new GroupLayoutEx();
ex.setVisible(true);
}
});
}
}
Related
So I'm trying to get the button on the bottom right and the text field taking up the bottom left but it keeps switching around for some reason. I think its borderLayout being stupid. I'm a noob at Java btw. Here's my code:
package textchat;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class window extends JFrame{
public static void main(String[] args)
{
new window();
}
public window()
{
//Window Config
//JFrame frame = new JFrame();
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension dm = tk.getScreenSize();
this.setSize(400,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("CALI V1");
this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
//this.setLayout(null);
int Width = this.getWidth();
//Panel(s)
JPanel Panel = new JPanel();
Panel.setLayout(new BorderLayout());
JPanel PanelSouth = new JPanel();
JPanel PanelEast = new JPanel();
JPanel PanelWest = new JPanel();
//button
JButton btn = new JButton("SEND");
//Text Area
JTextArea txt = new JTextArea(100 , 100);
txt.setText("TEXT IS HERE");
//Text Field
JTextField fld = new JTextField("Type Here",15);
//Adding to the panel
Panel.add(txt);
PanelSouth.add(PanelEast, BorderLayout.EAST);
PanelSouth.add(PanelWest, BorderLayout.WEST);
PanelEast.add(btn);
PanelWest.add(fld);
//adding to frame
this.add(Panel);
this.add(PanelSouth , BorderLayout.SOUTH);
this.setVisible(true);
}
}
While using BorderLayout in such a way kind of works, you should
not use it in such a way. Besides, your example has several issues.
For instance, you did not start the application on the EDT (Event Dispatch Tread).
Here is a working example that creates your inteded layout. It uses the powerful GroupLayout manager.
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class TextChatEx extends JFrame {
public TextChatEx() {
initUI();
}
private void initUI() {
JTextArea area = new JTextArea(15, 15);
JTextField field = new JTextField(15);
JButton sendButton = new JButton("Send");
createLayout(area, field, sendButton);
setTitle("Text chat");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setAutoCreateGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup()
.addComponent(arg[0])
.addGroup(gl.createSequentialGroup()
.addComponent(arg[1])
.addComponent(arg[2]))
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addComponent(arg[0])
.addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(arg[1])
.addComponent(arg[2]))
);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
TextChatEx ex = new TextChatEx();
ex.setVisible(true);
});
}
}
GroupLayout is a powerful layout manager; with this manager, you don't have to create a bunch of panels to create some basic layout.
public TextChatEx() {
initUI();
}
The GUI creation is delegated to the initUI() method. Rather than placing all the code into the constructor, we use a specialized method.
EventQueue.invokeLater(() -> {
TextChatEx ex = new TextChatEx();
ex.setVisible(true);
});
Each Swing application should be placed on the EDT. Failing to do this can lead to hard to find bugs in the future.
I want to place a JPanel with 300,200 size at 100,50 location in a JFrame, but the following code makes the whole JFrame to be filled with the JPanel, where am I wrong?
Code:
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setSize(700, 500);
panel.setSize(300, 200);
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
If I change BorderLayout.SOUTH or NORTH, the JPanel looks like a thin line at the bottom or top of the JFrame. Also I tried to use preferred size but its still the same result.
You need to understand the basics of Layout Managers before you can attempt anything with Swing.
Study the tutorial here https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html
If you are trying to construct a form with various Swing controls, never use absolute coordinates to position them. Resizing the window should dynamically reposition your controls according to the type of layout you want to use. If you are using your panel as a drawing canvas (which is what I think you are after), look at my example below.
Try to master a couple of fundamental layouts first such as BorderLayout and GridLayout. Once mastered you can use very few to achieve just about any kind of layout you desire by nesting them together. Also learn the basics of ScrollPane to make efficient use of screen real-estate
As for your original question, I created an example of how BorderLayout works and how to draw to a specific region on a panel. I also added some code so you can set your cursor differently depending on whether you are in the smaller region within a given panel.
Try this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class FrameDemo extends JFrame {
private static final long serialVersionUID = 1L;
public FrameDemo() {
super("Frame Demo");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new CustomPanel(Color.RED), BorderLayout.NORTH);
getContentPane().add(new CustomPanel(Color.GREEN), BorderLayout.SOUTH);
getContentPane().add(new CustomPanel(Color.BLUE), BorderLayout.EAST);
getContentPane().add(new CustomPanel(Color.YELLOW), BorderLayout.WEST);
getContentPane().add(new JScrollPane(new CustomPanel(Color.BLACK)), BorderLayout.CENTER);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new FrameDemo();
frame.setVisible(true);
}
});
}
}
class CustomPanel extends JPanel implements MouseMotionListener {
private static final long serialVersionUID = 1L;
private static final Dimension PANEL_SIZE = new Dimension(200, 100);
private static final int HAND_CURSOR_INDEX = 1;
private static final int DEFAULT_CURSOR_INDEX = 0;
private static final Cursor[] _cursors = new Cursor[] {
Cursor.getDefaultCursor(),
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
};
// I want to place a JPanel with 300,200 size at 100,50 location in a JFrame
private static final Rectangle _rectangle = new Rectangle(50, 10, 40, 50);
public CustomPanel(Color color) {
setBackground(color);
addMouseMotionListener(this);
}
public Dimension getPreferredSize() {
return PANEL_SIZE;
}
public Dimension getMinimumSize() {
return PANEL_SIZE;
}
public Dimension getMaximumSize() {
return PANEL_SIZE;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(
(int)_rectangle.getX(),
(int)_rectangle.getY(),
(int)_rectangle.getWidth(),
(int)_rectangle.getHeight());
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
int cursorIndex = _rectangle.contains(e.getPoint()) ?
HAND_CURSOR_INDEX :
DEFAULT_CURSOR_INDEX;
setCursor(_cursors[cursorIndex]);
}
}
If you want the panel to occupy part of the JFrame (contentpane) you can use other layout managers. He is an example using GroupLayout:
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.getContentPane().setPreferredSize(new Dimension(700, 500) );
panel.setPreferredSize(new Dimension(300, 200));
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(104)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 493, GroupLayout.PREFERRED_SIZE)
.addContainerGap(103, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(100)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 301, GroupLayout.PREFERRED_SIZE)
.addContainerGap(99, Short.MAX_VALUE))
);
frame.getContentPane().setLayout(groupLayout);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
output:
Another example using BorderLayout with 4 additional "place holder" or feeler panels :
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel centerPanel = new JPanel();
centerPanel.setPreferredSize(new Dimension(300, 200));
centerPanel.setBackground(Color.green);
centerPanel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.getContentPane().add(centerPanel);
JPanel northPanel = new JPanel();
northPanel.setBackground(Color.RED);
northPanel.setForeground(Color.BLACK);
northPanel.setPreferredSize(new Dimension(0, 150));
frame.getContentPane().add(northPanel, BorderLayout.NORTH);
JPanel westPanel = new JPanel();
westPanel.setBackground(Color.MAGENTA);
westPanel.setPreferredSize(new Dimension(200, 0));
frame.getContentPane().add(westPanel, BorderLayout.WEST);
JPanel southPanel = new JPanel();
southPanel.setBackground(Color.YELLOW);
southPanel.setPreferredSize(new Dimension(0, 150));
frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
JPanel eastPanel = new JPanel();
eastPanel.setBackground(Color.BLUE);
eastPanel.setPreferredSize(new Dimension(200, 0));
frame.getContentPane().add(eastPanel, BorderLayout.EAST);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
output :
import javax.swing.*;
import java.awt.*;
public class Class1 {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel another = new JPanel();
JPanel emptyPanel = new JPanel();
emptyPanel.setPreferredSize(new Dimension(700, 50));
frame.setSize(700, 500);
panel.setMaximumSize(new Dimension(300, 200));
panel.setMinimumSize(new Dimension(300, 200));
panel.setPreferredSize(new Dimension(300, 200));
panel.setBackground(Color.green);
panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
another.add(emptyPanel, BorderLayout.NORTH);
another.add(panel, BorderLayout.CENTER);
frame.add(another);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
The created image looks like below
It looks to me that immediate child container of the JFrame is resized to the size of the JFrame, the top level container, itself.
I am relatively new to programming, so I am sorry if this question is stupid. I am creating a Java program that involves one JButton inside a JPanel, and the JPanel is in a JFrame. Another button is outside the JPanel but still in the JFrame. I set the layout to a BoxLayout. My problem is that the the panel, which I made black, is taking up the whole JFrame except for where the second button is. How do I make the JPanel so it is only taking up the area right around the first button?
public class alt {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button1 = new JButton("button 1");
JButton button2 = new JButton("button 2");
public alt(){
frame.setVisible(true);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
panel.setBackground(Color.black);
frame.setTitle("test");
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
panel.add(button1);
frame.add(panel);
frame.add(button2);
button2.setAlignmentX(Component.CENTER_ALIGNMENT);
}
}
You could make use of a different layout manager, one which gives you more control over deciding how space is allocated and filling is handled, for example, GridBagLayout...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SampleLayout {
public static void main(String[] args) {
new SampleLayout();
}
public SampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel panel = new JPanel();
JButton button1 = new JButton("button 1");
JButton button2 = new JButton("button 2");
panel.setBackground(Color.black);
panel.add(button1);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(panel, gbc);
frame.add(button2, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at Laying Out Components Within a Container for more details
The reason why your panel takes up the bulk of the frame's content pane lies
in the way the BoxLayout manager works with the minimum, preferred,
and maximum values of components. It takes the maximum value of a component
into account. And since the maximum value of a JPanel is huge, it takes
all the space available. The solution is to change the maximum value
of a panel. However, this is bad practice. I do not recommend to use
the BoxLayout manager -- it is very weak and leads to poor code.
I recommend to use either the MigLayout manager or the GroupLayout manager.
I provide three solutions: a corrected BoxLayout solution, a MigLayout solution,
and a GroupLayout solution.
BoxLayout solution
We determine the maximum size of the button and change the panel's size
to be a bit larger than the button's.
package com.zetcode;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BoxLayoutPanel extends JFrame {
public BoxLayoutPanel() {
initUI();
}
private void initUI() {
JPanel cpane = (JPanel) getContentPane();
cpane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
cpane.setLayout(new BoxLayout(cpane,
BoxLayout.Y_AXIS));
JPanel pnl = new JPanel();
JButton btn1 = new JButton("Button 1");
JButton btn2 = new JButton("Button 2");
Dimension dm = btn1.getMaximumSize();
dm.height += 15;
dm.width += 15;
pnl.setMaximumSize(dm);
pnl.setBackground(Color.black);
add(pnl);
add(Box.createVerticalStrut(10));
pnl.add(btn1);
btn2.setAlignmentX(Component.CENTER_ALIGNMENT);
add(btn2);
setTitle("BoxLayout solution");
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
BoxLayoutPanel ex = new BoxLayoutPanel();
ex.setVisible(true);
}
});
}
}
This is not a clean solution. Generally, we should avoid calling the getMaximumSize() and
the setMaximumSize() in the application code -- this is the layout manager's job. Also in three occasions, we use fixed pixel widths: when we define an empty border, a vertical strut, and a maximum panel's size. This code is however not portable.
Pixel widths change when the resolution of the screen changes. This is a
shortcoming of the BoxLayout manager.
MigLayout solution
This solution is much cleaner and more portable. MigLayout is a third-party
manager, so we need to download additional libraries.
package com.zetcode;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutPanel extends JFrame {
public MigLayoutPanel(){
initUI();
setTitle("MigLayout solution");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initUI() {
JPanel main = new JPanel(new MigLayout("center"));
JPanel pnl2 = new JPanel();
JButton btn1 = new JButton("Button 1");
JButton btn2 = new JButton("Button 2");
pnl2.setBackground(Color.black);
pnl2.add(btn1);
main.add(pnl2, "wrap");
main.add(btn2, "alignx center");
add(main);
pack();
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutPanel ex = new MigLayoutPanel();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout is a built-in layout manager. With MigLayout, they are the most
portable and flexible layout managers.
package com.zetcode;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.CENTER;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
public class GroupLayoutPanel extends JFrame {
public GroupLayoutPanel(){
initUI();
setTitle("GroupLayout solution");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JPanel pnl = new JPanel();
JButton btn1 = new JButton("Button 1");
pnl.add(btn1);
JButton btn2 = new JButton("Button 2");
pnl.setBackground(Color.black);
gl.setAutoCreateGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
.addGroup(gl.createParallelGroup(CENTER)
.addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(btn2))
.addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addContainerGap()
.addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addPreferredGap(RELATED)
.addComponent(btn2)
.addContainerGap()
);
pack();
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GroupLayoutPanel ex = new GroupLayoutPanel();
ex.setVisible(true);
}
});
}
}
I just got back into coding, so my apologies for my noobines. I'm trying to create a simple program, with a menu where there is a background, and then in the center is a border, containing two buttons. I've sadly had no idea on how to make my JPanel (background), the background, and have my JPanel (main), just in the center not interfering with anything else.
Here is my code:
package me.niknea.supremeinvasion.menus;
import javax.swing.*;
import java.awt.*;
/**
* Created by Niknea on 7/20/14.
*/
public class Login extends JFrame{
JPanel background, main;
JButton loginButton, registerButton;
public Login(){
super("SupremeInvasion");
selector();
this.setSize(300, 300);
this.setVisible(true);
}//end SimpleGui
public void selector(){
main = new JPanel();
background = new JPanel();
registerButton = new JButton("Register");
loginButton = new JButton("Login");
main.setBackground(Color.LIGHT_GRAY);
background.setBackground(Color.CYAN);
main.add(registerButton);
main.add(loginButton);
main.setBorder(BorderFactory.createLineBorder(Color.BLACK));
main.setBorder(BorderFactory.createTitledBorder(""));
background.setLayout(new BorderLayout());
background.add(main, BorderLayout.CENTER);
this.add(background);
}
}
And a picture of how it looks : http://gyazo.com/e19aa2f86a53ae08e59218e958b766fa, as you can see, the buttons arent centered, nor is the background cyan with only the center being gray with the buttons.
Thanks again,
Niknea.
the buttons arent centered
If you want the buttons horizontally and vertically centered the easiest way is to use a GridBagLayout on the "backgroundPanel".
nor is the background cyan with
That is because the "main" panel completely covers the background panel. Make the "main" panel opaque by using:
main.setOpaque(false);
Try it again after removing below line from your code.
background.setLayout(new GridBagLayout());
and simply add main panel in background panel.
background.add(main);
For further reading, please follow Swing Tutorial on How to Use Various Layout Managers
Is this what you want?
You must set BorderLayout to background. It's default is FlowLayout. You can set a BorderLayout to the panel background and setPreferredSize to the panel main.
background.setLayout(new BorderLayout());
I cannot recommend using GridBagLayout manager. It has many drawbacks.
I have created two examples with MigLayout and GroupLayout.
I am not sure whether the user really needs a separate panel for
the two buttons. (People often seem to think that we need
a panel for such a task when in reality it is not needed.)
But nevertheless I have placed to buttons into a panel and
centered the panel on the window.
Solution with MigLayout
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class CenteredButtons extends JFrame {
public CenteredButtons() {
initUI();
setSize(300, 250);
setTitle("Centered buttons");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("center, center"));
JPanel cpnl = new JPanel();
cpnl.setBorder(BorderFactory.createEtchedBorder());
cpnl.add(new JButton("Register"));
cpnl.add(new JButton("Login"));
add(cpnl);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CenteredButtons ex = new CenteredButtons();
ex.setVisible(true);
}
});
}
}
Solution with GroupLayout
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CenteredButtons2 extends JFrame {
public CenteredButtons2() {
initUI();
setTitle("Centered buttons");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JPanel cpnl = new JPanel();
cpnl.setBorder(BorderFactory.createEtchedBorder());
cpnl.add(new JButton("Register"));
cpnl.add(new JButton("Login"));
gl.setHorizontalGroup(gl.createSequentialGroup()
.addGap(1, 100, Short.MAX_VALUE)
.addComponent(cpnl, GroupLayout.DEFAULT_SIZE,
GroupLayout.DEFAULT_SIZE,GroupLayout.PREFERRED_SIZE)
.addGap(1, 100, Short.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGap(1, 100, Short.MAX_VALUE)
.addComponent(cpnl, GroupLayout.DEFAULT_SIZE,
GroupLayout.DEFAULT_SIZE,GroupLayout.PREFERRED_SIZE)
.addGap(1, 100, Short.MAX_VALUE)
);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CenteredButtons2 ex = new CenteredButtons2();
ex.setVisible(true);
}
});
}
}
I have been trying to make a layout with MigLayout that consists of 3 panels, one on the right, one on top, and one that fills the rest of the space.
Like this:
There are several solutions possible. I provide two examples.
In both examples we also set the preferred width and height of
the panels. Normally, the panels would derive their preferred with from
their children.
The first layout is done with the dock constraint.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutThreePanels extends JFrame {
public MigLayoutThreePanels() {
initUI();
setTitle("Three panels");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout());
JPanel pnl1 = new JPanel();
pnl1.setBorder(BorderFactory.createEtchedBorder());
JPanel pnl2 = new JPanel();
pnl2.setBorder(BorderFactory.createEtchedBorder());
JPanel pnl3 = new JPanel();
pnl3.setBorder(BorderFactory.createEtchedBorder());
add(pnl2, "w 40, dock east");
add(pnl1, "h 40, dock north");
add(pnl3, "w 250, h 200, dock center");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutThreePanels ex = new MigLayoutThreePanels();
ex.setVisible(true);
}
});
}
}
The three panels are docked to east, north, and center. Additional spaces between
panels can be created with the gap constraints.
In the second example, we use utilize the grid structure.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutThreePanels2 extends JFrame {
public MigLayoutThreePanels2() {
initUI();
setTitle("Three panels");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("gap 3 3"));
JPanel pnl1 = new JPanel();
pnl1.setBorder(BorderFactory.createEtchedBorder());
JPanel pnl2 = new JPanel();
pnl2.setBorder(BorderFactory.createEtchedBorder());
JPanel pnl3 = new JPanel();
pnl3.setBorder(BorderFactory.createEtchedBorder());
add(pnl1, "h 40, growx");
add(pnl2, "w 40, spany 2, growy, wrap");
add(pnl3, "w 250, h 200, grow, push");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutThreePanels2 ex = new MigLayoutThreePanels2();
ex.setVisible(true);
}
});
}
}
In this example, we also set some gaps between the cells and container insets.