Using Java and its SWING library - java

I am trying to code a very simple form using java but i am running into more trouble than i expected because of the way swing lays out components, I have tried various different layout managers and still cannot layout the form the way i would like.
Here is how i would like the form to look: link text
Does anyone have any ideas about how to go about this because im stumped?
Thanks.

The easiest for your purposes is the GridLayout. As Aaron said, Netbeans has a great GUI builder if you don't want to learn the layout managers.

Take a look at Table Layout. It is much easier to use than nearly all of the default layout managers. Your form would be very simple to construct with it.

Short of using gridbaglayout, it is doable by borderlayout, gridlayout and flowlayout. Start by breaking the form into big visual pieces and make sub layouts under top level ones.
For example, in this case I would do this:
Divide the form in two vertical pieces by gridlayout (or borderlayout); top (or central) part for the labels and textfields, bottom (or south) for the button.
In top part, make either flowlayout with center align or another gridlayout to arrange the labels and textfields.
In the bottom part, use flowlayout with center align for the button.
I have worked with Java swing for 4 years and it was a hurdle to design layouts at first, but it gets easier the more you practise.

GridBagLayout can be daunting at first, but it's very flexible, and is worth getting to know.
JButton button = ...;
JLabel[] labels = new JLabel[] {
new JLabel("Label 1"),
...
};
JTextField[] fields = new JTextField[] {
new JTextField(15),
...
};
JPanel[] rows = new JPanel[] {
new JPanel(),
...
}
Container container = getContentPane();
container.setLayout(new GridBagLayout());
GridBagConstraints cons = new GridBagConstraints();
// Layout each row's contents(label + text field)
cons.fill = GridBagConstraints.BOTH;
cons.insets = new Insets(2, 8, 2, 8);
for (int i = 0; i < rows.length; ++i) {
rows[i].setLayout(new GridBagLayout());
// Labels get 30% of the row's extra horizontal space.
cons.weightx = 0.3;
rows[i].add(labels[i], cons);
// Text fields gets 70% of the row's extra horizontal space.
cons.weightx = 0.7;
rows[i].add(fields[i], cons);
// Add each row to the panel, top to bottom
// Each row takes up all of the horizontal space.
cons.gridx = 0;
cons.weightx = 1;
container.add(rows[i], cons);
cons.gridx = GridBagConstraints.RELATIVE;
}
// Add the button at the bottom.
// Dont let button get any extra horizontal space (so it won't stretch)
cons.gridx = 0;
cons.weightx = 0;
cons.fill = GridBagConstraints.NONE;
container.add(button, cons);

By far the easiest to use layout manager I've tried, at least for doing something similar to that, is DesignGridLayout. With that, the code would look something like:
layout.row().grid(new JLabel("JLabel1")).add(new JTextField());
layout.row().grid(new JLabel("JLabel2")).add(new JTextField());
...
layout.row().grid(new JLabel("JLabel5")).add(new JTextField());
layout.row().center().add(new JButton("JButton"));

A form like that should be very easy to design and code by hand. Just keep reading the documentation and playing around.
Another alternative is to use a GUI Builder, Netbeans has one that really impressed me when I took a look at it last year. I don't work in Java anymore so I can't provide you with much detail.
Netbeans GUI Builder (Formerly Matisse)

I would recommed you to use NetBeans.
It's much easier since it generates code with layout manager included, so you don't have to worry about it. It's good for beginners.

I'd do a main Panel with a BorderLayout.
The south area would hold a panel with the button in it.
The center area would hold a panel with a grid layout, grid bag layout or some kind of box layout that would lay your labels and text boxes out.

I really like the JGoodies Forms tool for laying out simple (and complex) forms. It's easy to work with and has great examples. If you want something really nice looking, you can use one of their look and feels too.

Related

GridBagLayout one cell alignment for label

