Java-Swing: A problem using layout managers! - java

I'm working on a JDialog (by hand, no GUI builders) and I'm having a problem doing the layout.
I have this:
My problem is that I don't know what how to tell that JList (within a JScrollPane) to have a Maximum width, I used the setSize, setMaximumSize and nothing works! I need that JList's width to be the half of the picture's size.
Explain the layouts:
The "Gene Information" is a GridLayout 2x4, it's contained by a JPanel with BoxLayout, the +/- JButtons is a BoxLayout also, all what I said before is within a BoxLayout.
Now, the "Genes" JPanel is a GridBagLayout.
What can I do?
Thanks in advance!
PD: The other borders are just for seeign the boundaries of the components.
Source Code:
scpGenesList.setViewportView(lstGenesList);
pnlGeneInfo.setLayout(new GridLayout(4, 2, 10, 10));
pnlGeneInfo.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Gene Information"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
lblGeneSymbol.setText("Symbol:");
lblGeneSymbol.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneChromosome.setText("Chromosome:");
lblGeneChromosome.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneStartPosition.setText("Start Position:");
lblGeneStartPosition.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneStopPosition.setText("Stop Position:");
lblGeneStopPosition.setHorizontalAlignment(SwingConstants.RIGHT);
pnlGeneInfo.add(lblGeneSymbol);
pnlGeneInfo.add(lblGeneSymbolValue);
pnlGeneInfo.add(lblGeneChromosome);
pnlGeneInfo.add(lblGeneChromosomeValue);
pnlGeneInfo.add(lblGeneStartPosition);
pnlGeneInfo.add(lblGeneStartPositionValue);
pnlGeneInfo.add(lblGeneStopPosition);
pnlGeneInfo.add(lblGeneStopPositionValue);
pnlGWASAddRemoveButtons.setLayout(new BoxLayout(pnlGWASAddRemoveButtons, BoxLayout.X_AXIS));
pnlGWASAddRemoveButtons.add(Box.createHorizontalGlue());
pnlGWASAddRemoveButtons.add(cmdGenesAdd);
pnlGWASAddRemoveButtons.add(Box.createHorizontalStrut(10));
pnlGWASAddRemoveButtons.add(cmdGenesRemove);
pnlGWASAddRemoveButtons.add(Box.createHorizontalGlue());
pnlGeneInfoButtons.setLayout(new BoxLayout(pnlGeneInfoButtons, BoxLayout.Y_AXIS));
pnlGeneInfoButtons.add(pnlGeneInfo);
pnlGeneInfoButtons.add(Box.createVerticalStrut(10));
pnlGeneInfoButtons.add(pnlGWASAddRemoveButtons);
pnlGenesPanel.setLayout(new GridBagLayout());
pnlGenesPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Genes"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
GridBagConstraints ctrGenes = new GridBagConstraints();
ctrGenes.fill = GridBagConstraints.BOTH;
ctrGenes.gridx = 0;
ctrGenes.gridy = 0;
ctrGenes.gridwidth = 1;
ctrGenes.gridheight = 1;
ctrGenes.weighty = 1.0;
ctrGenes.weightx = 1.0;
ctrGenes.insets = new Insets(0, 0, 0, 10);
pnlGenesPanel.add(scpGenesList, ctrGenes);
GridBagConstraints ctrGenesInfoButton = new GridBagConstraints();
ctrGenesInfoButton.fill = GridBagConstraints.BOTH;
ctrGenesInfoButton.gridx = 1;
ctrGenesInfoButton.gridy = 0;
ctrGenesInfoButton.gridwidth = 1;
ctrGenesInfoButton.gridheight = 1;
ctrGenesInfoButton.weighty = 1.0;
ctrGenesInfoButton.weightx = 1.0;
pnlGenesPanel.add(pnlGeneInfoButtons, ctrGenesInfoButton);
contentPane.add(pnlGenesPanel);
pack();

