Here is what I have:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.LineBorder;
public class Main {
// Field members
static JPanel panel = new JPanel();
static Integer indexer = 1;
static List<JLabel> listOfLabels = new ArrayList<JLabel>();
static List<JTextField> listOfTextFields = new ArrayList<JTextField>();
static JScrollPane scrollPane;
public static void main(String[] args) {
// Construct frame
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
//frame.setPreferredSize(new Dimension(990, 990));
frame.setTitle("My Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Frame constraints
//GridBagConstraints frameConstraints = new GridBagConstraints();
// Construct button
JButton addButton = new JButton("Add");
addButton.addActionListener(new ButtonListener());
// Add button to frame
//frameConstraints.gridx = 0;
//frameConstraints.gridy = 0;
//frame.add(addButton, frameConstraints);
frame.add(addButton);
// Construct panel
panel.setPreferredSize(new Dimension(1000, 1000));
panel.setLayout(new GridBagLayout());
panel.setBorder(LineBorder.createBlackLineBorder());
scrollPane = new JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setPreferredSize(new Dimension(600, 600));
// Add panel to frame
//frameConstraints.gridx = 0;
//frameConstraints.gridy = 1;
//frameConstraints.weighty = 1;
//frame.add(panel, frameConstraints);
frame.add(scrollPane);
// Pack frame
frame.pack();
// Make frame visible
frame.setVisible(true);
}
static class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
// Clear panel
panel.removeAll();
// Create label and text field
//JTextField jTextField = new JTextField();
//jTextField.setSize(100, 200);
//listOfTextFields.add(jTextField);
listOfLabels.add(new JLabel("" + indexer));
// Create constraints
//GridBagConstraints textFieldConstraints = new GridBagConstraints();
GridBagConstraints labelConstraints = new GridBagConstraints();
// Add labels and text fields
for (int i = 0; i < indexer; i++) {
// Text field constraints
//textFieldConstraints.gridx = 1;
//textFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
//textFieldConstraints.weightx = 0.5;
//textFieldConstraints.insets = new Insets(10, 10, 10, 10);
//textFieldConstraints.gridy = i;
// Label constraints
labelConstraints.gridx = 0;
labelConstraints.gridy = i;
labelConstraints.insets = new Insets(0, 0, 0, 0);
// Add them to panel
panel.add(listOfLabels.get(i), labelConstraints);
//panel.add(listOfTextFields.get(i), textFieldConstraints);
}
// Align components top-to-bottom
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = indexer;
c.weighty = 1;
c.ipady = 0;
panel.add(new JLabel(), c);
System.out.println("indexer is " + indexer);
// Increment indexer
indexer++;
panel.updateUI();
if(indexer ==2){
listOfLabels.set(0, new JLabel("Test"));
}
}
private int getWidth() {
// TODO Auto-generated method stub
return 0;
}
}
}
Here is the output:
What Am I doing wrong? I want the labels to be justified all the way to the left. I don't have any padding set to the left so I am confused.
FYI, I found this code on stackoverflow and my goal is to have labels that I can dynamically add and update, hence I commented out the textboxes.
Don't call setPreferredSize on the scroll pane, this isn't what you should setting, use GridBagConstraints weightx/y and fill properties.
Don't call updateUI, it doesn't do what you think it does, call revalidate instead, if you have to
The main reasons you're having problems is
You're call setPreferredSize on the panel. When adding components to a GridBagLayout, it will attempt to lay out components around the centre of the container
You've not specified a weightx or anchor property for the GridBagConstraints when adding the labels
Related
I'm trying to display a series of buttons in a JScrollpane. Reading around, I managed to exit with this code, but nothing is displayed. I do not understand a possible mistake. Thank you for help
As suggested I made some changes, I edited but not works
EDITED
or I'm stupid, or here is some other problem. Here is my complete code with the output image
public class Main extends javax.swing.JFrame {
private final JPanel gridPanel;
public Main() {
initComponents();
// EXISTING PANEL
gridPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);
this.Avvio();
}
private void Avvio() {
JPanel pane = new JPanel(new GridBagLayout());
pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
pane.setLayout(new GridBagLayout());
for (int i = 0; i < 10; i++) {
JButton button;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
button = new JButton("Button 1");
c.weightx = 0.5;
c.gridx = 0;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 2");
c.gridx = 1;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 3");
c.gridx = 2;
c.gridy = i;
pane.add(button, c);
}
gridPanel.add(pane);
gridPanel.revalidate();
gridPanel.repaint();
}
}
Alright, from your comments in another answer:
No problem for compile , simply the Jpanel is empty. The buttons does not appear.
After calling this.Avvio(); you must call:
this.add(scrollPane);
this.pack();
This will produce the following outputs (before and after resizing it):
But there's still no JScrollPanel
This at least solves the first problem, however you have more errors in your code, some of which have already been commented in other answers:
You're extending JFrame, this isn't needed as you can create a JFrame instance / object and use it later. You're never changing the JFrame's behavior and that's why it's not needed to extend it. See Extends JFrame vs. creating it inside the program for more information about this.
You're not calling pack() nor setSize(...) this creates a tiny window, which you need to manually resize. Call pack() recommended before making your JFrame visible. (As suggested at the beginning of this answer).
You're calling .invokeLater() method twice. You need to call it just once, I prefer this way:
SwingUtilities.invokeLater(() -> new Main()); //Note there is no call to .setVisible(true); as per point #1. It should go later in the program like: frame.setVisible(true);
You're calling gridPanel.revalidate(); and gridPanel.repaint() while it doesn't affect your program, it's not needed as your GUI is still not visible, and thus those calls have no effect on your program, you can safely remove them.
You're creating a new GridBagConstraints object on each iteration of the for loop, you can just change its properties inside it and declaring it outside the for loop, which will make your program better.
After following the above recommendations, you can end up with a code like this one:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Main {
private final JPanel gridPanel;
private JFrame frame;
public Main() {
// EXISTING PANEL
gridPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);
this.Avvio();
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
private void Avvio() {
JPanel pane = new JPanel(new GridBagLayout());
pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
pane.setLayout(new GridBagLayout());
for (int i = 0; i < 10; i++) {
JButton button;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
button = new JButton("Button 1");
c.weightx = 0.5;
c.gridx = 0;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 2");
c.gridx = 1;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 3");
c.gridx = 2;
c.gridy = i;
pane.add(button, c);
}
gridPanel.add(pane);
}
public static void main(String args[]) {
/* Create and display the form */
SwingUtilities.invokeLater(() -> {
new Main();
});
}
}
Which still produces this output:
BUT... We still can improve it a little more!
We may have two nested for loops, for the GridBagConstraints properties as well as the generation of the buttons:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class ScrollablePaneWithButtons {
private static final int ROWS = 10;
private static final int COLS = 3;
private JFrame frame;
private JPanel pane;
private JButton[][] buttons;
private GridBagConstraints gbc;
private JScrollPane scroll;
private JButton[] menuButtons;
private JPanel menuPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new ScrollablePaneWithButtons()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(this.getClass().getSimpleName());
pane = new JPanel();
pane.setLayout(new GridBagLayout());
menuPane = new JPanel();
menuPane.setLayout(new GridLayout(1, 3));
buttons = new JButton[ROWS][COLS];
menuButtons = new JButton[] {new JButton("Edit"), new JButton("Delete"), new JButton("Sort Fields")};
gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.weightx = 0.5;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
buttons[i][j] = new JButton("Button " + (j + 1));
gbc.gridx = j;
gbc.gridy = i;
pane.add(buttons[i][j], gbc);
}
}
scroll = new JScrollPane(pane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
for (JButton b : menuButtons) {
menuPane.add(b);
}
frame.add(scroll);
frame.add(menuPane, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
And this example is (in my opinion) easier to read and follow up. And this is the output the above code is generating:
You can still choose which code to use, either doing the modifications at the first part of this answer, the second one following the recommendations above or the last one which is shorter.
Problems noted:
Avvio - the pane layout was reset during each loop. Set it once before the loop.
Avvio - the pane was added to the grid pane in each loop. Add it once after the loop.
Avvio - the constraints place the buttons in the same grid locations. With the previous two issues fixed, only the last three buttons placed appear.
I'm assuming you want three buttons in a row, so I changed the loop to use the counter as a row counter. The code below will create ten rows of three buttons.
What appears:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
public class Main extends javax.swing.JFrame {
private JPanel gridPanel;
public Main() {
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setSize(600,400);
//EXISTING PANEL
gridPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);
this.Avvio();
this.add(borderLayoutPanel, BorderLayout.CENTER);
this.setVisible(true);
}
private void Avvio() {
JPanel pane = new JPanel(new GridBagLayout());
pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
pane.setLayout(new GridBagLayout());
for (int i = 0; i < 10; i++) {
JButton button;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
button = new JButton("Button 1");
c.weightx = 0.5;
c.gridx = 0;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 2");
c.gridx = 1;
c.gridy = i;
pane.add(button, c);
button = new JButton("Button 3");
c.gridx = 2;
c.gridy = i;
pane.add(button, c);
}
gridPanel.add(pane);
gridPanel.revalidate();
gridPanel.repaint();
}
public static void main(String args[]) {
new Main();
}
}
There are several things to do to make it work:
Add a main method
This main method is the entry point. This makes sure the swing-code runs in the AWT-thread. This is what the SwingUtilities.invokeLater is for
Instantiate, pack and display the frame. The size setting is only for experimenting with the scrollpane
Declare the gridPanel as an instance variable
wrap the gridPanel with the scrollPane
Optionally, wrap the scrollPane with the borderLayoutPanel
Invoke the Avvio method because this is the one that adds the buttons
Add the outmost element to the frame
Here is the fixed code:
public class MyFrame extends javax.swing.JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MyFrame frame = new MyFrame();
frame.pack();
frame.setSize(600, 300);
frame.setVisible(true);
});
}
private JPanel gridPanel;
public MyFrame() {
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
gridPanel = new JPanel(new GridLayout(0, 1));
JScrollPane scrollPane = new JScrollPane(gridPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);
this.Avvio();
this.add(borderLayoutPanel, BorderLayout.CENTER);
}
private void Avvio() {...}
}
I have simplified the program and removed all the mistakes
and bad practices. (Missing package, unnecessary panels, calling invokeLater() twice and others.)
Here is a working example:
package com.zetcode;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class JavaScrollPaneEx extends JFrame {
public JavaScrollPaneEx() {
initUI();
}
private void initUI() {
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = createButtonPanel();
JScrollPane scrollPane = new JScrollPane(buttonPanel);
panel.add(scrollPane, BorderLayout.CENTER);
add(panel);
setTitle("Buttons in JScrollBar");
setSize(350, 250);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.PAGE_START;
c.insets = new Insets(5, 5, 5, 5);
for (int i = 0, j = 0; i < 5; i++) {
JButton btn = new JButton("Button " + (j + 1));
c.weightx = 0.5;
c.gridx = i;
c.gridy = 0;
panel.add(btn, c);
btn = new JButton("Button " + (j + 2));
c.gridx = i;
c.gridy = 1;
panel.add(btn, c);
btn = new JButton("Button " + (j + 3));
c.gridx = i;
c.gridy = 2;
panel.add(btn, c);
j += 3;
}
return panel;
}
public static void main(String args[]) {
EventQueue.invokeLater(() -> {
JavaScrollPaneEx ex = new JavaScrollPaneEx();
ex.setVisible(true);
});
}
}
And this is the screenshot.
And since I consider GridBagLayout to be a very bad
layout manager, I have created a similar example with MigLayout
manager.
We need the following Maven dependency for this example:
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>5.0</version>
</dependency>
The source:
package com.zetcode;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
public class JavaScrollPaneEx2 extends JFrame {
public JavaScrollPaneEx2() {
initUI();
}
private void initUI() {
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = createButtonPanel();
JScrollPane scrollPane = new JScrollPane(buttonPanel);
panel.add(scrollPane, BorderLayout.CENTER);
add(panel);
setTitle("Buttons in JScrollBar");
setSize(350, 250);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new MigLayout());
for (int i = 0, j = 0; i < 5; i++) {
JButton btn1 = new JButton("Button " + (j + 1));
JButton btn2 = new JButton("Button " + (j + 2));
JButton btn3 = new JButton("Button " + (j + 3));
JButton btn4 = new JButton("Button " + (j + 4));
JButton btn5 = new JButton("Button " + (j + 5));
panel.add(btn1, "sgx");
panel.add(btn2, "sgx");
panel.add(btn3, "sgx");
panel.add(btn4, "sgx");
panel.add(btn5, "sgx, wrap");
j += 5;
}
return panel;
}
public static void main(String args[]) {
EventQueue.invokeLater(() -> {
JavaScrollPaneEx2 ex = new JavaScrollPaneEx2();
ex.setVisible(true);
});
}
}
From my code I expect my JTextArea to fill the top left border seen below:
But as you can see its taking up a tiny section in the middle.
I am using GridBagConstraints on the panel which contains the components.
There is a main class which calles up a class called frame. This class creates the JFrame and sets the size as well as other things. This is then called from the MainFrame.java which has extended the jframe which creates 3 panels and sets their layout. this is seen below
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame
{
private Panel1 storyPanel;
private Panel2 statsPanel;
private Panel3 commandsPanel;
public MainFrame(String title)
{
super(title);
// Setting Layout
GridBagConstraints gbc = new GridBagConstraints();
storyPanel = new Panel1();
storyPanel.setLayout(new GridBagLayout());
statsPanel = new Panel2();
commandsPanel = new Panel3();
Container p = getContentPane();
p.add(storyPanel, BorderLayout.WEST);
p.add(statsPanel, BorderLayout.EAST);
p.add(commandsPanel, BorderLayout.SOUTH);
}
}
The panel in questions is Panel1 or storyPanel. I have set the layout and the code calls the Panel1.java as seen below:
import javax.swing.*;
import java.awt.*;
public class Panel1 extends JPanel
{
public Panel1()
{
GridBagConstraints gbc = new GridBagConstraints();
//Set size of Panel1
int xsizeP1 = (Frame.xsize() / 2);
int ysizeP1 = (Frame.ysize() / 3 * 2);
setPreferredSize(new Dimension(xsizeP1, ysizeP1));
setBorder(BorderFactory.createLineBorder(Color.black));
//Adding JTextArea and adding settings to it
JTextArea storyLine = new JTextArea(" test ");
storyLine.setLineWrap(true);
storyLine.setWrapStyleWord(true);
storyLine.setEditable(false);
//Adding JScrollPane to the JTextArea and making it have a vertical scrollbar
JScrollPane scroll = new JScrollPane(storyLine);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//GridBagConstraints setup for components
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.VERTICAL;
add(scroll, gbc);
}
}
I don't understand why my gbc.fill isnt making the JTextArea fill the top left border of the screen shot.
Thanks in advance for any reply's
-Tom T
changing the layout to border layout
import javax.swing.*;
import java.awt.*;
public class Panel1 extends JPanel
{
public Panel1()
{
//GridBagConstraints gbc = new GridBagConstraints();
//gbc.weightx = 0.1;
//gbc.weighty = 0.1;
BorderLayout b = new BorderLayout();
//Set size of Panel1
int xsizeP1 = (Frame.xsize() / 2);
int ysizeP1 = (Frame.ysize() / 3 * 2);
setPreferredSize(new Dimension(xsizeP1, ysizeP1));
setBorder(BorderFactory.createLineBorder(Color.black));
//Adding JTextArea and adding settings to it
JTextArea storyLine = new JTextArea(" test ");
storyLine.setLineWrap(true);
storyLine.setWrapStyleWord(true);
storyLine.setEditable(false);
//Adding JScrollPane to the JTextArea and making it have a vertical scrollbar
JScrollPane scroll = new JScrollPane(storyLine);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//gbc.gridx = 0;
//gbc.gridy = 0;
//gbc.weightx = 1;
//gbc.weighty = 1;
//gbc.fill = GridBagConstraints.BOTH;
add(scroll, b.CENTER);
}
}
Don't set the layout of storyPanel, as it's contents have already been added and laid out, so changing the layout manager here will discard any properties you applied. Instead, set the layout in Panel1's constructor before you add any components.
Use GridBagConstraints.BOTH for the fill property. The fill property can only have one specified value
Use weightx and weighty to specify how much of the available space the component should use
For example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MainFrame extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new MainFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private Panel1 storyPanel;
// private Panel2 statsPanel;
// private Panel3 commandsPanel;
public MainFrame(String title) {
super(title);
storyPanel = new Panel1();
Container p = getContentPane();
p.add(storyPanel, BorderLayout.WEST);
p.add(new JLabel("East"), BorderLayout.EAST);
p.add(new JLabel("South"), BorderLayout.SOUTH);
}
public class Panel1 extends JPanel {
public Panel1() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//Set size of Panel1
setBorder(BorderFactory.createLineBorder(Color.black));
//Adding JTextArea and adding settings to it
JTextArea storyLine = new JTextArea(20, 20);
storyLine.setLineWrap(true);
storyLine.setWrapStyleWord(true);
storyLine.setEditable(false);
//Adding JScrollPane to the JTextArea and making it have a vertical scrollbar
JScrollPane scroll = new JScrollPane(storyLine);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//GridBagConstraints setup for components
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
add(scroll, gbc);
}
}
}
Having said all that, a BorderLayout would be simpler
public class Panel1 extends JPanel {
public Panel1() {
setLayout(new BorderLayout());
//Set size of Panel1
setBorder(BorderFactory.createLineBorder(Color.black));
//Adding JTextArea and adding settings to it
JTextArea storyLine = new JTextArea(20, 20);
storyLine.setLineWrap(true);
storyLine.setWrapStyleWord(true);
storyLine.setEditable(false);
//Adding JScrollPane to the JTextArea and making it have a vertical scrollbar
JScrollPane scroll = new JScrollPane(storyLine);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
add(scroll);
}
}
i tried a border layout and set it to center expecting it to resize but that failed as well
Would suggest that you're making a fundamental mistake some where, as it works fine for me. Remember, set the layout BEFORE you add any components to the container
How do I use setRows and setColumns to change the amount of rows and columns in my window?
Here's a copy of my code and where I tried to implement the set rows and columns:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.*;
#SuppressWarnings("unused")
public class GUI
{
public static void main(String[] args)
{
new GUI();
}
public GUI()
{
JFrame AG = new JFrame("Adventure Game");
AG.setExtendedState(JFrame.MAXIMIZED_BOTH);
AG.setResizable(true);
AG.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p=new JPanel();
p.setLayout (new GridBagLayout());
AG.add(p);
GridBagConstraints GBC = new GridBagConstraints();
GridLayout.setRows(100);//heres the set rows<<<<<<<<<<<<<<<<<<<
GridLayout.setColumns(100);//heres the set columns<<<<<<<<<<<<<<<<<<<
AG.getContentPane().add(p, BorderLayout.NORTH);
JButton saveButton =new JButton("Save");
JButton loadButton =new JButton("Load");
JButton optionsButton = new JButton("Options");
JLabel textBox= new JLabel("Story line will go here.");
JLabel label11 = new JLabel("Test 1");
GBC.gridx = 0;
GBC.gridy = 1;
p.add(label11,GBC);
JLabel label12 = new JLabel("Test 2");
GBC.gridx = 0;
GBC.gridy = 2;
p.add(label12,GBC);
JLabel label13 = new JLabel("Test 3");
GBC.gridx = 0;
GBC.gridy = 3;
p.add(label13,GBC);
JLabel label14 = new JLabel("Test 4");
GBC.gridx = 0;
GBC.gridy = 5;
p.add(label14,GBC);
AG.setVisible(true);
}
}
GridBagConstraints work with the GridBagLayout, not the GridLayout. Your call to GridLayout doesn't do anything.
To set the rows and columns with GridBagConstraints, you need to use GBC.gridx = ...; and GBC.gridy = ...;
If you are trying to place gaps between your buttons, empty GridBag cells are not the way to do it; use the insets of your GridBagConstraints for that.
To make a component in a GridBagLayout disappear without the other components shifting around, place the button in a JPanel with a CardLayout, and make sure you add that JPanel to your GridBagLayout instead of the button:
private JButton optionalButton;
private void buildWindow() {
// ...
optionalButton = new JButton("Optional Action");
JPanel optionalButtonPanel = new JPanel(new CardLayout());
optionalButtonPanel.add(optionalButton, "BUTTON");
optionalButtonPanel.add(new JLabel(), "BLANK");
// ...
}
private void setOptionalButtonVisible(boolean visible) {
Container optionalButtonPanel = optionalButton.getParent();
CardLayout layout = (CardLayout) optionalButtonPanel.getLayout();
layout.show(optionalButtonPanel, visible ? "BUTTON" : "BLANK");
}
CardLayout always displays one and only one of its components, but it sizes its associated container to fit all the components, including the invisible ones.
I have cretaed textfields and labels on clicking 'add' button. I have given x and y coordinates, but textbox appearing is in improper manner.
how to correct it? and also how to increase width of textbox ???
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
public class SS
{
// Field members
static JPanel panel = new JPanel();
static Integer indexer = 1;
static List<JLabel> listOfLabels = new ArrayList<JLabel>();
static List<JTextField> listOfTextFields = new ArrayList<JTextField>();
public static void main(String[] args)
{
// Construct frame
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
frame.setPreferredSize(new Dimension(800, 800));
frame.setTitle("My Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Frame constraints
GridBagConstraints frameConstraints = new GridBagConstraints();
// Construct button
JButton addButton = new JButton("Add");
addButton.addActionListener(new ButtonListener());
// Add button to frame
frameConstraints.gridx = 0;
frameConstraints.gridy = 0;
frame.add(addButton, frameConstraints);
// Construct panel
panel.setPreferredSize(new Dimension(400, 400));
panel.setLayout(new GridBagLayout());
panel.setBorder(LineBorder.createBlackLineBorder());
// Add panel to frame
frameConstraints.gridx = 0;
frameConstraints.gridy = 1;
frameConstraints.weighty = 20;
frame.add(panel, frameConstraints);
// Pack frame
frame.pack();
// Make frame visible
frame.setVisible(true);
}
static class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent arg0)
{
// Clear panel
panel.removeAll();
// Create label and text field
listOfTextFields.add(new JTextField());
listOfLabels.add(new JLabel("Name " + indexer));
// Create constraints
GridBagConstraints textFieldConstraints = new GridBagConstraints();
GridBagConstraints labelConstraints = new GridBagConstraints();
// Add labels and text fields
for(int i = 0; i < indexer; i++)
{
// Text field constraints
textFieldConstraints.gridx = 20;
textFieldConstraints.gridy = i;
// Label constraints
labelConstraints.gridx = 1;
labelConstraints.gridy = i;
// Add them to panel
panel.add(listOfTextFields.get(i), textFieldConstraints);
panel.add(listOfLabels.get(i), labelConstraints);
}
// Align components top-to-bottom
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = indexer;
c.weighty = 1;
panel.add(new JLabel(), c);
// Increment indexer
indexer++;
}
}
}
To get the frame to refresh with the text box you need to call pack at the bottom of your actionPerformed method.
frame.pack();
For this you need to have frame as a class variable.
static JFrame frame;
For the size the grid bag layout will override your setSize so you can give it a weight and make it stretch to fill in the space. This can go just after your other textFieldContraints calls.
textFieldConstraints.weightx = 1;
textFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
This should make the text boxes appear when you hit the button and take up the box.
Increase width of textfield.
listOfTextFields.add(new JTextField(null,10));
I have a JPanel (yellow) placed in JScrollPane.
When I enter some text in JTextPane, it resizes, but the vertical scrollbar is still not active. yelowPanel.getSize() returns the same value it was before.`(You can see it on redPanel).
So how can I refresh yellowPanel? I want to scroll panel vertically.
I tried to:
panelCreating.revalidate();
panelCreating.invalidate();
panelCreating.repaint();
Works only panelCreating.setPreferredSize(new Dimension(333, 777)); but I don't know what size to set. It depends on content.
There is a small example:
package swingtest;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class SwingTest extends JFrame {
public SwingTest() {
initComponents();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SwingTest().setVisible(true);
}
});
}
private JPanel panelCenter, panelCreating;
private JScrollPane scrollPaneCreating, scrollPaneCenter;
private JTextPane textPane1, textPane2;
private JButton button1;
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(300, 300));
panelCreating = new JPanel();
panelCreating.setMinimumSize(new Dimension(160, 200));
panelCreating.setPreferredSize(new Dimension(160, 200));
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textPane1 = new JTextPane();
textPane1.setText("a\na");
textPane2 = new JTextPane();
textPane2.setText("b\nb");
button1 = new JButton("+++");
panelCenter = new JPanel();
panelCenter.setBackground(Color.blue);
scrollPaneCenter = new JScrollPane(panelCenter);
// ----------------- Left Panel Init -----------------------
panelCreating.setLayout(new GridBagLayout());
panelCreating.setBackground(Color.ORANGE);
panelCreating.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0, 0, 4, 4);
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.weightx = c.weighty = 0;
c.gridx = 0;
c.gridy = GridBagConstraints.RELATIVE;
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = 1;
c.fill = GridBagConstraints.BOTH;
panelCreating.add(textPane1, c);
button1.addActionListener(new ActionListener() {
int height = 50;
#Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
textPane2.setPreferredSize(new Dimension(150, height));
height += 30;
panelCreating.revalidate();
panelCreating.repaint();
scrollPaneCreating.revalidate();
}
});
panelCreating.add(button1, c);
panelCreating.add(textPane2, c);
// -------------------------------------------------------
getContentPane().setLayout(new GridBagLayout());
c = new GridBagConstraints();
c.ipadx = c.ipady = 0;
c.insets = new Insets(0, 0, 0, 0);
c.weighty = 0;
c.gridheight = 1;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.weightx = 0;
c.fill = GridBagConstraints.BOTH;
getContentPane().add(scrollPaneCreating, c);
c.gridx = 1;
c.gridy = 1;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
getContentPane().add(scrollPaneCenter, c);
}
}
Yellow panel also uses GridBagLayout.
Sorry for my English
Instead of setting a preferred size on panelCreating, set it on scrollPaneCreating. And don't set a preferred size on the text components, they will grow as you add new lines of text to them. The idea is to have the panel inside the scroll pane grow as large as it needs to, and just restrict the size of the scroll pane itself.
// [...]
panelCreating = new JPanel();
//panelCreating.setMinimumSize(new Dimension(160, 200));
//panelCreating.setPreferredSize(new Dimension(160, 200));
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPaneCreating.setMinimumSize(new Dimension(160, 200));
scrollPaneCreating.setPreferredSize(new Dimension(160, 200));
// [...]
#Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
//textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
//textPane2.setPreferredSize(new Dimension(150, height));
//height += 30;
// This isn't necessary either
//panelCreating.revalidate();
//panelCreating.repaint();
//scrollPaneCreating.revalidate();
}
Edited to add: another alternative is to set sizes on the JViewport that is attached to the scroll pane. The viewport is where the content is displayed. You can sort of think of the scroll pane as being composed of the viewport plus scrollbars. If the scroll pane is set to a fixed size, then the viewport size is determined by subtracting the scroll bar size. But if the viewport is set to a fixed size, then the scroll pane size is determined by adding the scroll bar size to the viewport size. Setting a fixed size on the viewport is preferable if you want to precisely control how much content should be displayed on screen, because scroll bar sizes can vary by operating system.
scrollPaneCreating.getViewport().setMinimumSize(new Dimension(160, 200));
scrollPaneCreating.getViewport().setPreferredSize(new Dimension(160, 200));
The default layout of JPanel is FlowLayout. Try GridLayout instead. There's a related example here. For example,
panelCreating = new JPanel(new GridLayout());
scrollPaneCreating = new JScrollPane(panelCreating);
Addendum: Also consider nested layouts. The example below uses BoxLayout for the left panel.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
/** #see https://stackoverflow.com/questions/9184476 */
public class SwingTest extends JFrame {
private static final int N = 8;
public SwingTest() {
initComponents();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SwingTest().setVisible(true);
}
});
}
private JPanel panelCenter, panelCreating;
private JScrollPane scrollPaneCreating, scrollPaneCenter;
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panelCreating = new JPanel();
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panelCenter = new JPanel();
panelCenter.setBackground(Color.blue);
scrollPaneCenter = new JScrollPane(panelCenter);
// ----------------- Left Panel Init -----------------------
panelCreating.setLayout(new BoxLayout(panelCreating, BoxLayout.Y_AXIS));
panelCreating.setBackground(Color.orange);
panelCreating.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
panelCreating.add(createTextPane());
panelCreating.add(Box.createVerticalStrut(N));
panelCreating.add(createTextPane());
panelCreating.add(Box.createVerticalStrut(N));
panelCreating.add(createTextPane());
// -------------------------------------------------------
setLayout(new GridLayout(1, 0));
add(scrollPaneCreating);
add(scrollPaneCenter);
pack();
}
private JTextPane createTextPane() {
JTextPane pane = new JTextPane();
pane.setText(""
+ "Twas brillig and the slithy toves\n"
+ "Did gyre and gimble in the wabe;\n"
+ "All mimsy were the borogoves,\n"
+ "And the mome raths outgrabe.");
pane.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
return pane;
}
}
I fixed your problem adding 1 line.
panelCreating.setPreferredSize(new Dimension((int) panelCreating.getPreferredSize().getWidth(),
(int)(panelCreating.getPreferredSize().getHeight()+30)));
The line must be inserted after the following lines;
#Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
textPane2.setPreferredSize(new Dimension(150, height));
height += 30;
Explanation:
The grid bag layout do not set it's pane preferred size when you set the preferred size of the textPanes inside it, but the scrollPane only scrolls based on the preferred size of the pane in it. So you must set the new preferred size of the pane every time you change the size of the components in it, then the scrollPane will know exactly what he must do. That's what i did, a add a line that increased the preferred size of creatingPanel, wich is the one inside the scrollPanel