0

I am trying to make a game which looks something like this: Layout Design

I'm trying to find the most suitable layout design for this. I tried using gridbag layout but there are some components which are not added correctly. This is my code:

//Gridbag for the whole frame
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
this.setLayout(gridbag);
constraints.fill = GridBagConstraints.BOTH;
constraints.insets = new Insets(10, 10, 10, 10);
constraints.weightx = 0.5;

//Top left panel
pnlHP = new JPanel();
pnlHP.setBackground(new Color (75, 55, 28));
gridbag.setConstraints(pnlHP, constraints);
this.add(pnlHP);

GridBagLayout gridbagHP = new GridBagLayout();
GridBagConstraints constraintsHP = new GridBagConstraints();
pnlHP.setLayout(gridbagHP);
constraintsHP.fill = GridBagConstraints.BOTH;
constraintsHP.insets = new Insets(10, 10, 10, 10);
constraintsHP.weightx = 1.0;

lblHPTitle = new JLabel();
lblHPTitle.setText("HP");
lblHPTitle.setForeground(Color.WHITE);
lblHPTitle.setFont(new Font("Arial", Font.PLAIN, 60));
gridbagHP.setConstraints(lblHPTitle, constraintsHP);
pnlHP.add(lblHPTitle);

lblHP = new JLabel();
lblHP.setText("asdf");
lblHP.setForeground(Color.WHITE);
lblHP.setFont(new Font("Arial", Font.PLAIN, 20));
lblHP.setHorizontalAlignment(SwingConstants.RIGHT);
constraintsHP.gridwidth = GridBagConstraints.REMAINDER;
gridbagHP.setConstraints(lblHP, constraintsHP);
pnlHP.add(lblHP);

pgbHP = new JProgressBar();
pgbHP.setBackground(new Color (75, 55, 28));
pgbHP.setValue(25);
constraintsHP.weightx = 0.0;
gridbagHP.setConstraints(pgbHP, constraintsHP);
pnlHP.add(pgbHP);

//Top center part
btnGo = new JButton();
btnGo.setBackground(new Color (126, 72, 28));
btnGo.setText("Start Adventure!");
btnGo.setForeground(Color.WHITE);
btnGo.setFont(new Font("Arial", Font.PLAIN, 42));
gridbag.setConstraints(btnGo, constraints);
this.add(btnGo);

//Top right panel
pnlMPSP = new JPanel();
pnlMPSP.setBackground(new Color (75, 55, 28));
constraints.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(pnlMPSP, constraints);
this.add(pnlMPSP);

GridBagLayout gridbagMPSP = new GridBagLayout();
GridBagConstraints constraintsMPSP = new GridBagConstraints();
pnlMPSP.setLayout(gridbagMPSP);
constraintsMPSP.fill = GridBagConstraints.BOTH;
constraintsMPSP.insets = new Insets(10, 10, 10, 10);
constraintsMPSP.weightx = 1.0;

lblMPSP = new JLabel();
lblMPSP.setText("asdf");
lblMPSP.setForeground(Color.WHITE);
lblMPSP.setFont(new Font("Arial", Font.PLAIN, 20));
gridbagMPSP.setConstraints(lblMPSP, constraintsMPSP);
pnlMPSP.add(lblMPSP);

lblMPSPTitle = new JLabel();
lblMPSPTitle.setText("MP");
lblMPSPTitle.setForeground(Color.WHITE);
lblMPSPTitle.setFont(new Font("Arial", Font.PLAIN, 60));
lblMPSPTitle.setHorizontalAlignment(SwingConstants.RIGHT);
constraintsMPSP.gridwidth = GridBagConstraints.REMAINDER;
gridbagMPSP.setConstraints(lblMPSPTitle, constraintsMPSP);
pnlMPSP.add(lblMPSPTitle);

pgbMPSP = new JProgressBar();
pgbMPSP.setBackground(new Color (0, 0, 255));
pgbMPSP.setValue(25);
constraintsMPSP.weightx = 0.0;
gridbagMPSP.setConstraints(pgbMPSP, constraintsMPSP);
pnlMPSP.add(pgbMPSP);

//Middle Left
lblNotifications = new JLabel();
lblNotifications.setText("<html>N<br>o<br>t<br>i<br>f<br>i<br>c<br>a<br>t<br>i<br>o<br>n<br>s</html>");
lblNotifications.setFont(new Font("Arial", Font.PLAIN, 20));
lblNotifications.setBackground(Color.WHITE);
gridbag.setConstraints(lblNotifications, constraints);
this.add(lblNotifications);

//Middle Center
txtNotifCenter = new JTextPane();
txtNotifCenter.setBackground(new Color (205, 160, 96));
txtNotifCenter.setEnabled(false);
txtNotifCenter.setDisabledTextColor(Color.black);
scpNotifCenter = new JScrollPane(txtNotifCenter);
scpNotifCenter.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
gridbag.setConstraints(scpNotifCenter, constraints);
this.add(scpNotifCenter);

