I have a vision for a project - a multiplayer, web based browser game where users can create rooms and invite their friends. However, I am currently lacking some severe knowledge to build this. Thus, I have decided to build a series of smaller projects to build gain knowledge in one area at a time.
To familiarize myself with networking and sockets, I am building a Java based chat app, using Swing for the GUI. I wanted to keep my design minimal, with two panels. Panel 1 will have 3 components: a label for a prompt, a text field to enter a nickname, and a button to connect, like so:
Right away, I ran into a problem: I could not for the life of me get all three of my components to be both stacked and centered (along both the x and y axis). Messing around with different layout managers resulted in my components being stacked vertically but residing in the top left corner, or cenetered but all 3 components stacked horizontally.
Two trivial solutions came to me:
- Manually manipulate each component by adjusting its pixels so they go in the positions I wanted. This code will totally be maintainable.
- Move on with the project and focus on the functionality. This is actually the option I chose at first, but after many iterations of starting up the GUI over and over for testing, the uncentered elements turned into an itch that I needed to scratch.
After much experimentation, I was able to find two Layout Managers that each did one part of what I wanted:
Using a BoxLayout layout manager, I was able to stack components together vertically:
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS);
JLabel label1 = new JLabel("label1");
JLabel label2 = new JLabel("label2");
panel.add(label1);
panel.add(label2);
Using a GridBagLayout layout manager with default GradBagConstraints, I was able to center my components:
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
panel.add(label1, gbc);
panel.add(label2, gbc);
To my surprise, I was able to nest layout managers within layout managers. By nesting my BoxLayout within my GridBagLayout, I was able to achieve my intended result:
public class TestVerticalAlignement {
protected void initUI() {
final JFrame frame = new JFrame();
frame.setTitle("Test vertical alignement");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JLabel label = new JLabel("Enter a nickname: ");
JTextField textField = new JTextField();
JButton button = new JButton("Connect");
panel.add(label);
panel.add(textField);
panel.add(button);
outerPanel.add(panel, gbc);
frame.add(outerPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new TestVerticalAlignement().initUI());
}
}