I have for example 3x3 components in grid layout, and I would like all of them to be labels, but since I have some padding I want my labels to be in center of their cell. But I can't seem to manage it...
Part of the relevant code:
panel = new JPanel();
GridBagLayout gridBag = new GridBagLayout();
panel.setLayout(gridBag);
panel.setSize(new Dimension(30, 400));
GridBagConstraints c = new GridBagConstraints()
JLabel lab = new JLabel("proba");
lab.setBorder(outline);
c.fill = GridBagConstraints.BOTH;
c.gridx =2; c.gridy=2; c.ipady = 10; c.ipadx=10;
c.ipadx=100; panel.add(lab,c);
[update]
You really should post an SSCCE so we can all try it and not have to guess where the problem is. My last guess - and this is something you should do regardless of whether it fixes your current problem - is
label.setHorizontalAlignment(JLabel.CENTER);
If your label is centered and fills the entire grid cell, the text will still be left justified by default. The above change will cause the text to be centered within the label.
However if your label is not filling the cell, this won't help.
[original]
It's hard to say exactly what's wrong since this is not a full program, but here are a few comments that might get you on the right track.
First, you should be using setPreferredSize instead of setSize (see Java: Difference between the setPreferredSize() and setSize() methods in components)
When you make this change you will see that the panel is not quite what you want. It's very tall and thin. Perhaps a typo - did you mean (300,400) instead of (30,400)
Now I'm guessing all your labels will be clumped together. In order to get them to spread out you need to add:
c.weightx = .5;
c.weighty = .5;
(actually any non-zero value will work). This is described in http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container.
This should get you close(r) ...

How to reduce the space between the 3 swing checkboxes?

I want to reduce the size between the components with in the Formatting group (left side on the image). How to do this?
JPanel formattingGroup = createGroupWithName("Formatting");
formattingGroup.setMinimumSize(new Dimension(250, 20));
formattingGroup.setLayout(new GridLayout(5, 0));
add(formattingGroup);
final JCheckBox showSurface = new JCheckBox("Show surface");
showSurface.setSelected(true);
formattingGroup.add(showSurface);
final JCheckBox showTerrain = new JCheckBox("Show terrain");
showTerrain.setSelected(true);
formattingGroup.add(showTerrain);
final JCheckBox showVehicleStatus = new JCheckBox("Show vehicle status");
showVehicleStatus.setSelected(true);
formattingGroup.add(showVehicleStatus);
JPanel pnl = createGroupWithName("Depth Stretch");
formattingGroup.add(pnl);
JSlider slider = new JSlider(0, 10);
pnl.add(slider);
When using a GridLayout all components are made the same size.
You are adding a JPanel with a TitledBorder and a JSlider to the grid. Therefore the checkboxes will take the same vertical height as that panel.
You need to use a different layout manager for the panel. Maybe a vertical BoxLayout.
You might look at available size variants, discussed in Resizing a Component.
Use gridbaglayout because that gives you the opportunity to give weights, to columns or rows and set spacing and padding values.
I made a Swing application that contains out of 12 Frames and they all are made with GridBagLayout.
I also tried other before that but they all had limits. That's where the GridBagLayout kicks in. It's a bit harder in begin to understand how it works, but once you get feeling with it, it really is best thing to get the components where you want.
If you want i'll give you a cool example of a frame created with GridBagLayout.

Nested JPanel with GridBagLayout

I have a JFrame with GridBagLayout. weightx and weighty values are assigned different no-zero values and GridBagConstraints.fill = GridBagConstraints.BOTH. I nested a JPanel in one of the cells and gave it a GridBagLayout too. When adding components to the nested JPanel, the cell size where the nested JPanel resides grows on all sides missing up the parent's layout. Insets and padding are not used. How can I fix this problem?Thanks.
This is an example of the GridBagConstraints values:
GridBagConstraints treePanCon = new GridBagConstraints();
treePan.setLayout(treePanGridbag);
treePanCon.fill = GridBagConstraints.BOTH;
treePanCon.weightx = 0.5;
treePanCon.weighty = 1;
treePanCon.gridx = 0;
treePanCon.gridy = 0;
treePanCon.gridwidth = 1;
treePanCon.gridheight = 1;
This is a screenshot before adding components to the nested JPanel:
This a screenshot after adding components to the nested JPanel:
That's exactly what is supposed to happen. Please explain the behavior you're looking for. As an aside the layout managers available with J2SE are less than ideal. Having done a large amount of Swing work in a past life I would highly recommend checking out JGoodies forms: http://www.jgoodies.com/freeware/forms/. Check out the whitepaper, it's easy to use and much more intuitive than GridBag.
This is probably of absolutely no use to you at this late date, but...
It looks like you probably used BOTH when laying out the two new buttons.
If the preferredSize.width on the tree is the width you want for the inner panel,
and you wanted the two new buttons to each be half the width of the tree,
set their preferredSize.width to half the preferredSize.width of the tree, and use NONE on the two buttons.
Use VERTICAL on the tree in the inner panel.
Use VERTICAL on the inner panel in the outer panel.

Best Swing Layout for 2-dimensional grid of buttons?