Why not give the "Genes" panel a 2x1 GridLayout? That should ensure that both sides have the same size.
But actually, it would make more sense to me to give the list all space not taken by the controls, since those require a fixed amount of space while the list may benefit from all additional space it can get, if there are wide entries.
To that end, I would give the "Genes" panel a BorderLayout, put the list in the CENTER slot and the controls in the EAST slot.

Following #Michael Borgwardt's suggestion to let the list grow, you can use setVisibleRowCount() to produce a convenient initial panel size. If necessary, you can also examine the Dimension returned by getPreferredScrollableViewportSize(), which "computes the size of viewport needed to display visibleRowCount rows."

Without seeing all the code here it may be impossible to tell you what is wrong. One thing I would suggest if you have time is to take a look at MigLayout. You can use it with Swing & SWT and once you learn it is a pretty powerful layout manager IMHO.
Hope this helps, good luck.

It doesn't answer your question - but I've found that the JGoodies FormLayout to be more intuitive than the GridBagLayout. The library, as well as some examples, can be found here:
http://jgoodies.com/freeware/forms/index.html

I think the earlier solutions are all valid, and it is more of a coding preference in terms of which layout managers to use. Based on your requirement, here is a working one with standard layout managers only (Grid, GridBag and Border). Have fun, - MS.
import java.awt.;
import javax.swing.;
import javax.swing.border.*;
public class GeneDialog extends JDialog {
private String[] plusMinus = {"+","-"}, tfNames = {
"Symbol", "Chromosome", "Start position", "Stop position"},
listData = {"Gene01", "Gene02", "Gene03", "Gene04", "Gene05", "Gene06",
"Gene07", "Gene08", "Gene09", "Gene10", "Gene11", "Gene12"};
private JTextField[] gtField= new JTextField[tfNames.length];
private JList list = new JList (new DefaultListModel());
public GeneDialog (Frame f, String title) {
super (f, title, true);
Container cp = getContentPane();
cp.setLayout (new GridLayout(1,2));
JScrollPane listScrollPane = new JScrollPane (list);
listScrollPane.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Genes"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
DefaultListModel lm = (DefaultListModel) list.getModel();
for (int k = 0 ; k < listData.length ; k++)
lm.addElement (listData[k]);
cp.add (listScrollPane);
cp.add (controlPanel());
pack();
}
private GridBagConstraints makeGBC (int inset) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets (inset, inset, inset, inset);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = GridBagConstraints.RELATIVE;
return gbc;
}
private JPanel controlPanel() {
JPanel cp = new JPanel (new BorderLayout()),
bp = new JPanel (new GridBagLayout()),
tp = new JPanel (new GridBagLayout());
GridBagConstraints gbc = makeGBC (10);
for (int i = 0 ; i < tfNames.length ; i++) {
JLabel label = new JLabel (tfNames[i], JLabel.TRAILING);
tp.add (label, gbc);
}
gbc.gridx++; gbc.weightx = 1.0f;
for (int i = 0 ; i < tfNames.length ; i++) {
gtField[i] = new JTextField(12);
tp.add (gtField[i], gbc);
}
gbc = makeGBC (10);
for (int i = 0 ; i < plusMinus.length ; i++) {
JButton b = new JButton (plusMinus[i]);
bp.add (b, gbc);
gbc.gridx++;
}
cp.add (tp, "Center");
cp.add (bp, "South");
return cp;
}
public static void main (String[] args) {
new GeneDialog (null, "Genes").setVisible (true);
}}

Try setting the maximum width for both the JScrollPane and the JList that is within it.

I just want to tell that I share the same opinion as javamonkey79. Take a look at MigLayout, you'll love it, and from Java 7 on it will be standart java-onboard layout.

Related

Setting the position of GridBagLayout at the top of JPanel in Java Swing

