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.
Related
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.
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);
}
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'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
I have this problem where the JPanel (contentPane) re-sizes (testLabel) GUI components to be really small whenever they are too big to fit in the panel. I have added scrollbars to the JPanel but the components still re-size instead of using the scrollbars. Here is my class where I use the JPanel with scrollbars.
package marsPackage;
import java.awt.*;
import javax.swing.*;
public class DashTab{
private JLabel testLabel; //test label
private JLabel testLabel2;
private JLabel testLabel3;
private JLabel testLabel4;
private JPanel dashPanel; //Panel that holds the JTabbedPane tab
private JPanel contentPane; // Panel that holds all GUI components
private JScrollPane scrollPane; // Scrollpane used on contentPane
/*
* Constructor
* All of your GUI components should be added to
* contentPane using the gridBagLayout.
*/
public DashTab(){
//Creating the dashpanel that holds everything
dashPanel = new JPanel();
dashPanel.setBackground(Color.WHITE);
//Creating the contentPane that holds all GUI components and
//uses vertical/horizontal sidebards as needed
contentPane = new JPanel();
contentPane.setBackground(Color.WHITE);
//Giving the contentPane the GridBagLayout
contentPane.setLayout(new GridBagLayout());
GridBagConstraints g = new GridBagConstraints();
contentPane.setPreferredSize(new Dimension(857, 725));
//Adding scrollPane to Content Pane and adding those two to dashPanel
scrollPane = new JScrollPane(contentPane);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBackground(Color.WHITE);
dashPanel.add(scrollPane);
/*
* You may begin adding your GUI components from this point forward.
* Remember to only use GridBagLayout with GridBagConstraints using the
* g variable.
*/
testLabel = new JLabel("Testing Here 1");
testLabel.setPreferredSize(new Dimension(500, 500));
testLabel.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.gray));
g.gridx = 0;
g.gridy = 0;
contentPane.add(testLabel, g);
testLabel2 = new JLabel("Testing Here 2");
testLabel2.setPreferredSize(new Dimension(250, 200));
testLabel2.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.gray));
g.gridx = 1;
g.gridy = 0;
contentPane.add(testLabel2, g);
testLabel3 = new JLabel("Testing Here 3");
testLabel3.setPreferredSize(new Dimension(200, 200));
testLabel3.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.gray));
g.gridx = 1;
g.gridy = 1;
contentPane.add(testLabel3, g);
testLabel4 = new JLabel("Testing Here 4");
testLabel4.setPreferredSize(new Dimension(200, 200));
testLabel4.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.gray));
g.gridx = 2;
g.gridy = 2;
contentPane.add(testLabel4, g);
}
/**
* The getDashTab method returns a DashTab object.
* #return a DashTab panel object.
*/
public JPanel getDashTab(){
return dashPanel;
}
}
This is how the above code looks like:
Whenever I remove contentPane.setPreferredSize(new Dimension(857, 725)); the panel just stretches out and complete ignores the scrollbars making it look like:
contentPane.setPreferredSize(new Dimension(857, 725));
Don't use the setPreferredSize() method to set the size. That is the job of the layout manager, in this case, the GridBagLayout to determine the size of the panel.
Scrollbars will appear automatically when the preferred size of the panel is greater than the size of the scrollpane.
GUI components to be really small whenever they are too big to fit in the panel.
The GridBagLayout will try to respect the preferred size of the component. If the preferred size is greater than the size of the panel, then the components "minimum size" will be used. In the case of a JLabel, the minimum size is the space needed to entirely display the text.
Once again, don't try to use the setPreferedSize() method.