Swing - GridBagLayout button adding mistake - java

I use this function to create tabs. When I want to add button "?" that will open the Wizard, this button appears at the right side of this JTable. How to edit this?
comp1 - "1. Dp/Drho", comp2 - "2. Df2/Drho", comp3 - "3. SDSS", comp4 - "4. Help". name1-4 - names of this tabs.
static protected JPanel allocateUniPane(Component comp1,Component comp2,Component comp3, Component comp4,
String name1, String name2, String name3, String name4){
JPanel resultPane = new JPanel();
GridBagLayout gridbagforUnionPane = new GridBagLayout();
GridBagConstraints cUnionPane = new GridBagConstraints();
resultPane.setLayout(gridbagforUnionPane);
cUnionPane.fill = GridBagConstraints.BOTH;
cUnionPane.anchor = GridBagConstraints.CENTER;
JButton showWizard = new JButton("?");
cUnionPane.weightx = 0.5;
cUnionPane.weighty = 0.5;
JTabbedPane jtp = new JTabbedPane();
jtp.addTab(name1, comp1);
jtp.addTab(name2, comp2);
jtp.addTab(name3, comp3);
jtp.addTab(name4, comp4);
cUnionPane.gridx = 0;
cUnionPane.gridy = 0;
resultPane.add(jtp,cUnionPane);
cUnionPane.fill = GridBagConstraints.NORTH;
cUnionPane.weightx = 0.5;
cUnionPane.gridx = 1;
cUnionPane.gridy = 0;
resultPane.add(showWizard,cUnionPane);
return resultPane;
}