I have written the following code to add a JLabel to a JPanel but it displays it in the center, while I expected it to be placed at the top of the JPanel.
Here is the piece of code I'm referring to:
JPanel pnlProjects = new JPanel();
pnlProjects.setMinimumSize(new Dimension(10, 300));
GridBagLayout gridBagLayout = new GridBagLayout();
pnlProjects.setLayout(gridBagLayout);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
// add multiple label dynamically;
for (int count = 0; count < project.length; count++) {
lblProjects[count] = new JLabel("Project"+count );
lblProjects[count].setHorizontalAlignment(SwingConstants.LEFT);
lblProjects[count].setHorizontalTextPosition(SwingConstants.LEFT);
lblProjects[count].setBorder(BorderFactory.createBevelBorder(0));
lblProjects[count].setPreferredSize(new Dimension(100, 20));
gridBagConstraints.fill = GridBagConstraints.VERTICAL;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = count;
pnlProjects.add(lblProjects[count], gridBagConstraints);
}
// Add project panel in to the scorllPan
JScrollPane jspProjectlist = new JScrollPane(pnlProjects);
Would anyone be ablt to explain to me how to change it as per my requirement?
You can use next trick: add next code after your loop:
gridBagConstraints.weighty=1;
gridBagConstraints.gridy++;
pnlProjects.add(new JLabel(" "), gridBagConstraints);
That dummy JLabel will grab all space under your project JLabel's.

Placing buttons in a specified location using swing in java

I am trying to learn how to make JAVA programs and I am working with Swing. I am trying to place a button in the top left corner of the window and it keeps going to the top center.
public void createGUI(){
JFrame frame = new JFrame("My Project");
frame.setDefaultCloseOperation(3);
frame.setSize(400, 350);
frame.setVisible(true);
JPanel panel = new JPanel();
frame.add(panel);
addButtonGUI(panel, new JButton(), "test", 1, 1);
}
public void addButtonGUI(JPanel panel, JButton button, String text, int x, int y){
GridBagConstraints gbc = new GridBagConstraints();
button.setText(text);
button.setEnabled(true);
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 2;
gbc.weightx = 1.0D;
gbc.fill = 2;
panel.add(button, gbc);
}
What am I doing wrong or is there a better way to do this?
Please help
You need to set the layout of the JPanel to GridBagLayout to use GridBagConstraints:
JPanel panel = new JPanel(new GridBagLayout());
Also as you only have one effective 'cell' you need to use an anchor and set weighty for the JButton to allow movement in the Y-axis.
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weighty = 1.0;
Also I would set the fill setting to NONE:
gbc.fill = GridBagConstraints.NONE;
so that the button does not occupy the full width of the panel. (2 = HORIZONTAL fill).
instead of
addButtonGUI(panel, new JButton(), "test", 1, 1);
}
what would happen if you used
addButtonGUI(panel, new JButton(), "test", 0, 0);
}

GridBagLayout - Height of one row causes the width of next row to change

