I am trying to make a game which looks something like this:
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!
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
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.
Related
so basically, when I add two panes to container with BorderLayout I have a something like padding and I have no idea how to fix it
below the code is a pic of what I mean
Container mainContainer = this.getContentPane(); //
mainContainer.setLayout(new BorderLayout(8, 6));
mainContainer.setBackground(Color.BLACK);
this.getRootPane().setBorder(BorderFactory.createMatteBorder(4, 4, 4, 4, Color.CYAN));
JPanel panelZTekstem = new JPanel();
panelZTekstem.setBackground(Color.ORANGE);
poleTekstowe.setEditable(false);
poleTekstowe.setText("0");
poleTekstowe.setSize(400, 100);
poleTekstowe.setOpaque(true);
poleTekstowe.setFont(new Font("MV Boli", Font.BOLD, 20));
poleTekstowe.setHorizontalAlignment(JTextField.RIGHT);
panelZTekstem.setLayout(new FlowLayout());
panelZTekstem.add(poleTekstowe);
mainContainer.add(panelZTekstem,BorderLayout.NORTH);
JPanel panelZLiczbami = new JPanel();
for (int i = 0; i <= 16; i++) {
JButton test = new JButton();
panelZLiczbami.add(test);
}
panelZLiczbami.setBackground(Color.BLUE);
mainContainer.add(panelZLiczbami, BorderLayout.CENTER);
when I add two panes to container with BorderLayout I have a something like padding
mainContainer.setLayout(new BorderLayout(8, 6));
What did you think the 8/6 values are used for?
You are creating a gap between the components.
It is best to read the API to understand how the parameters are used.
Can somebody explain me how can I put few jButtons inside jLabel which have background image like on this image? The main jFrame is undecorated and is set to full screen.
I saw a lot of different examples like
this or like this, but these examples are showing only single button in jPanel.
Personally, I'd avoid using a JLabel for this purpose, it does not calculate it's required size based on it's content, but rather off it's icon and text properties.
This might be a good or bad thing, but it can catch your unawares if you're not aware of it.
Instead, I'd use a customised JPanel, which would allow you to define things like the resize and fill rules, for example and for example
Now, once you have that covered, you need to create a panel of your buttons. I prefer to create a dedicated class, as it makes it easier to isolate functionality and management, but that's me...
public class ButtonPane extends JPanel {
public ButtonPane() {
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(8, 8, 8, 8));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(2, 2, 2, 2);
add(new JButton("Button 1"), gbc);
add(new JButton("Button 2"), gbc);
add(new JButton("Button 3"), gbc);
}
}
Next, you need to add this panel to your background
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(backgroundPane);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.SOUTHEAST;
gbc.insets = new Insets(30, 30, 30, 30);
ButtonPane buttonPane = new ButtonPane();
frame.add(buttonPane, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Which can generate something like...
Have a look at Laying Out Components Within a Container and How to Use GridBagLayout for some more details
These examples are truly good enough, I think you should just learn more about swing.
For now, You could simply do:
JFrame frame = new JFrame("Hi there");
JButton b1 = new JButton("1");
JButton b2 = new JButton("2");
frame.add(b1);
frame.add(b2);
b1.setBounds(60, 60, 40, 40);
b2.setBounds(10, 10, 40, 40);
frame.setVisible(true); //in case, add frame.setLayout(null);
You can of course add buttons to JPanel instead of JFrame
I need some help in JInternalFrame within JPanel's Area.I have a JFrame which contains
JPanel added to its ContentPane.JFrame Contains Menu when i click one of its Menu item i
need JInternal Frame to be added on top of the contentpane.The Code i have given so far,
JDesktopPane desktop = new JDesktopPane();
desktop.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0 };
gbl_contentPane.rowHeights = new int[] { 0, 0, 0, 0 };
gbl_contentPane.columnWeights = new double[] { 1.0, 6.0, 1.0,
Double.MIN_VALUE };
gbl_contentPane.rowWeights = new double[] { 0.0, 8.0, 0.0,
Double.MIN_VALUE };
topPanel.setLayout(gbl_contentPane);
JPanel left = new JPanel();
GridBagConstraints gbc_left = new GridBagConstraints();
gbc_left.insets = new Insets(0, 0, 5, 5);
gbc_left.fill = GridBagConstraints.BOTH;
gbc_left.gridx = 0;
gbc_left.gridy = 1;
topPanel.add(left, gbc_left);
JPanel middle = new JPanel();
GridBagLayout gbl_middle = new GridBagLayout();
gbl_middle.columnWeights = new double[] { 1.0 };
middle.setLayout(gbl_middle);
GridBagConstraints gbc_middle = new GridBagConstraints();
gbc_middle.insets = new Insets(0, 0, 5, 5);
gbc_middle.fill = GridBagConstraints.BOTH;
gbc_middle.gridx = 1;
gbc_middle.gridy = 1;
topPanel.add(middle, gbc_middle);
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 30;
middle.add(panel1, gbc);
panel1.setLayout(new MigLayout("", "[944.00,grow][353.00]",
"[6.00][128.00,grow][]"));
/*lblHeader = new JLabel(
"<html>Indira Institute of Technology<br>Tatabad<br>Karpagam Complex Stop<br>Coimbatre</html>");
lblHeader.setIcon(new ImageIcon(
"C:\\Users\\Prakash\\Desktop\\images.jpg"));
panel1.add(lblHeader, "cell 0 1 2 1,alignx center,aligny center");*/
JPanel panel2 = new JPanel();
gbc = new GridBagConstraints();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
gbc.insets = new Insets(2, 2, 2, 2);
middle.add(panel2, gbc);
panel2.setLayout(new MigLayout(
"",
"[30px][69.00px][144.00][68.00][][159.00px][59.00px][65px][28.00][]",
"[20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][30.00][48.00:n,grow 50,shrink 50]"));
getContentPane.add(topPanel);
I have never used the DesktopPane in this(I don't know how to make use of this in this situation) And The Screen So far is as follows,
Now I need the JInternalFrame to be added for the Previous Screen as Follows,
I am aware that i can only be able to add a JInternalFrame to the DesktopPane.But i
Already Filled my ContentPane with JPanel to show its content.How can i achieve Jinternal
Frame to be added in this JFrame.Kindly give your valuable suggestions.
Not really the right direction. You original panel is under the control of layout manager, this means that when you add the JInternalFrame to it, the layout manager wants to try and layout it out.
Generally speaking, a JInternalFrame wants to reside in a container which is unmanaged, allowing it to be positioned and sized independently of the content.
A possible solution might be to take advantage of the glass pane for the JInternalFrame instead, for more details see How to Use Root Panes
Another solution might be to use a JLayeredPane. Basically, you would start by setting the layout manager of the JLayeredPane to something link BorderLayout add the first panel to it and then add a second, transparent pane, with no layout, above it. You would add the JInternalFrames to this second panel.
See How to Use Layered Panes for more details
The question that jumps out at me though is...why? Why wouldn't you just use some kind of dialog instead? See How to Make Dialogs for more details
What is it what you really want?
You wrote you already have your content pane added to your frame. JDesktopPane has to have its own space reserved. If you don't have or you don't want to reserve space for the internal frames in your main frame, then maybe you don't even want it to be part of the main frame. In this case you might want to use child JDialogs instead of JInternalFrames.
So either add your JDesktopPane to your main frame (having its space reserved) or use child JDialogs which can be modal or not and can overlap any part of the main frame. JInternalFrames are only visible in the area of the JDesktopPane while child JDialogs can "float" over your main frame.
Check out this Oracle documentation: How to Use Internal Frames
And How to Make Dialogs.
I am trying to make a 3 column layout, in each column i want to be able to absolute position labels and textboxes.
Problem is that my label (jLabel2) never even gets displayed..
Here is my code:
/**
* Top JPanel (Top)
*/
JPanel pnlTop = new JPanel();
pnlTop.setBackground(new java.awt.Color(223, 223, 217));
pnlTop.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new java.awt.Color(173, 173, 166)));
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 5; // five rows
c.gridheight = 1; // one column
c.fill = GridBagConstraints.BOTH;
//c.weighty = 0.04;
add(pnlTop, c);
/**
* Top JPanel Content (Here is where i want to put absolute content)
*/
JPanel pnlTopContent = new JPanel();
pnlTopContent.setLayout(null);
jLabel2.setFont(new java.awt.Font("Lucida Grande", 1, 16)); // NOI18N
jLabel2.setText("Hello");
jLabel2.setLocation(150, 50);
pnlTopContent.add(jLabel2);
pnlTop.add(pnlTopContent);
Any ideas what i am doing wrong?
Then its showing but not in the right place
What does "right place" mean to you? Why are you even adding you label to a second panel? Why not just add the label directly to the pnlTopContent?
GridBagLayout has a constraint that allows you to position the component right/left/center of the column. Read the section from the Swing tutorial on How to Use GridBagLayout. You might want to start with the anchor constraint.
Use layout manager for pnlTopContent. Which one is right depends on what you want. Even the default FlowLayout might work. If you want to center the label, you can for example use FlowLayout with center alignment:
pnlTopContent.setLayout(new FlowLayout(FlowLayout.CENTER));
I want to shorten my text field so it doesn't stretch to to the end of my jframe so this is how it looks now:
How do control the width of the textfield so it does't streatch like that I tried setPreferedSize() and setSize() yet they didn't work??
#Override
public void run() {
JFrame frame = new JFrame("Test Calculator");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(500, 500);
JPanel panel = new JPanel(new GridBagLayout());
frame.getContentPane().add(panel, BorderLayout.NORTH);
GridBagConstraints c = new GridBagConstraints();
JLabel testLabel = new JLabel("Enter Score For Test 1: ");
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(40, 15, 15, 0);
panel.add(testLabel , c);
JTextField txtField1 = new JTextField("TextField");
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = .5;
panel.add(txtField1 , c);
}
You're telling the layout that the text field must fill horizontally, so that's what it does. Replace
c.fill = GridBagConstraints.HORIZONTAL;
by
c.fill = GridBagConstraints.NONE;
First and foremost, get rid of this:
frame.setSize(500, 500);
Instead let your components and layout managers size themselves by calling pack() on your JFrame after filling it and before setting it visible.
Next, consider either adding an empty border around your main container, or else adding an empty JLabel to your GridBagLayout using container.
You can also give your JTextField appropriate insets to give a cushion around it.
c.insets = new Insets(40, 15, 15, 40);
panel.add(txtField1, c);
You can change how many columns a particular component takes up by changing GridBagConstraints gridwidth field.
//this would make the next component take up 2 columns
c.gridwidth = 2;
You could have a jpanel and set its dimensions and layout, then add the elements to that panel and add the panel to your jframe.
There are different layout types that can be used depending on what you need to be done. I usually like to use Box's. They have methods that allow you to create horizontal/vertical struts, create rigid areas(this is what I usually use)
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createVerticalBox();
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(testLabel);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(txtField1);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box2.add(Box.createRigidArea(new Dimension(0,30)));
box2.add(box1);
box2.add(Box.createRigidArea(new Dimension(0,30)));
JFrame.add(box2);
Check this link out for descriptions and how to use all the different kinds of layouts: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html