I'm trying to create a JDialog like the Symbol dialog in Microsoft Word that you get by choosing Symbol... from the Insert menu. Basically, it's an n x m (n and m are not known until runtime) grid of small buttons. I've got a first version of this working nicely using a GridLayout. The problem is that when you resize the dialog (and there is a requirement that you should be able to resize it), the size of the buttons changes. I need the size of the buttons to remain constant.
But I want the dimensions of the grid containing the buttons to change. For example, if the dialog gets wider, but stays the same height, the number of rows should lessen, while the number of columns increases.
I've thought of a couple of ways to fix this:
When the dialog is resized, create a new GridLayout and repopulate it with the buttons. I'm going to try this and see how it looks, but it seems like a clumsy way of doing it.
Use some other type of layout such as a FlowLayout. I took a stab at this, but it put all n x m buttons in one row. I do not want to use horizontal scroll-bars and the buttons ran off the right edge. Anyway, it's supposed to be a 2-dimensional grid of buttons.
What is the best way to solve this layout problem?
Create a buttons panel with GridLayout and set a fixed size (could be calculated at runtime of course) to it. The buttons panel should be contained in a panel of BoxLayout.
Check out the BoxLayout Tutorial
Very Very basic example:
public static void main(String[] args) throws Exception
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonPanel = new JPanel();
JPanel containerPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2,2));
buttonPanel.add(new JButton("1"));
buttonPanel.add(new JButton("2"));
buttonPanel.add(new JButton("3"));
buttonPanel.add(new JButton("4"));
buttonPanel.setPreferredSize(new Dimension(300, 400));
containerPanel.add(buttonPanel);
frame.getContentPane().add(containerPanel);
frame.pack();
frame.setVisible(true);
}
if the dialog gets wider, but stays the same height, the number of rows should lessen, while the number of columns increases.
Wrap Layout might be what you are looking for.
I had a similar issue with a single column of buttons, and found that MiGLayout (third-party, available here) was simple and effective for this. It helped both with making a grid and with setting button sizes, although it took me a day or two to get used to its syntax.
But the key is really setting button sizes; GridLayout certainly seems like the way to go for a layout that is, well, a grid. I haven't tested, but I suspect that the built-in setXSize() methods would work just as well. The GridBagLayout tutorial has examples of some things you can do with sizing/positioning.
FlowLayout would be the way to go but you might have some configuration problems. What layout manager does the parent component use?

How to make JLabels start on the next line

JPanel pMeasure = new JPanel();
....
JLabel economy = new JLabel("Economy");
JLabel regularity = new JLabel("Regularity");
pMeasure.add(economy);
pMeasure.add(regularity);
...
When I run the code above I get this output:
Economy Regularity
How can I get this output, where each JLabel starts on a new line? Thanks
Economy
Regularity
You'll want to play around with layout managers to control the positioning and sizing of the controls in your JPanel. Layout managers are responsible for placing controls, determining where they go, how big they are, how much space is between them, what happens when you resize the window, etc.
There are oodles of different layout managers each of which allows you to layout controls in different ways. The default layout manager is FlowLayout, which as you've seen simply places components next to each other left to right. That's the simplest. Some other common layout managers are:
GridLayout - arranges components in a rectangular grid with equal-size rows and columns
BorderLayout - has one main component in the center and up to four surrounding components above, below, to the left, and to the right.
GridBagLayout - the Big Bertha of all the built-in layout managers, it is the most flexible but also the most complicated to use.
You could, for example, use a BoxLayout to layout the labels.
BoxLayout either stacks its components on top of each other or places them in a row — your choice. You might think of it as a version of FlowLayout, but with greater functionality. Here is a picture of an application that demonstrates using BoxLayout to display a centered column of components:
An example of code using BoxLayout would be:
JPanel pMeasure = new JPanel();
....
JLabel economy = new JLabel("Economy");
JLabel regularity = new JLabel("Regularity");
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.Y_AXIS));
pMeasure.add(economy);
pMeasure.add(regularity);
...
I read this piece of code:
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.VERTICAL));
It seems BoxLayout doesn't have VERTICAL. Upon searching, this will work using the following code:
pMeasure.setLayout(new BoxLayout(pMeasure, BoxLayout.Y_AXIS));
Here is what you need to use:
JLabel economy = new JLabel("<html>Economy<br>Regularity</html>");
A quick way is to use html within the JLabel.
For instance include the <br/> tag.
Otherwise, implement a BoxLayout.
Make a separate JPanel for each line, and set the dimensions to fit each word:
JLabel wordlabel = new JLabel("Word");
JPanel word1 = new JPanel();
word1.setPreferredSize(new Dimension(#,#);
This should work for each word. You can then add each of those JPanels to your main JPanel. This also allows you to add other components next to each word.

Categories

Resources