The UI I am working on displays a panel which lets a user select a movie and play. There are controls to play, pause, etc.
The layout seems to look the way I want. The panel uses a GridBagLayout. Row 2 displays a text area for status messages and row 3 displays a panel with buttons and a progress bar.
The problem I am running into is that when I have too many lines of text in the text area, the buttons in row 3 wrap around. This is irrespective of the height of the outer frame.
The height in row 2 is affecting the width in row 3. I don't understand this behavior. I am wondering if someone can tell me what is it that I am doing wrong and how I can fix it? I have attached the code.
On a slightly different topic, if you are looking at the code, can you also suggest a way to leave a margin between the bottom-most component and the outermost panel?
Thank you in advance for your help.
Regards,
Peter
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
public MoviePanel() {
this.setLayout(new GridBagLayout());
this.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
this.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
this.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
this.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.weighty = 1.0;
c.insets.top = 10;
this.add(txtInfo, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 2;
c.weightx = 1.0;
this.add(controllerOuter, c);
}
I see several things in your code:
You force the preferredSize of the JButton's. If possible, I would remove that because this will often get you more problems than solutions. If you want to force the preferredSize, you should also pay attention to set the minimum and maximum sizes as well, otherwise you get weird behaviour like the one you are observing
You use a BoxLayout to display the controls. While this is perfectly acceptable, BoxLayout also relies on min/max size to perform the layout, which you did not set.
You use imbricated layouts. This is fine too, but why not use only the GridBagLayout of your MoviePanel?
Usually TextAreas are wrapped in JScrollPane, in case the text is too big. You can also setLineWrap(true) on the TextArea, so that it does not go too far on the right. By setting rows/columns on the TextArea, you will define its preferreSize (to prevent it from depending of the text it contains).
On your GridBagConstraints, the fill property can only be: NONE, VERTICAL, HORIZONTAL or BOTH (You used VERTICAL for one of them). Also, it is not needed to recreate a new instance, you can reuse the same GridBagConstraint over and over, it is automatically cloned by the LayoutManager when you set the constraint for the component.
Now for the solutions, I found several:
When you add the contollerOuter, also specify c.fill = GridBagConstraints.HORIZONTAL; (This is the easiest way to solve your issues)
When you set the preferredSize of the JButtons, also force their minimumSize to the same value.
Use only the GridBagLayout to layout all components. (This would be my favorite)
Replace the FlowLayout by a BoxLayout with a X_AXIS.
Rember that GridBagConstraints properties :
gridx, gridy: specifies the location
gridwidth, gridheight: specifies the colspan/rowspan
weightx, weighty: specifies who gets the extra horizontal/vertical space and in what proportion
anchor: specifies the alignement of the component withing its "cell", if the "cell" is bigger than the component
fill: specifies if the component should stretch to the cell width/height
Just adding one JPanel each for Center and Bottom will do the trick for you, so till your JTextArea your GridBagLayout will server the purpose and after that the BorderLayout of the MAIN JPanel will do. Moreover, adding JScrollPane also to the whole thing reduces the effort needed at other areas. Have a look at the code and output :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class JTextPaneExample extends JPanel
{
private Icon info = UIManager.getIcon("OptionPane.informationIcon");
private Icon error = UIManager.getIcon("OptionPane.errorIcon");
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JTextPane Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setBackground(Color.WHITE);
JPanel centerPanel = new JPanel();
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
centerPanel.setLayout(new GridBagLayout());
centerPanel.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
centerPanel.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
centerPanel.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
centerPanel.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
JScrollPane scroller = new JScrollPane();
scroller.setViewportView(txtInfo);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1.0;
c.insets.top = 10;
centerPanel.add(scroller, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
add(centerPanel, BorderLayout.CENTER);
add(controllerOuter, BorderLayout.PAGE_END);
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JTextPaneExample().createAndDisplayGUI();
}
});
}
}
Here is the output as you add more lines :

JScrollPanes inside GridBagLayout gets resized randomly

Here is a tough one for you guys :)
Basically I have a GridBagLayout with 2 columns : a list wrapped in a scrollpane in each one. The scrollpanes are stretched in BOTH direction.
If I progressively reduce the height of this panel (by dragging the window's edge), I see "random" resizing happening on the scrollpanes:
second one's width gets reduced when first's Hscroll bar appears
then, second one's width gets shrinked again for no reason...
If i don't wrap my components, don't get this behavior.
And if you replace the right hand list with a tree, it will behaves differently:
shrinking the window's height bellow 380-ich px, the tree gets resized...
If i don't wrap my components, the tree gets resized anyway if you keep resizing the window !
Do you guys have any idea what's going on ???
PS: the actual layout i am trying to build is more complex than this example. In the mean time i use SpringLayout to do what i want but it requires to much (not so beautiful) things to setup
protected static ListModel newListModel(int n) {
DefaultListModel lm = new DefaultListModel();
for (int i = 0; i < n; ++i)
lm.addElement("AAA");
return lm;
}
protected static JComponent createContentPane() {
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridy = 0;
gbc.gridx = 0;
pane.add(new JScrollPane(new JList(newListModel(12))), gbc);
++gbc.gridx;
pane.add(new JScrollPane(new JList(newListModel(4))), gbc);
return pane;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.getContentPane().add(createContentPane());
f.setSize(800, 400);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
I have an application with several ScrollPanes in a GridBagLayout, and they also exhibit sudden resizes when I resize the window. It seems that a jump occurs when the actual size of the ScrollPane steps over its "preferred size". I have found a workaround: set the preferred size to 1x1 pixels. If the component has positive weight and stretches BOTH, it will still occupy the whole cell, but will not jump. If you need several cells to resize in different proportions, you can set preferred size of another one to, say, 2x1 pixels.
this is basic principles of GridBagLayout, you forgot for define anchor, then you can be able to fix placed JComponent to the rellative Point, and I think that GridBagLayout complicated your GUI, this LayoutManager is better use for placing lots of JComponents to the one container,(without using nested layout)
for example
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderPanels extends JFrame {
private static final long serialVersionUID = 1L;
public BorderPanels() {
setLayout(new GridBagLayout());// set LayoutManager
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
gbc.gridx = gbc.gridy = 0;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 20;
add(panel1, gbc); // add compoenet to the COntentPane
JPanel panel2 = new JPanel();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "60pct"));
gbc.gridy = 1;
gbc.weightx = gbc.weighty = 60;
//gbc.insets = new Insets(2, 2, 2, 2);
add(panel2, gbc); // add component to the COntentPane
JPanel panel3 = new JPanel();
panel3.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
gbc.gridy = 2;
gbc.weightx = gbc.weighty = 20;
gbc.insets = new Insets(2, 2, 2, 2);
add(panel3, gbc);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
pack();
setVisible(true); // important
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() { // important
public void run() {
BorderPanels borderPanels = new BorderPanels();
}
});
}
}
to avoiding against to complicating simple things
use GridLayout (all JComponents have got same Dimmension on the screen)
use BoxLayout or BorderLayout