You want the button to appear to be part of the tabbed pane. You can't use a GridBagLayout (or most other layouts) because they layout positions components in two dimensions on the panel.
Maybe the OverlayLayout will do what you want since it positions components in the third dimension. For example:
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class TabbedPaneWithComponent
{
private static void createAndShowUI()
{
JPanel panel = new JPanel();
panel.setLayout( new OverlayLayout(panel) );
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.add("1", new JTextField("one"));
tabbedPane.add("2", new JTextField("two"));
tabbedPane.setAlignmentX(1.0f);
tabbedPane.setAlignmentY(0.0f);
JCheckBox checkBox = new JCheckBox("Check Me");
checkBox.setOpaque( false );
checkBox.setAlignmentX(1.0f);
checkBox.setAlignmentY(0.0f);
panel.add( checkBox );
panel.add(tabbedPane);
JFrame frame = new JFrame("TabbedPane With Component");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setLocationByPlatform( true );
frame.setSize(400, 100);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

Related

Nicer way to layout TextFields aligned to the top of JPanel

If I use GridLayout or BoxLayout for bunch of JTextField and JLabel pairs it will equally split are of JPanel among the text-fields.
it looks like this:
What I want looks like this ( with text-fields squeezed to the top ):
and I was able to achive that following this answer. The code is:
public void forceSize( int szx, int szy, JComponent comp ){
comp.setPreferredSize( new Dimension( szx, szy ) );
comp.setMaximumSize ( new Dimension( szx, szy ) );
comp.setMinimumSize ( new Dimension( szx, szy ) );
};
public void addLabeledBox( String label_str, JTextField valField, JPanel labelPane, JPanel valuePane ){
JLabel label = new JLabel( label_str );
label.setLabelFor( valField );
labelPane.add( label );
forceSize( 100, 20, label );
forceSize( 100, 20, valField );
valuePane.add( valField );
}
public JComponent makeCityPanel( ){
//JPanel labelPane = new JPanel( new GridLayout(0,1) );
//JPanel valuePane = new JPanel( new GridLayout(0,1) );
JPanel labelPane = new JPanel( ); labelPane.setLayout( new BoxLayout( labelPane, BoxLayout.Y_AXIS ) );
JPanel valuePane = new JPanel( ); valuePane.setLayout( new BoxLayout( valuePane, BoxLayout.Y_AXIS ) );
//panel.setLayout(new GridBagLayout());
//panel.setLayout(new GridBagLayout());
name_field = new JTextField( );
addLabeledBox( "name", name_field, labelPane, valuePane );
ix_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
addLabeledBox( "ix", ix_field, labelPane, valuePane);
iy_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
addLabeledBox( "iy", iy_field, labelPane, valuePane);
factorySpace_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
addLabeledBox( "FactorySpace", factorySpace_field, labelPane, valuePane);
storeSpace_field = new JFormattedTextField( NumberFormat.getNumberInstance() );
addLabeledBox( "StoreSapce", storeSpace_field, labelPane, valuePane );
//JScrollPane cityPanel = new JScrollPane( );
JPanel cityPanel = new JPanel(new GridLayout(1,0));
cityPanel.add( labelPane );
cityPanel.add( valuePane );
cityPanel.setSize( 100 , 100 );
return cityPanel;
}
However, I have feeling that this is not the correct way. ( Also here they say that it is bad ).
So is there a better way?
Another way is to nest panels with different layout managers:
Make the layout of your "main" panel a BorderLayout and add this panel to the tabbed pane.
Create a second "child" panel using your GridLayout and add your components to the panel.
Add the "child" panel to the BorderLayout.PAGE_Start of the "main" panel. This will respect the preferred height of the panel.
Or you can always use a GridBagLayout. It is more involved because you need to specify constraints for each component, but you can get your desired effect with a single panel. Read the section from the Swing tutorial on How to Use GridBagLayout for more information and working examples.
A great layout to use is MigLayout.
Here is a bit of code which achieves what you want using the layout.
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
public class SimpleGUI
{
public JFrame myMainWindow = new JFrame("City View");
JPanel guiPanel = new JPanel();
JLabel name = new JLabel("Name");
JLabel ix = new JLabel("ix");
JLabel iy = new JLabel("iy");
JLabel factorySpace = new JLabel("Factory Space");
JLabel storeSpace = new JLabel("Store Space");
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
JTextField t3 = new JTextField();
JTextField t4 = new JTextField();
JTextField t5 = new JTextField();
int fontMetrics;
FontMetrics fM;
public void runGUI()
{
myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myMainWindow.setLayout(new GridLayout(1,1));
createTestPanel();
myMainWindow.getContentPane().add(guiPanel);
myMainWindow.setVisible(true);
myMainWindow.pack();
myMainWindow.setMinimumSize(new Dimension(myMainWindow.getBounds().getSize()));
}
public void createTestPanel()
{
MigLayout layout = new MigLayout("wrap 2", "[grow]");
guiPanel.setLayout(layout);
fM = name.getFontMetrics(name.getFont());
fontMetrics = fM.stringWidth("Name");
name.setSize(fontMetrics+10,25);
guiPanel.add(name);
guiPanel.add(t1,"growx, width 100:100:");
fM = ix.getFontMetrics(ix.getFont());
fontMetrics = fM.stringWidth("ix");
ix.setSize(fontMetrics+10,25);
guiPanel.add(ix);
guiPanel.add(t2,"growx, width 100:100:");
fM = iy.getFontMetrics(iy.getFont());
fontMetrics = fM.stringWidth("iy");
iy.setSize(fontMetrics+10,25);
guiPanel.add(iy);
guiPanel.add(t3,"growx, width 100:100:");
fM = factorySpace.getFontMetrics(factorySpace.getFont());
fontMetrics = fM.stringWidth("Factory Space");
factorySpace.setSize(fontMetrics+10,25);
guiPanel.add(factorySpace);
guiPanel.add(t4,"growx, width 100:100:");
fM = storeSpace.getFontMetrics(storeSpace.getFont());
fontMetrics = fM.stringWidth("Store Space");
storeSpace.setSize(fontMetrics+10,25);
guiPanel.add(storeSpace);
guiPanel.add(t5,"growx, width 100:100:");
}
public static void main(String[] args)
{
SimpleGUI sG = new SimpleGUI();
sG.runGUI();
}
}
However when you resize this it might look better if when adding the labels you use something like this.
JLabel someLabel = new JLabel("something");
...
MigLayout layout = new MigLayout("wrap 2", "[right][grow]");
guiPanel.setLayout(layout);
guiPanel.add(someLabel,"grow");
Which will give a GUI which looks like this.
Some example code for this would be
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
public class SimpleGUI
{
public JFrame myMainWindow = new JFrame("City View");
JPanel guiPanel = new JPanel();
JLabel name = new JLabel("Name");
JLabel ix = new JLabel("ix");
JLabel iy = new JLabel("iy");
JLabel factorySpace = new JLabel("Factory Space");
JLabel storeSpace = new JLabel("Store Space");
JTextField t1 = new JTextField();
JTextField t2 = new JTextField();
JTextField t3 = new JTextField();
JTextField t4 = new JTextField();
JTextField t5 = new JTextField();
public void runGUI()
{
myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myMainWindow.setLayout(new GridLayout(1,1));
createTestPanel();
myMainWindow.getContentPane().add(guiPanel);
myMainWindow.setVisible(true);
myMainWindow.pack();
myMainWindow.setMinimumSize(new Dimension(myMainWindow.getBounds().getSize()));
}
public void createTestPanel()
{
MigLayout layout = new MigLayout("wrap 2", "[right][grow]");
guiPanel.setLayout(layout);
guiPanel.add(name);
guiPanel.add(t1,"growx, width 100:100:");
guiPanel.add(ix);
guiPanel.add(t2,"growx, width 100:100:");
guiPanel.add(iy);
guiPanel.add(t3,"growx, width 100:100:");
guiPanel.add(factorySpace);
guiPanel.add(t4,"growx, width 100:100:");
guiPanel.add(storeSpace);
guiPanel.add(t5,"growx, width 100:100:");
}
public static void main(String[] args)
{
SimpleGUI sG = new SimpleGUI();
sG.runGUI();
}
}
This looks to me like a classic case for GroupLayout. Unfortunately, the tutorial for GroupLayout is rather overly fond of 'chaining' method calls together, but if you go through it once you should be able to do yours, which is a fairly simple case.
The basic idea is that you add each component once to a vertical layout and once to a horizontal layout; think of it as creating rows columns and rows. Once nice thing about this as compared to GridLayout is that the layout and field 'columns' don't need to be the same width.

Gridlayout button click then load under the buttons a form Java

I really didn't now how to form the question i have a gridlayout with 4 buttons. When the user press Add module i want under the buttons a form instead of a new windows if this is possible.
frame = new JFrame("ModuleViewer");
makeMenu(frame);
Container contentPane = frame.getContentPane();
// Specify the layout manager with nice spacing
contentPane.setLayout(new GridLayout(0, 2));
addModule = new JButton("Toevoegen Module");
contentPane.add(addModule);
overview = new JButton("Overzicht Modules");
contentPane.add(overview);
addSchoolweeks = new JButton("Aapassen schoolweken");
contentPane.add(addSchoolweeks);
weekheavy = new JButton("Weekbelasting");
contentPane.add(weekheavy);
frame.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
I know that i first need to add een action method for the buttons i know how to do that so that isn't important. I only want to know how i could create a layout under the buttons so when a user clicks the layout will be draw.
Each panel can only have one layout, but you can use multiple panels for the desired effect: a top panel using GridLayout to hold your buttons, and a bottom panel using CardLayout to hold multiple other panels, one for each button click. Each of these panels can use whatever layout you want, depending on its contents.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CardLayoutDemo implements Runnable
{
final static String CARD1 = "Red";
final static String CARD2 = "Green";
final static String CARD3 = "Blue";
JPanel cards;
CardLayout cardLayout;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new CardLayoutDemo());
}
public void run()
{
JButton btnRed = createButton("Red");
JButton btnGreen = createButton("Green");
JButton btnBlue = createButton("Blue");
JPanel buttons = new JPanel(new GridLayout(1,3));
buttons.add(btnRed);
buttons.add(btnGreen);
buttons.add(btnBlue);
JPanel card1 = new JPanel();
card1.setBackground(Color.RED);
JPanel card2 = new JPanel();
card2.setBackground(Color.GREEN);
JPanel card3 = new JPanel();
card3.setBackground(Color.BLUE);
cardLayout = new CardLayout();
cards = new JPanel(cardLayout);
cards.add(card1, CARD1);
cards.add(card2, CARD2);
cards.add(card3, CARD3);
JFrame f = new JFrame("CardLayout Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(buttons, BorderLayout.NORTH);
f.add(cards, BorderLayout.CENTER);
f.setSize(300, 200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JButton createButton(final String name)
{
JButton button = new JButton(name);
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
cardLayout.show(cards, name);
}
});
return button;
}
}

