Reputation: 33
I'm trying to create a console using Java Swing (GridBagLayout).
I don't know why, but as you can see at the left margin, grids don't have the correct size.
It's supposed to be shown this way:
Where light blue is the list, green the image, orange the text panel and yellow the text field.
I don't know how to make the list bigger and the image smaller. Too, the text field's grid is binded to the list one, even tough the list is on y 1 and the text field on y 2.
Here's some code.
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
list.setBackground(new Color(160, 160, 160));
list.setSelectionBackground(new Color(150, 150, 150));
scrollPane.setPreferredSize(new Dimension(20, 20));
manager.setCommandList(listInput);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
JLabel image = new JLabel(new ImageIcon());
manager.setImageField(image);
c.insets = new Insets(0, 0, 0, 0);
c.ipady = 0;
c.ipadx = 0;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.1;
c.weighty = 0.3;
c.fill = GridBagConstraints.BOTH;
console.add(image, c);
where 'c' is a grid bag constraint and console the main JPanel. As you can see, the list has a grid height of 2 and weight of 0.6, and the image a grid height of 1 and weight of 0.9, so not sure why the list is 4 times smaller than the image.
Another issue, I've added a listener to the JLabel holding the image (on resize), anyways, it isn't called. Should I add the listener to the main panel? as the image is only being resized by the layout manager.
Thanks ^^
EDIT: SSCCE:
package co.relieved.jelly.application.display.swing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
@SuppressWarnings("serial")
public class Test extends JPanel {
static JLabel image;
public static void main(String[] args) {
display();
try {
BufferedImage buffer = ImageIO
.read(new File("/home/juanco/Pictures/Screenshot from 2016-02-08 22-43-22.png"));
image.setIcon(new ImageIcon(
buffer.getScaledInstance(image.getWidth(), image.getHeight(), BufferedImage.SCALE_SMOOTH)));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public Test() {
super(new GridLayout(1, 1));
JTabbedPane tabs = new JTabbedPane();
/*** >>> Console Pane <<< ***/
JPanel console = new JPanel();
console.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.ipadx = 0;
c.ipady = 0;
c.gridwidth = 1;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.BOTH;
// Console Screen
JTextPane screen = new JTextPane();
screen.setEditable(false);
c.gridx = 1;
c.gridy = 0;
c.gridheight = 2;
c.weightx = 0.8;
c.weighty = 1;
console.add(screen, c);
// Console Input
JTextField input = new JTextField();
c.insets = new Insets(2, 0, 2, 0);
c.ipady = 3;
c.gridy = 2;
c.gridheight = 1;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
console.add(input, c);
// Command List
DefaultListModel<String> listInput = new DefaultListModel<String>();
listInput.setSize(1);
JList<String> list = new JList<String>(listInput);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane scrollPane = new JScrollPane(list);
c.insets = new Insets(2, 2, 2, 2);
c.ipady = 0;
c.ipadx = 100;
c.gridx = 0;
c.gridy = 1;
c.gridheight = 2;
c.weightx = 0.1;
c.weighty = 0.6;
c.fill = GridBagConstraints.BOTH;
console.add(scrollPane, c);
// Image Displayer
image = new JLabel(new ImageIcon());
c.insets = new Insets(0, 0, 0, 0);
c.ipadx = 0;
c.gridy = 0;
c.gridheight = 1;
c.weighty = 0.3;
console.add(image, c);
// General
tabs.addTab("Console", console);
/*** >>> Logs Pane <<< ***/
JPanel logs = new JPanel();
tabs.addTab("Logs", logs);
// Setup
tabs.setSelectedIndex(0);
add(tabs);
}
static void display() {
JFrame frame = new JFrame("Relieved Console");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(800, 500));
frame.add(new Test(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Upvotes: 1
Views: 5204
Reputation: 324207
Here's some code.
Which doesn't help. The grid can only be completed with the entire code. That is we need to know the gridwidth and gridheight for all components in order to determine the allocation of space to each component in the grid.
the text field's grid is binded to the list one, even tough the list is on y 1 and the text field on y 2.
You can't just randomly assign a component to a grid. The component will only go to grid 2 if the component above it has a grid height of 2. So basically each of your columns needs to have components with a total grid height of 3.
I don't know how to make the list bigger
Setting a preferred size of (20, 20) doesn't help. Anyway you should not be using the setPreferredSize() method.
Instead you should be using:
list.setVisibleRowCount(...);
to specify the visible rows. Then the JList can determine its own preferred size.
Another layout option is to use nested panels which can simplify the layout.
So you could start with a "west" panel that uses a BorderLayout. Then you add the label to "PAGE_START" and the list to "CENTER".
Then you create a "center" panel. Add the main component to the "CENTER" and the text field to the "PAGE_START".
Then you add the two panels to the frame:
frame.add(westPanel, BorderLayout.LINE_START);
frame.add(centerPanel, BorderLayout.CENTER);
Edit:
Sorry, I take back my comment about making each column have a grid height of 3. You can't just specify a total grid height of 3 because you only have 2 components in each column, so each component can only have a height of 1.
Check out my answer in this posting: Why does this GridBagLayout not appear as planned? for a hack that allows you to manipulate gridHeight/Weight by using invisible components in a row/column.
However, I don't recommend that approach. it will be far easier to use my suggestion of nested panels using a BorderLayout (or some other layout manager on the nested panels).
Upvotes: 4
Reputation: 33
I fixed it splitting the "console" JPanel in two, a border layout panel to the left and a grid bag layout panel to the right. As @camickr suggested
Upvotes: 0
Reputation: 3102
It seems to me that you would need to also specify the gridwidth
and/or gridheight
for the text field as well.
GridBagLayout is like a glorified GridLayout. It will attempt to align all of the components with the nearest grid spaces around it. Oracle's Tutorials also describe this behavior.
Much of the time, issues with laying out components using GridBagLayout come from the other components being added to the layout instead of the apparent problem child.
Upvotes: 0