GridLayout Help in Java

I have a JPanel with the following code:
JPanel pane = new JPanel();
pane.setLayout(new GridLayout(3, 2, 10, 30));
final JTextField fileName = new JTextField();
pane.add(fileName);
JButton creater = new JButton("Create File");
pane.add(creater);
JButton deleter = new JButton("Delete File");
pane.add(deleter);
I was wondering, how do I make it so that the JTextField takes up two spaces on the GridLayout, while having the two buttons share a row by taking up one space each on the same line?
It is a hard to do with GridLyout. You have create wider cells (e.g. new GridLayout(2, 2, 10, 30), then add TextField to the fist cell. Then you have to create yet another panel with GridLayout(2, 1), put it into the cell in second line and add your button into 1 st cell of this nested grid layout.
Shortly you need GridLayout into other GridLayout.
There are better tools to implement this. First take a look on GridBagLayout. It is just to be sure that life is not always pick-nick :). Then take a look on alternative solutions like MigLayout. It is not a part of JDK but it really powerful tool that makes your life easier.
You cannot do column spans with GridLayout. I recomend you try GridBagLayout and GridBagConstraints
After trashing the suggestion of 3rd party layouts, and since I possess a malevolent hatred of GBL, I thought it was about to time to 'put my code where my mouth is' for public scrutiny (and trashing).
This SSCCE uses a nested layout.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class SimpleLayoutTest {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JPanel ui = new JPanel( new BorderLayout(20,20) );
// I would go for an EmptyBorder here, but the filled
// border is just to demonstrate where the border starts/ends
ui.setBorder( new LineBorder(Color.RED,15) );
// this should be a button that pops a JFileChooser, or perhaps
// a JTree of the existing file system structure with a JButton
// to prompt for the name of a new File.
final JTextField fileName = new JTextField();
ui.add(fileName, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 30));
ui.add(buttonPanel, BorderLayout.CENTER);
JButton creater = new JButton("Create File");
buttonPanel.add(creater);
JButton deleter = new JButton("Delete File");
buttonPanel.add(deleter);
JOptionPane.showMessageDialog(null, ui);
}
};
SwingUtilities.invokeLater(r);
}
}
Take a look at the tutorial on How to Use GridBagLayout.
Sample code:
JPanel pane = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
pane.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
final JTextField fileName = new JTextField();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 0;
pane.add(fileName, c);
JButton creater = new JButton("Create File");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 1;
pane.add(creater, c);
JButton deleter = new JButton("Delete File");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
pane.add(deleter, c);

Categories