JDialog vs JOptionPane vs JPanel correct screen resize

I'm having endless problems when I need to show the user some very complex interface with save or cancel buttons and need this interface to correctly deal with different monitor resolutions.
Suppose for instance this interface needs to fit 17 JTextFields and a resizable JTextArea in a 1280 x 768 monitor (my 13'' laptop has vertical size of 760 pixel).
here is an SSCCE:
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
private static Container layoutComponents(String title, float alignment)
{
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++)
{
JTextField jtextField= new JTextField("jtextfield "+i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20),
new java.awt.Dimension(32767, 20)));
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++)
{
JTextField jtextField= new JTextField("jtextfield "+i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add( new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20),
new java.awt.Dimension(32767, 20)));
}
return container;
}
public static void main(String args[])
{
Container panel1 = layoutComponents("Left", Component.LEFT_ALIGNMENT);
JOptionPane.showConfirmDialog(
null, panel1, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
}
}
Now I would like the above example to behave so that:
The size of the window resizes not cropping any of the content
The size of the window somehow deals differently based on the resolution of the monitor.
I dont' have to statically specify maximumSize, MinimumSize and preferredSize (with the NetBeans GUI editor for instance) so that each time I have to make numerous tests just to find out the correct size
the JtextArea resizes itself vertically depending on the vertical resolution up to a maximum.
You can add an option pane to a dialog, as shown here and here.
As an aside, call setSize() after pack().
Addendum: Here's a variation of your sscce that places the option pane in a scroll pane having an initial size based on screen geometry, as shown here.
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame {
private static Container layoutComponents(String title, float alignment) {
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++) {
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++) {
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
return container;
}
private static Box.Filler createFiller() {
return new Box.Filler(new Dimension(0, 20), new Dimension(0, 20),
new Dimension(Short.MAX_VALUE, 20));
}
public static void main(String args[]) {
Container panel = layoutComponents("Left", Component.LEFT_ALIGNMENT);
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JScrollPane jsp = new JScrollPane(panel){
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 2 * screenSize.height / 3);
}
};
JOptionPane optPane = new JOptionPane();
optPane.setMessage(jsp);
optPane.setMessageType(JOptionPane.PLAIN_MESSAGE);
optPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
JFrame f = new OptionPanePanel();
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.add(optPane);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
}
how can I show something like the above so that:
I don't know what that means. Post your SSCCE that shows us exactly the problem you are having.
This works fine for me:
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
public OptionPanePanel()
{
JPanel panel = new JPanel( new BorderLayout() );
JPanel north = new JPanel();
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
north.add( new JTextField(10) );
JTextArea textArea = new JTextArea(5, 20);
panel.add(north, BorderLayout.NORTH);
panel.add(new JScrollPane(textArea));
int result = JOptionPane.showConfirmDialog(
this, panel, "addRecord", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
}
public static void main(String[] args)
{
JFrame frame = new OptionPanePanel();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
}
Thank you for you answers, so far I came with this solution: get the monitor height and if smaller than 1024 then show a small dialog within a JscrollPane (thanks to trashgod for pointing it), otherwise show a normal dialog with standard height (I have to calculate by trial unfortunately)
import java.awt.*;
import javax.swing.*;
public class OptionPanePanel extends JFrame
{
private static Container layoutComponents(String title, float alignment)
{
JPanel container = new JPanel();
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
for (int i = 0, n = 7; i < n; i++)
{
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
JTextArea jTextArea = new JTextArea(15, 30);
container.add(jTextArea);
for (int i = 6, n = 13; i < n; i++)
{
JTextField jtextField = new JTextField("jtextfield " + i, n);
jtextField.setAlignmentX(alignment);
container.add(jtextField);
container.add(createFiller());
}
return container;
}
private static Box.Filler createFiller()
{
return new Box.Filler(new Dimension(0, 20), new Dimension(0, 20),
new Dimension(Short.MAX_VALUE, 20));
}
public static void main(String args[])
{
Container panel = layoutComponents("Left", Component.LEFT_ALIGNMENT);
/*Let's check the monitor height in multi monitor setup */
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int monitorHeight = gd.getDisplayMode().getHeight();
int result;
if (monitorHeight <= 1024)
{
final Dimension preferredDimension = new Dimension(500, monitorHeight - 110);
panel.setPreferredSize(preferredDimension);
JScrollPane jsp = new JScrollPane(panel)
{
#Override
public Dimension getPreferredSize()
{
return new Dimension(500, 700);
}
};
result = JOptionPane.showOptionDialog(null, jsp,
"",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
new String[]
{
("save"), ("cancel")
}, // this is the array
"default");
}
else
{
final Dimension preferredDimension = new Dimension(500, 700);
panel.setPreferredSize(preferredDimension);
result = JOptionPane.showOptionDialog(null, panel,
"",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
new String[]
{
("save"), ("cancel")
}, // this is the array
"default");
}
if (result == JOptionPane.OK_OPTION)
{
//do something
}
}
}

BoxLayout misunderstanding strut

I'm prgramming a simple input diagram in Swing. I use boxLayout to create a simple GUI of user input. Problem is that creating a horizontal strut between the JPanel of all the labels and the JPanel of the JTextFields causes the whole panel to shift downwards (weird) this is the whole panel:
private JPanel secondCard() {
//main panel. set the boxlayout
secondCard = new JPanel();
secondCard.setLayout(new BoxLayout(secondCard,BoxLayout.Y_AXIS));
// create vertical strut for looks
secondCard.add(Box.createVerticalStrut(20));
// create title. center it.
JLabel title = new JLabel("Configure main network parameters ");
title.setAlignmentX(CENTER_ALIGNMENT);
secondCard.add(title);
// create vertical strut for looks
secondCard.add(Box.createVerticalStrut(20));
// create panel for the description labels
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel,BoxLayout.Y_AXIS));
labelPanel.setAlignmentX(LEFT_ALIGNMENT);
JLabel inPut =new JLabel("number of inputs");
inPut.setAlignmentX(LEFT_ALIGNMENT);
labelPanel.add(inPut);
inPut =new JLabel("number of outputs");
inPut.setAlignmentX(LEFT_ALIGNMENT);
labelPanel.add(inPut);
inPut =new JLabel("number of layers");
inPut.setAlignmentX(LEFT_ALIGNMENT);
labelPanel.add(inPut);
JPanel textFieldPanel = new JPanel();
textFieldPanel.setLayout(new BoxLayout(textFieldPanel,BoxLayout.Y_AXIS));
textFieldPanel.setAlignmentX(LEFT_ALIGNMENT);
JTextField inputTextField = new JTextField();
inputTextField.setAlignmentX(LEFT_ALIGNMENT);
textFieldPanel.add(inputTextField);
inputTextField.setMinimumSize(new Dimension(0,0));
inputTextField = new JTextField();
inputTextField.setAlignmentX(LEFT_ALIGNMENT);
textFieldPanel.add(inputTextField);
inputTextField.setMinimumSize(new Dimension(0,0));
inputTextField = new JTextField();
inputTextField.setAlignmentX(LEFT_ALIGNMENT);
textFieldPanel.add(inputTextField);
inputTextField.setMinimumSize(new Dimension(0,0));
textFieldPanel.setMaximumSize(new Dimension(50, labelPanel.getMaximumSize().height));
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel,BoxLayout.X_AXIS));
inputPanel.setAlignmentX(CENTER_ALIGNMENT);
inputPanel.add(labelPanel);
//this is the problem strut!! it causes inputPanel to shift downwards
inputPanel.add(Box.createHorizontalStrut(20));
inputPanel.add(textFieldPanel);
secondCard.add(inputPanel);
return secondCard;
}
without the strut it looks like:
With strut it looks like (I know I suck at picture editing):
You are adding a Box strut to a BoxLayout.
As the javadoc states, createHorizontalStrut(int width):
Creates an invisible, fixed-width component. In a horizontal box, you
typically use this method to force a certain amount of space between
two components. In a vertical box, you might use this method to force
the box to be at least the specified width. The invisible component
has no height unless excess space is available, in which case it takes
its share of available space, just like any other component that has
no maximum height.
As such, it is filling the height between your title JLabel and the bottom of the JPanel.
You might want to consider using Box.createRigidArea(new Dimension(20, height)) instead, where height could be specified or set to the height of labelPanel.
Or, you could reconsider the layout for your JPanel - take a look at the visual guide.
For future reference, if you cannot make sense of your Swing layout, try putting adding a coloured LineBorder to the JComponents you're unsure of. In this case, the Box struts are not JComponents but Components, so you'd have to put them into a JPanel, but this would at least have shown you what space each component was taking up in your top-level JPanel.
use Cardlayout for wizard logics
put JLabel(Configure ...., JLabel.CENTER) to the BorderLayout.NORTH
put JPanel with JButtons to the BorderLayout.SOUTH
put JPanel with SpringLayout, GridLayout, or GridBagLayout to the BorderLayout.CENTER
Top-Level Container have got implemened BorderLayout by default, then there no reason to re_define BorderLayout
above mentioned steps are called NestedLayout
alternative are put all JComponents by using GridBagLayout, SpringLayout or todays MigLayout to the one JPanel, but why bothering
Example of a nested layout, one using BorderLayout, FlowLayout (JPanel's default), and GridBagLayout:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class LayoutFoo {
private static final String TITLE = "Configure Main Foobar Parameters";
private static final String[] LABEL_TEXTS = {
"Number of Spams", "Number of Frapzats", "Number of Zignuts"
};
private static final int TEXTFIELD_SIZE = 10;
private static final Insets WEST_INSETS = new Insets(5, 5, 5, 10);
private static final Insets EAST_INSETS = new Insets(5, 10, 5, 5);
private static final int EB_GAP = 5;
private Map<String, JTextField> textFieldMap = new HashMap<String, JTextField>();
public JPanel getConfigFooPanel() {
JPanel textFieldPanel = new JPanel(new GridBagLayout());
for (int i = 0; i < LABEL_TEXTS.length; i++) {
addTextAndField(textFieldPanel, LABEL_TEXTS[i], i);
}
int blVertGap = 20;
JPanel borderLayoutPanel = new JPanel(new BorderLayout(0, blVertGap));
borderLayoutPanel.setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP,
EB_GAP, EB_GAP));
JLabel titleLabel = new JLabel(TITLE, JLabel.CENTER);
borderLayoutPanel.add(titleLabel, BorderLayout.PAGE_START);
borderLayoutPanel.add(textFieldPanel, BorderLayout.CENTER);
JPanel outerWrapperFlowPanel = new JPanel();
outerWrapperFlowPanel.add(borderLayoutPanel);
return outerWrapperFlowPanel;
}
public String getFieldText(String labelText) {
JTextField field = textFieldMap.get(labelText);
if (field == null) {
return ""; // ?? throw exception
} else {
return field.getText();
}
}
private void addTextAndField(JPanel panel, String text, int i) {
JLabel label = new JLabel(text, JLabel.LEFT);
JTextField textField = new JTextField(TEXTFIELD_SIZE);
textFieldMap.put(text, textField);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = i;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = WEST_INSETS;
panel.add(label, gbc);
gbc.gridx = 1;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = EAST_INSETS;
panel.add(textField, gbc);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("LayoutFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new LayoutFoo().getConfigFooPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Java Swing - JButtons on New Line

I am trying to print out a dynamically generated list of buttons with each button on a new line.
public void addComponentToPane(Container pane) {
JTabbedPane tabbedPane = new JTabbedPane();
//Create the "cards".
JPanel card1 = new JPanel() {
JPanel card1 = new JPanel()
...
int n = 10;
JButton[] jButtons = new JButton[10];
for(int i=0; i<n; i++){
jButtons[i] = new JButton("test" + i);
card1.add(jButtons[i]);
//card1.add("<br>");//<--this is wrong; but hopefully you get my point.
jButtons[i].addActionListener(this);
}
Put them into a box:
Box card1 = Box.createVerticalBox();
or, if you want all the buttons to have the same size, use GridLayout with one column:
JPanel card1 = new JPanel(new GridLayout(n, 1))
Here are two solutions using a constrained GridLayout and a BoxLayout
I prefer the GridLayout (on the left) since it normalizes the width of the buttons and makes it easy to add a small space between them.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class DynamicButtons {
public static void main(String[] args) {
final JPanel gui = new JPanel(new BorderLayout());
final JPanel gridButton = new JPanel(new GridLayout(0,1,2,2));
gridButton.add(new JButton("Button 1"));
JPanel gridConstrain = new JPanel(new BorderLayout());
gridConstrain.add(gridButton, BorderLayout.NORTH);
final Box boxButton = Box.createVerticalBox();
boxButton.add(new JButton("Button 1"));
JButton b = new JButton("Add Button");
b.addActionListener( new ActionListener() {
int count = 2;
public void actionPerformed(ActionEvent ae) {
gridButton.add(new JButton("Button " + count));
boxButton.add(new JButton("Button " + count));
count++;
gui.revalidate();
}
});
gui.add(b, BorderLayout.NORTH);
JSplitPane sp = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
new JScrollPane(gridConstrain),
new JScrollPane(boxButton));
gui.add(sp, BorderLayout.CENTER);
gui.setPreferredSize(new Dimension(250,150));
JOptionPane.showMessageDialog(null, gui);
}
}
Use GridBagLayout and set GridBagConstaints.gridy field.
I suppose you need something like this :
For this you require a Box Layout , see this for more details : How to Use BoxLayout
and if needed here is a demo : Java Tutorials Code Sample – BoxLayoutDemo.java

Categories