//Middle Right
txtXPInfo = new JTextPane();
txtXPInfo.setBackground(new Color (205, 160, 96));
txtXPInfo.setEnabled(false);
txtXPInfo.setDisabledTextColor(Color.black);
scpXPInfo = new JScrollPane(txtXPInfo);
scpXPInfo.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
constraints.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(scpXPInfo, constraints);
this.add(scpXPInfo);

//I haven't made the bottom part yet

this.pack();

If this was run, the lblNotifications and txtNotifCenter (or scpNotifCenter) seemed to have the same width. I wanted to make it like in the picture. Am I supposed to use another layout, or am I just using the gridbag layout in the wrong way? Thank you in advance!

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Grandevox
  • 92
  • 2
  • 8
  • 2
    One possible solution is not to use a single layout but rather to nest JPanels, each using its own layout. Another option is to use a more flexible 3rd party layout such as MiGLayout. – DontKnowMuchBut Getting Better May 17 '17 at 14:42
  • 2
    `I'm trying to find the most suitable layout design for this.` - you are never restricted to a single layout manager. You can nest panels each using a different layout manager to achieve you desired layout. So the key to design the screen logically using the appropriate layout manager for a group of components. – camickr May 17 '17 at 14:42
  • @DontKnowMuchButGettingBetter would nesting JPanels be very heavy to the program? – Grandevox May 17 '17 at 14:55
  • @camickr could you show me an example of how to nest layout managers? Or at least a link will be very much appreciated! – Grandevox May 17 '17 at 14:56
  • Heck no. It would be better in the long run since you could create separate "view" or GUI classes for separate regions of the GUI. – DontKnowMuchBut Getting Better May 17 '17 at 15:26
  • @DontKnowMuchButGettingBetter okay then I'll try that. Thanks for your suggestion! – Grandevox May 17 '17 at 15:36
  • *"an example of how to nest layout managers"* See [this answer](http://stackoverflow.com/a/5630271/418556). – Andrew Thompson May 18 '17 at 05:54
  • @AndrewThompson thank you! I'll check it out – Grandevox May 18 '17 at 16:55

2 Answers2

1

It is unsure which parts of your screen are components and which are not (for example is the hp display one component or a group of them?) but GridBagLayout can certainly do what you want.

The key is not to try and do it all with one GridBagLayout, since then everything needs to line up in a grid.

Instead split your screen into three rows. Use on layout to arrange the three rows (for example BoxLayout) and then use a separate layout manager inside each row (for example GridBagLayout) to lay out the components within that row.

Tim B
  • 40,716
  • 16
  • 83
  • 128
  • Could you show me an example of how to do that? Or at least a link will be very much appreciated! – Grandevox May 17 '17 at 14:57
  • Just create 3 JPanels. Arrange them one under the other. Put the top row of controls in the first JPanel. The next row in the middle JPanel. The bottom one in that JPanel. Layout each row however you like. – Tim B May 17 '17 at 15:08
  • Okay, I'll try that. Thank you for your suggestion! – Grandevox May 17 '17 at 15:27
1

GridBagLayout is very difficult to use and only people that are a glutton for punishment try to use it. It was actually originally intended to be used by GUI builders rather than be coded by hand.

You should use nested layouts. You actually have a pretty standard layout. For your main window use BorderLayout (and this is the default layout of all top-level containers like JFrame).

Your HP, Start Adventure, and MP will be in a JPanel that uses a X_AXIS BoxLayout (JPanels use FlowLayout by default, so you will have to set it to BoxLayout). That JPanel will go in the NORTH position of the BorderLayout.

Your two notification text areas would probably go best in a JSplitPane (with one text area on the left side, the other text area on the right side), then put the split pane in the CENTER of the BorderLayout.

Then your CharMode, Level, and Logout will be in yet another JPanel using X_AXIS BoxLayout. That JPanel will go in the SOUTH position of your BorderLayout.

Tutorials for Border and Box Layouts:

https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html

Split Panes:

https://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html

Michael
  • 2,683
  • 28
  • 30
  • Thank you! This works very well with what I was trying to achieve! – Grandevox May 18 '17 at 16:54
  • You may want to consider using JavaFX instead of Swing (JavaFX is the replacement for Swing). With JavaFX you can use SceneBuilder to build the GUI (you can still use the same general layout I described...it has HBox and VBox instead of BoxLayout with an axis specified). In addition you can style JavaFX components with a very CSS-like syntax. You can probably get it to look exactly like your mockup. JavaFX getting started links here: http://docs.oracle.com/javase/8/javase-clienttechnologies.htm CSS: http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/css_tutorial.htm#JFXUI733 – Michael May 18 '17 at 17:10
  • Okay I'll look into it. Thanks! – Grandevox May 18 '17 at 17:25