Here is my code. When I resize the program the other layouts, it works fine except for the CheckPanel (with GridBagLayout); somehow it became bigger. How can I handle this?
Advance Thanks.
JPanel CheckPanel = new JPanel();
CheckPanel.setBackground(Color.WHITE);
GridBagConstraints gbc_CheckPanel = new GridBagConstraints();
gbc_CheckPanel.gridwidth = 2;
gbc_CheckPanel.fill = GridBagConstraints.BOTH;
gbc_CheckPanel.gridx = 0;
gbc_CheckPanel.gridy = 1;
CenterPanel.add(CheckPanel, gbc_CheckPanel);
CheckPanel.setLayout(new GridLayout(0, 6, 0, 0));
The constraint
gbc_CheckPanel.fill = GridBagConstraints.BOTH;
tells the GridBagLayout to let this component use any available extra space (also depending on its preferred- and maximum size). Using GridBagConstraints.NONE or GridBagConstraints.VERTICAL could solve this, but you still have to decide which component will receive the extra space.
EDIT: Based on the comments, it is still not clear how the other components are inserted, and how the distribution of extra space is specified. In this example, the weighty fields are used to say that the table should receive all extra space. Maybe it helps to identify differences to the original program:
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class CheckboxConstraints
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.setBackground(Color.RED);
fill(centerPanel);
f.getContentPane().setLayout(new GridLayout(1,1));
f.getContentPane().add(centerPanel);
f.setSize(500, 300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static void fill(JPanel centerPanel)
{
addSearchBar(centerPanel);
addCheckBoxPanel(centerPanel);
addTable(centerPanel);
}
private static void addSearchBar(JPanel centerPanel)
{
GridBagConstraints gbc = null;
gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0;
gbc.weighty = 0;
centerPanel.add(new JButton("Search"), gbc);
gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 0;
centerPanel.add(new JTextField(), gbc);
}
private static void addCheckBoxPanel(JPanel centerPanel)
{
JPanel checkPanel = new JPanel();
checkPanel.setBackground(Color.WHITE);
GridBagConstraints gbc_CheckPanel = new GridBagConstraints();
gbc_CheckPanel.gridwidth = 2;
gbc_CheckPanel.fill = GridBagConstraints.BOTH;
gbc_CheckPanel.gridx = 0;
gbc_CheckPanel.gridy = 1;
gbc_CheckPanel.weighty = 0;
centerPanel.add(checkPanel, gbc_CheckPanel);
checkPanel.setLayout(new GridLayout(0, 6, 0, 0));
checkPanel.add(new JCheckBox("C0"));
checkPanel.add(new JCheckBox("C1"));
checkPanel.add(new JCheckBox("C2"));
checkPanel.add(new JCheckBox("C3"));
checkPanel.add(new JCheckBox("C4"));
checkPanel.add(new JCheckBox("C5"));
}
private static void addTable(JPanel centerPanel)
{
JTable table = new JTable(new Object[][] {
{"C00", "C01" },
{"C00", "C01" },
}, new Object[]{ "H0", "H1" });
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weighty = 1.0;
JScrollPane scrollPane = new JScrollPane(table);
centerPanel.add(scrollPane, gbc);
}
}
Please try:
gbc_CheckPanel.fill =GridBagConstraints.HORIZONTAL
and to adjust the space vertically
gbc_CheckPanel.ipady = 20; //Not sure this works in your case but this should fix the resizing issue
Another solution is to add a new JPanel with BorderLayout and insert the panel with JCheckBoxes using the constraint BorderLayout.NORTH and the table with constraint BorderLayout.CENTRE
Related
I want to build this same frame in the image with Layout Manager
What I already did:
Used BorderLayout to add all three JLabel to BorderLayout.WEST(Used GridLayout(3,1).
Used BorderLayout to add all three JTextField to BorderLayout.CENTER(used GridLayout(3,1).
I build this frame by manually adding components using the setBounds method.
Here's my implementation of your screen capture.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class SmplForm implements Runnable {
#Override // java.lang.Runnable
public void run() {
createAndDisplayGui();
}
private void createAndDisplayGui() {
JFrame frame = new JFrame("Nonce creator");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createForm(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
JButton proceedButton = new JButton("Proceed");
buttonsPanel.add(proceedButton);
return buttonsPanel;
}
private JPanel createForm() {
JPanel form = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.insets.top = 5;
JLabel transactionLabel = new JLabel("Transaction");
form.add(transactionLabel, gbc);
gbc.gridx = 1;
JTextField transactionTextField = new JTextField(20);
form.add(transactionTextField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
JLabel nonceLabel = new JLabel("Nonce");
form.add(nonceLabel, gbc);
gbc.gridx = 1;
JTextField nonceTextField = new JTextField(20);
form.add(nonceTextField, gbc);
gbc.gridx = 2;
JCheckBox autoCheckBox = new JCheckBox("Auto");
form.add(autoCheckBox, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
JLabel hashLabel = new JLabel("Hash");
form.add(hashLabel, gbc);
gbc.gridx = 1;
JTextField hashTextField = new JTextField(20);
hashTextField.setText("8350e5a3e24c153df2275c9f80692773");
hashTextField.setEnabled(false);
form.add(hashTextField, gbc);
return form;
}
public static void main(String[] args) {
EventQueue.invokeLater(new SmplForm());
}
}
This GUI has three slight tweaks, the first two as seen in the example by Abra:
The button is center aligned.
The label for the check box is to the right of the check.
The labels are right aligned.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class NonceCreator {
private JComponent ui = null;
NonceCreator() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridBagLayout());
ui.setBorder(new EmptyBorder(20,30,20,30));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5,5,5,5);
// add the labels
gbc.anchor = GridBagConstraints.EAST;
ui.add(new JLabel("Transaction"), gbc);
gbc.gridy = 1;
ui.add(new JLabel("Nonce"), gbc);
gbc.gridy = 2;
ui.add(new JLabel("Hash"), gbc);
gbc.anchor = GridBagConstraints.WEST;
// add the text fields
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 2;
ui.add(new JTextField(30), gbc);
gbc.gridy = 2;
JTextField hashField = new JTextField(
"8350e5a3e24c153df2275c9f80692773", 30);
hashField.setEditable(false);
ui.add(hashField, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1;
ui.add(new JTextField(20), gbc);
// add the check box
gbc.gridx = 2;
ui.add(new JCheckBox("Auto"), gbc);
// add the button
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 3;
gbc.anchor = GridBagConstraints.CENTER;
ui.add(new JButton("Proceed"), gbc);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
NonceCreator o = new NonceCreator();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I don't use a visual GUI Builder. I think you can use GroupLayout or GridBagLayout for a flexible design. Also you can use a design tool like Adobe XD, and convert this to Java. That will be easier.
Look at;
https://docs.oracle.com/javase/tutorial/uiswing/layout/group.html
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
I am having issues with GridBagLayout & GridBagConstraints in a GUI I am beginning to build. I have to pictures, one of the current state of the GUI, & one of the desired state of the GUI. I have been trying to reach the desired state but have been unable to :(. Here is the code, & I will also attach the 2 pictures I mentioned above. Moreover, there is an issue with the way that I am formatting the first or second checkbox, but I have been unable to figure out what the issue is.
Driver Class:
import javax.swing.SwingUtilities;
public class Driver {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TheFrame();
}
});
}
}
JFrame Class:
import javax.swing.JFrame;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class TheFrame extends JFrame {
//Declarations
private GridBagConstraints gbc;
private String myString;
private JLabel selectionLab;
private JCheckBox defconLevel1;
private JCheckBox defconLevel2;
private JCheckBox defconLevel3;
private JCheckBox defconLevel4;
private JCheckBox defconLevel5;
public TheFrame() {
super("DEFCON DEACTIVATOR");
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new GridBagLayout());
//Initialization
gbc = new GridBagConstraints();
selectionLab = new JLabel("Please Select DECON Level");
defconLevel1 = new JCheckBox("DEFCON 1");
defconLevel2 = new JCheckBox("DEFCON 2");
defconLevel3 = new JCheckBox("DEFCON 3");
defconLevel4 = new JCheckBox("DEFCON 4");
defconLevel5 = new JCheckBox("DEFCON 5");
//Configuration
//Add to contentPane
//ROW 1
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = gbc.NORTH;
gbc.weighty = 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(selectionLab);
//ROW 2
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel1,gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel2,gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel3,gbc);
gbc.gridx = 3;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel4,gbc);
gbc.gridx = 4;
gbc.gridy = 1;
gbc.anchor = gbc.NORTH;
gbc.weighty= 1;
gbc.insets = new Insets(0,0,0,0);
this.getContentPane().add(defconLevel5,gbc);
}
}
Updated Code:
Driver Class
import javax.swing.SwingUtilities;
public class Driver {
//Declarations
private static SelectionPanel selectionPanel;
private static HeaderPanel headerPanel;
private static TheFrame frame = new TheFrame(selectionPanel,headerPanel);
// public Driver() {
//
// }
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Driver();
}
});
}
}
TheFrame Class
import javax.swing.JFrame;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class TheFrame extends JFrame {
//Declarations
private GridBagConstraints gbc;
private SelectionPanel selectionPanel;
private HeaderPanel headerPanel;
public TheFrame(SelectionPanel selectionPanel, HeaderPanel headerPanel) {
super("DEFCON DEACTIVATOR");
this.selectionPanel = selectionPanel;
this.headerPanel = headerPanel;
//Initialization
gbc = new GridBagConstraints();
selectionPanel = new SelectionPanel();
headerPanel = new HeaderPanel();
this.getContentPane().setLayout(new GridBagLayout());
//Configuration
//Add to contentPane
gbc.anchor = gbc.NORTH; //Content-Pane GLOBAL
gbc.insets = new Insets(0,0,0,0); //Content-Pane GLOBAL
gbc.weightx = 0; //Content-Pane GLOBAL
gbc.weighty = 0.05;
gbc.gridx = 0;
gbc.gridy = 0;
this.getContentPane().add(headerPanel,gbc);
gbc.weighty = 1;
gbc.gridx = 0;
gbc.gridy = 1;
this.getContentPane().add(selectionPanel,gbc);
//Finalize JFrame Last Steps Configurations
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
SelectionPanel Class
import java.awt.Insets;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class SelectionPanel extends JPanel {
//Declarations
private JCheckBox defconLevel1;
private JCheckBox defconLevel2;
private JCheckBox defconLevel3;
private JCheckBox defconLevel4;
private JCheckBox defconLevel5;
private GridBagConstraints gbc;
public SelectionPanel() {
//Initializations
defconLevel1 = new JCheckBox("DEFCON 1");
defconLevel2 = new JCheckBox("DEFCON 2");
defconLevel3 = new JCheckBox("DEFCON 3");
defconLevel4 = new JCheckBox("DEFCON 4");
defconLevel5 = new JCheckBox("DEFCON 5");
gbc = new GridBagConstraints();
//Configuration
this.setLayout(new GridBagLayout());
//Add
//ROW 1
gbc.insets = new Insets(0,0,0,0); //Content-Pane Global
//gbc.anchor = gbc.EAST; //Makes Elements chain-follow each other
gbc.gridy = 0;
gbc.gridx = 0;
this.add(defconLevel1,gbc);
gbc.gridx = 1;
this.add(defconLevel2,gbc);
gbc.gridx = 2;
this.add(defconLevel3,gbc);
gbc.gridx = 3;
this.add(defconLevel4,gbc);
gbc.gridx = 4;
this.add(defconLevel5,gbc);
}
}
HeaderPanel Class
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class HeaderPanel extends JPanel {
private JLabel headerLab;
private GridBagConstraints gbc;
public HeaderPanel() {
//Initialize
headerLab = new JLabel("PLEASE SELECT DEFCON LEVEL");
gbc = new GridBagConstraints();
//Configure
this.setLayout(new GridBagLayout());
//Add
gbc.gridx = 0;
gbc.gridy = 0;
this.add(headerLab,gbc);
}
}
Present Picture:
Wished Design:
Updated Image:
The constraint for the label also needs:
gbc.gridwitdh = 5;
This will allow the label to take up the same horizontal space as the 5 checkboxes, allowing each check box to be displayed in its own column.
You will then need to reset the gridwidth to 1 before adding the other components.
Another option might be to use a Titled Border on your panel. Then you can just use a FlowLayout for adding all the check boxes. This is an easier solution since you don't need to worry about all the GridBagConstraints.
Edit:
Read the section from the Swing tutorial on How to Use GridBagLayout for information about all the constraints.
The first thing you need to do is actually use the constraints for the label otherwise setting the gridwidth won't do anything as the default constrainsts will be used:
//this.getContentPane().add(selectionLab);
add(selectionLab, gbc);
It still won't look correct because you will then need to understand the proper values to be used with the following constraints:
weighty
anchor
weightx
I'll let you play with the constraints one at a time to see what happens as you change the constraint. The tutorial link will help with the different values.
I have a problem with GridbagLayout; I've 5 buttons and I want to have them in this way:
I've already tried different approaches but no one works in the correct way.
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGridBagLayout {
protected void initUI() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel southPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 2;
gbc.gridy = 0;
JButton enterRoom = new JButton("Enter room");
JButton exitRoom = new JButton("Exit room");
JButton login = new JButton("Login");
JButton logout = new JButton("Logout");
JButton whoIsIn = new JButton("Who is in");
gbc.gridx = 1;
southPanel.add(enterRoom, gbc);
gbc.gridx = 5;
southPanel.add(exitRoom, gbc);
gbc.gridy = 1;
gbc.gridx = 0;
southPanel.add(login, gbc);
gbc.gridx = 3;
southPanel.add(logout, gbc);
gbc.gridx = 6;
southPanel.add(whoIsIn, gbc);
frame.add(southPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestGridBagLayout().initUI();
}
});
}
}
Appears:
I'm not interested in other approaches (such as GridLayout), I'd like to know what I'm missing.
GridBagLayout can be a strange animal in some cases. But anyway, gridwidth is something that works, only if there is an actual component that requires some width within the "spanned" column (for example, if you say gridx=0 and gridwidth=2, column 0 has a component and the "spanned" column is column 1).
In your case, column 2, 4 & 7 have no components, so their width is set to 0. Additionnaly, column 5 also gets a width of 0, because column 6 provides enough witdth to the exit room button, so in the end you get the result you see.
Now, not sure of the kind of layout you are trying to achieve (I saw your screenshot, but how should it behave when the panel collapses/expands in width?). So find below, an example that comes a bit closer to what you describe (although I don't find it very nice)
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGridBagLayout2 {
protected void initUI() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel southPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
JButton enterRoom = new JButton("Enter room");
JButton exitRoom = new JButton("Exit room");
JButton login = new JButton("Login");
JButton logout = new JButton("Logout");
JButton whoIsIn = new JButton("Who is in");
gbc.gridx = 0;
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.EAST;
southPanel.add(enterRoom, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx = 2;
southPanel.add(exitRoom, gbc);
gbc.gridy = 1;
gbc.gridx = 0;
southPanel.add(login, gbc);
gbc.weightx = 0;
gbc.gridx = 1;
southPanel.add(logout, gbc);
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.EAST;
gbc.gridx = 2;
southPanel.add(whoIsIn, gbc);
frame.add(southPanel);
frame.pack();
frame.setSize(frame.getWidth() * 4 / 3, frame.getHeight());
frame.setMinimumSize(frame.getSize());
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestGridBagLayout().initUI();
}
});
}
}
GridbagLayout seems to require a row where a component occupies all of the columns in the row. See: Why does this GridBagLayout not appear as planned? for the basis of this solution.
Note the that horizontal strut size was choosen to be half the size of the "Logout" button so that two cells with span the width of the logout button to give the centering of components that you desire.
import java.awt.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JButton enterRoom = new JButton("Enter room");
JButton exitRoom = new JButton("Exit room");
JButton login = new JButton("Login");
JButton logout = new JButton("Logout");
JButton whoIsIn = new JButton("Who is in");
setLayout( new GridBagLayout() );
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 0,5, 0);
gbc.gridwidth = 2;
gbc.gridx = 1;
gbc.gridy = 0;
add(enterRoom, gbc);
gbc.gridx = 5;
gbc.gridy = 0;
add(exitRoom, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(login, gbc);
gbc.gridx = 3;
gbc.gridy = 1;
add(logout, gbc);
gbc.gridx = 6;
gbc.gridy = 1;
add(whoIsIn, gbc);
// Add dummy components so every cell has a component.
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridwidth = 1;
gbc.gridy = 2;
int strutWidth = logout.getPreferredSize().width / 2;
for (int i = 0; i < 8; i++)
{
gbc.gridx = i;
add(Box.createHorizontalStrut(strutWidth), gbc);
}
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE(), BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
I am using a GridBagLayout for my components in a JFrame. I just started using it, and I keep confusing myself. What I want is; Patch notes in the top left, buttons (vertical) on the right, play button on the bottom. I'm not sure what the issue really is, but can you please help me organize this?
Here's my code:
package counter.main;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
public class HomeFrame {
private static JPanel panel;
private static JButton play = new JButton("Play");
private static JPanel p;
File patch = new File(Main.class.getResource("/counter/res/ResourceCounterPatchNotes.txt").getFile());
//private static JLabel text;
public static JLabel greet = new JLabel("", SwingConstants.CENTER);
static JFrame frame = new JFrame("Resource Counter - Home"); {
frame.setSize(800, 500);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.repaint();
frame.revalidate();
createView();
}
private void createView() {
setIcon();
panel = new JPanel();
frame.getContentPane().add(panel);
p = new JPanel();
frame.getContentPane().add(p);
p.setLayout(new FlowLayout(FlowLayout.CENTER, 400, 360));
play.setPreferredSize(new Dimension(200, 70));
p.add(play);
JPanel p2 = new JPanel();
frame.getContentPane().add(p2);
p2.setLayout(new GridBagLayout());
JButton button = new JButton(" Button ");
play.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
Thread.sleep(500);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
SelectionFrame.frame1.setVisible(true);
frame.setVisible(false);
}
});
JTextArea ta = new JTextArea();
p2.setBackground(Color.BLACK);
ta.setForeground(Color.WHITE);
ta.setFont(new Font("Lucida Sans", Font.PLAIN, 12));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(-150, 5, 5, 30);
gbc.gridx = 0;
gbc.gridy = 0;
p2.add(ta, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
p2.add(button, gbc);
/*gbc.anchor = GridBagConstraints.SOUTH;
gbc.gridx = 0;
gbc.gridy = 2;
p2.add(play, gbc);*/
try {
ta.read(new FileReader(patch), null);
ta.setEditable(false);
//p2.add(ta, BorderLayout.WEST);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
greet.setFont(new Font( "Dialog", Font.BOLD, 20));
frame.getContentPane().add(greet, BorderLayout.NORTH);
}
public void setIcon() {
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/counter/res/Iron-Pickaxe-icon.png")));
}
}
Here is what I get:
Your code is a mess (sorry), I could spent a lot of time trying to unravel your compound layouts, but it would be easier to just start again. Not saying that you might not consider using a compound layout concept, but I think that's what's got you into such a mess to start with...
So I've basically create a simplified example of what I "guess" your description is asking for...
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = gbc.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
JTextArea patch = new JTextArea(10, 20);
add(new JScrollPane(patch), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
for (int index = 0; index < 6; index++) {
add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
gbc.gridx = 1;
gbc.anchor = GridBagConstraints.SOUTH;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(new JButton("Play >"), gbc);
}
}
}
With layouts, it's best to start with pen and paper, group the elements you need to together (like the buttons down the right side for example) and devise a plan for how you might lay them out and prototype of view ideas...
Updated
1) How can I have it so that there is space between the TextArea and the buttons, and vertical space on the buttons? I tried using the Insets but I haven't arranged the numbers in a correct way yet.
insets is the correct way to go...
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 8, 2, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (int index = 0; index < 6; index++) {
core.add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
2) I would like the "Play" button at the center-bottom of the screen, and have it be larger
You "could" do this with GridBagLayout, but I decided not to, as it can cause some issues if you're not careful with how your setup the constraints for the other components, so instead, I used a combination of BorderLayout and GridBagLayout.
To make the "play" button larger, you could modify the font or adjust the button's margins...
playButton.setMargin(new Insets(12, 12, 12, 12));
depending on the effect you're after
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout(0, 4));
JPanel core = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
JTextArea patch = new JTextArea(10, 20);
core.add(new JScrollPane(patch), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 8, 2, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (int index = 0; index < 6; index++) {
core.add(new JButton("Button #" + index), gbc);
gbc.gridy++;
}
add(core);
JButton playButton = new JButton("Play >");
playButton.setMargin(new Insets(12, 12, 12, 12));
add(playButton, BorderLayout.SOUTH);
}
}
I have a form with lots of text fields and some of those text fields may contain very long strings. To make it work I made those text fields scrollable using this code:
JScrollPane scroll = new JScrollPane(textField);
scroll.setPreferredSize(new Dimension((int)textField.getPreferredSize().getWidth(), (int)textField.getPreferredSize().getHeight() * 2));
Then I put scroll into my form using GridBagLayout.
Second line in my example is required for scroller to show up. But it has downside. When I resize window to fit whole text in text field, then scroll disapears leaving me with just two times higher then others text field, which looks ridiculous.
How can I make this all work and show me normal size of text field after scroller is hidden?
EDIT:
You may use following as a demo code to reproduce the issue:
import javax.swing.*;
import java.awt.*;
public class ScrollTextDemo extends JFrame{
public ScrollTextDemo(){
super();
this.setPreferredSize(new Dimension(500, 300));
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
textField.setCursor(new Cursor(0));
textField.setEditable(false);
JScrollPane scroll = new JScrollPane(textField);
scroll.setPreferredSize(new Dimension(70, 40) );
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
gbc.insets = new Insets(5, 5, 0, 5);
panel.add(scroll,gbc);
//let's add one more text field without scroll bar to compare
JTextField textField2 = new JTextField("abc");
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
gbc.insets = new Insets(5, 5, 0, 5);
panel.add(textField2,gbc);
this.add(panel);
}
public static void main(String args[]){
ScrollTextDemo demo = new ScrollTextDemo();
demo.pack();
demo.setVisible(true);
}
}
For this , in the absence of a good SSCCE, I think you hadn't provided any constraint that goes for fill, which is used for
Used when the component's display area is larger than the component's requested size to determine whether and how to resize the component. Valid values (defined as GridBagConstraints constants) include NONE (the default), HORIZONTAL (make the component wide enough to fill its display area horizontally, but do not change its height), VERTICAL (make the component tall enough to fill its display area vertically, but do not change its width), and BOTH (make the component fill its display area entirely).
So you must add something like this to your GridBagConstraints
constraintsGridBag.fill = GridBagConstraints.HORIZONTAL;
This will only allow it to expand HORIZONTALLY not both ways.
** EDIT : As for the added code **
Never specify setPreferredSize(...) for any component in Swing. Let the Layout Manager you are using, take care for that. Remove all setPreferredSize(...) thingies, will let it remain in normal size upon resizing.
*EDIT 2 : *
Code to tell you what I am saying :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class GridBagTest extends JFrame
{
private JPanel topPanel;
private JPanel bottomPanel;
public GridBagTest()
{
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
//gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.8;
// Setting TOP PANEL.
topPanel = new JPanel();
topPanel.setLayout(new GridBagLayout());
GridBagConstraints constraintsTopPanel = new GridBagConstraints();
constraintsTopPanel.gridwidth = 2; // Specifies that this component will take two columns.
constraintsTopPanel.gridheight = 1; // specifies that the component will take one row.
/*
* fill with HORIZONTAL, means the component upon resize, will
* only expand along the X-Axis.
*/
constraintsTopPanel.fill = GridBagConstraints.NONE;
constraintsTopPanel.insets = new Insets(5, 5, 5, 5);
constraintsTopPanel.ipadx = 2;
constraintsTopPanel.ipady = 2;
constraintsTopPanel.weightx = 0.3;
constraintsTopPanel.weighty = 0.2;
constraintsTopPanel.gridx = 0;
constraintsTopPanel.gridy = 0;
JTextField tfield1 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);
topPanel.add(tfield1, constraintsTopPanel);
constraintsTopPanel.gridx = 2;
constraintsTopPanel.gridy = 0;
final JTextField tfield2 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);
topPanel.add(tfield2, constraintsTopPanel);
constraintsTopPanel.gridx = 4;
constraintsTopPanel.gridy = 0;
JTextField tfield3 = new JTextField("kajslkajfkl dsjlafj lksdj akljsd lfkajflkdj lkaj flkdjalk jflkaj lkfdsj salkj flkaj flkja dslkfjal ksjdflka jlfjd aflsdj", 10);
topPanel.add(tfield3, constraintsTopPanel);
topPanel.setBackground(Color.WHITE);
add(topPanel, gbc);
constraintsTopPanel.gridx = 0;
constraintsTopPanel.gridy = 2;
constraintsTopPanel.gridwidth = 6; // Specifies that this component will take two columns.
constraintsTopPanel.gridheight = 1; // specifies that the component will take one row.
JButton button = new JButton("REMOVE");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
topPanel.remove(tfield2);
topPanel.revalidate();
topPanel.repaint();
}
});
topPanel.add(button, constraintsTopPanel);
//Setting BOTTOM PANEL.
bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
bottomPanel.setBackground(Color.DARK_GRAY);
JLabel label3 = new JLabel("I am a new JLABEL for the bottom JPanel", JLabel.CENTER);
label3.setForeground(Color.WHITE);
bottomPanel.add(label3, BorderLayout.CENTER);
gbc.weighty = 0.2;
add(bottomPanel, gbc);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
setVisible(true);
}
public static void main(String... args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridBagTest();
}
});
}
}
Well the best I've got is looking ugly in code, but does exactly what I need to the textField. Below is changed sample code from initial question. I'd be thankfull for any ideas how to make it better:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class ScrollTextDemo extends JFrame{
public ScrollTextDemo(){
super();
this.setPreferredSize(new Dimension(500, 300));
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
textField.setCursor(new Cursor(0));
textField.setEditable(false);
JScrollPane scroll = new JScrollPane(textField, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
//gbc.ipady = 20;//gives some room for scroll to appear and don't hide text area under the scroll.
gbc.insets = new Insets(5, 5, 0, 5);
panel.add(scroll,gbc);
//let's add one more text field without scroll bar to compare
JTextField textField2 = new JTextField("bbbbbbbb");
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
gbc.insets = new Insets(5, 5, 0, 5);
panel.add(textField2,gbc);
scroll.addComponentListener( new ScrollTextComponentListener(scroll, textField2));
this.add(panel);
}
public static void main(String args[]){
ScrollTextDemo demo = new ScrollTextDemo();
demo.pack();
demo.setVisible(true);
}
}
class ScrollTextComponentListener implements ComponentListener {
private boolean scrollVisible;
private JScrollPane scroll;
private JComponent compareComponent;
public ScrollTextComponentListener(JScrollPane scroll, JComponent compareComponent) {
this.scroll = scroll;
this.compareComponent = compareComponent;
}
private boolean isScrollVisible() {
return scroll.getHorizontalScrollBar().getModel().getExtent() != scroll.getHorizontalScrollBar().getModel().getMaximum();
}
private void setScrollSize(){
boolean scrollVisible = isScrollVisible();
if (scrollVisible){
scroll.setPreferredSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2));
//also had to set both min and max sizes, because only preffered size didn't always work
scroll.setMinimumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2));
scroll.setMaximumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()*2));
}
else {
scroll.setPreferredSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()));
scroll.setMinimumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()));
scroll.setMaximumSize(new Dimension(compareComponent.getWidth(),compareComponent.getHeight()));
}
this.scrollVisible = scrollVisible;
}
#Override
public void componentResized(ComponentEvent e) {
if (isScrollVisible() != scrollVisible) setScrollSize();
}
#Override
public void componentMoved(ComponentEvent e) {
}
#Override
public void componentShown(ComponentEvent e) {
setScrollSize();
}
#Override
public void componentHidden(ComponentEvent e) {
}
}