I need to write an applet that converts char values to ascii values. Right now I'm just trying to get the layout of the applet right, but for some reason my JTextFields are showing up very strangely and I don't know how to go about fixing it. One is very large and the other is extremely small.
I had some trouble getting GridLayout to work the way I wanted, and I have some feeling that the problems have something to do with that but I don't know for sure.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class Ex1_2 extends JApplet implements ActionListener
{
private JTextField charInput;
private JLabel display1;
private JLabel dummy;
private JLabel display2;
private JLabel welcome;
private JTextField ascii;
private JLabel error;
Container pane = getContentPane();
public void init()
{
pane.setLayout(new BorderLayout());
pane.setBackground(Color.orange);
display1 = new JLabel("Character", SwingConstants.CENTER);
display2 = new JLabel("ASCII code", SwingConstants.CENTER);
dummy = new JLabel("", SwingConstants.CENTER);
dummy.setBackground(Color.orange);
welcome = new JLabel("Char <-> ASCII converter", SwingConstants.CENTER);
welcome.setForeground(Color.blue);
pane.add(welcome, BorderLayout.NORTH);
pane.add(dummy, BorderLayout.SOUTH);
//charInput.addActionListener(this);
add(addMiddle());
}
JPanel addMiddle()
{
JPanel p = new JPanel();
p.setLayout(new GridLayout(0, 2, 10, -5));
p.setBackground(Color.green);
p.add(display1, BorderLayout.SOUTH);
p.add(display2, BorderLayout.SOUTH);
p.add(dummy);
p.add(addInnerLeft());
p.add(addInnerRight());
p.add(dummy);
return p;
}
JPanel addInnerLeft()
{
JPanel p2 = new JPanel(new GridLayout(0, 2));
p2.setBackground(Color.yellow);
pane.add(p2);
charInput = new JTextField("");
charInput.setForeground(Color.black);
//p2.add(charInput);
return p2;
}
JPanel addInnerRight()
{
JPanel p3 = new JPanel();
p3.setBackground(Color.yellow);
ascii = new JTextField("");
ascii.setForeground(Color.black);
//p3.add(ascii);
return p3;
}
public void actionPerformed(ActionEvent e)
{
}
}
A quick fix:
Consider setting your JTextFields's column property. For instance, if you use:
ascii = new JTextField("", 5);
your ascii JTextField now gets some preferred size width.
A better long-term fix:
Study, learn and use the layout managers to better advantage.
Note that a problem with JApplets is that the size is specified by the HTML code and not by the layout managers (as far as I understand things), and so you must take care to make sure that the GUI's are sized big enough.
e.g., with layouts, I got this:
The second text field is sized that way because you initialized it:
ascii = new JTextField("");
This represents that the text field has a string value for its name where the length of the string is zero. The text field is being sized automatically according to the text it contains. Since it contains a string with zero length, the size of the text field is so small.
You could use the setColumns(int columns) method on the text field to give it a fixed width, so that it can get a preferred size.
Related
I am trying to figure why I can't see my labels like when I try to put 2 labels into 1 panel they dissapear, the only way I can seem to get it to work is if I add everything to JFrame with no type of hierarchy.
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
static JRadioButton tirebg1 = new JRadioButton();
static JRadioButton tirebg2 = new JRadioButton();
static JRadioButton tirebg3 = new JRadioButton();
static ButtonGroup tirebg = new ButtonGroup();
public static void main(String[] args) {
Car cspeed = new Car();
int carspeed = cspeed.getSpeed();
Motorcycle mspeed = new Motorcycle();
int motospeed = mspeed.getSpeed();
Truck tspeed = new Truck();
int truckSpeed = tspeed.getSpeed();
JRadioButton wide = new JRadioButton();
JLabel tbuttons = new JLabel();
JPanel topPane = new JPanel();
tirebg.add(tirebg1);
tirebg.add(tirebg2);
tirebg.add(tirebg3);
JFrame GUIframe = new JFrame();
JLabel label1 = new JLabel();
label1.setLayout(new FlowLayout());
JLabel tireLabel = new JLabel();
String[] names = new String[5];
names[0] = "Car";
names[1] = "Truck";
names[2] = "Motorcycle";
String[] hello = new String[5];
GUIframe.setSize(500, 500);
GUIframe.setDefaultCloseOperation(EXIT_ON_CLOSE);
JList list = new JList(names);
list.setBorder(BorderFactory.createRaisedSoftBevelBorder());
label1.add(list);
tireLabel.add(tirebg1);
tireLabel.add(tirebg2);
tireLabel.add(tirebg3);
topPane.add(tbuttons);
topPane.add(tireLabel);
topPane.setLayout(new FlowLayout());
label1.setBackground(Color.cyan);
GUIframe.add(topPane);
GUIframe.validate();
GUIframe.setBackground(Color.GREEN);
GUIframe.setVisible(true);
}
}
Since you posted a lot of code and I'm not sure what were you trying to achieve, I modified your code adding 3 JLabels at the topPane. And 3 JRadioButtons (I didn't add the ButtonGroup) below on a second JPanel, I commented how to make them appear on a vertical and horizontal align.
Something you should take into account is:
Don't extend and create objects from JFrame (One or the other, not both, I recommend you to create objects).
You were giving your JPanel a Layout after adding components to it, it should be done before.
From the above point, you were also giving your Layout to your JLabel not your JPanel.
You were adding a JList into a JLabel.
You missed to have a class constructor too.
Don't have multiple JFrames for more see The use of multiple JFrames, Good / Bad practice
Next time post a code which has no dependencies such as your Truck, Car and Motorcycle classes (i.e. a Runnable example). And use plain text instead so we can copy-paste the code and see the issue. Also try posting images (or the link and we can edit to add it).
Now, the outpus of my own program are:
And it was done with the following code.
import javax.swing.*;
import java.awt.*;
public class GUIExample {
JFrame frame;
JLabel label1, label2, label3;
JPanel topPane, radioPane;
JRadioButton radio1, radio2, radio3;
public static void main(String[] args) {
new GUIExample();
}
GUIExample () {
frame = new JFrame();
topPane = new JPanel();
radioPane = new JPanel();
topPane.setLayout(new FlowLayout());
// radioPane.setLayout(new BoxLayout(radioPane, BoxLayout.PAGE_AXIS)); //Vertical align
radioPane.setLayout(new FlowLayout()); //Horizontal align
label1 = new JLabel("Car");
label2 = new JLabel("Motorcycle");
label3 = new JLabel("Truck");
radio1 = new JRadioButton("Radio1");
radio2 = new JRadioButton("Radio2");
radio3 = new JRadioButton("Radio3");
topPane.add(label1);
topPane.add(label2);
topPane.add(label3);
radioPane.add(radio1);
radioPane.add(radio2);
radioPane.add(radio3);
frame.add(topPane, BorderLayout.PAGE_START);
frame.add(radioPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Your code has several issues, but the reason that you're not seeing the tireLabel or the tbuttons component is because you're using a JLabel. Understand that JLabel is not built to act as a container for other components. The key concept is that it calculates its preferred size based on the text it holds and/or the icon it holds and (and this is key) not on the sizes or preferred sizes of any components it might hold.
The solution is to not use JLabel for a purpose it wasn't intended for but rather to use a JPanel which does adjust its own preferred size depending on the sizes of its held components and its layouts.
Other unrelated issues:
Your program extends JFrame but never uses itself as a JFrame, something that will confuse anyone who reads your code. If you're not going to use the instance of the class as a JFrame, then don't extend the class.
Your program isn't an OOP-compliant program, one with instance fields, public methods, and such, but rather is little more than one large static main method, and this will result in a large God-method, one with too much responsibility, and one that is very difficult to debug and to maintain. Don't throw out the OOP baby with the bath water -- Create Swing GUI's in a well-behaved OOP-compliant way.
You're trying to set background colors to components that are not opaque (a JLabel), to components that are never added to the GUI (label1), or are not fully displayed (the JFrame).
You're using FlowLayout an awful lot, and in places where other layouts would probably serve you better. It's as if it's the only layout that you know how to use, and so you use it. Try branching out and using other layouts including GridLayout for your JRadioButton container and perhaps BorderLayout for the main container (JPanel).
So I am a computer science student and I've finished my first year. I wanted to create a simple program and I realized that I am so tired of using no layout;
this.setLayout(null);
It is so tiresome to add bounds to every single component. Well, I have been using JPanel components and GridLayout a lot, which have made my work a bit easier. But I am tired of it.
I care very much about the look of the GUI I make and use almost half the time programming to make the GUI look good before I start adding the functionality of the code. By not using a layout and adding bounds I am forced to setResizable(false) because it looks bad if I change the size of the JFrame.
I've been searching a bit, and I know of BorderLayout, and FlowLayout, but I don't like them. Is there any Layout that keeps the relative size of the components with respect to the size of the window?
For example I want to make a simple program that looks like this: (Quick sketch in Photoshop)
I can easily make this with 3 panels, but as I said, if I change the size of the frame everything stays in place instead of being relative to the window-size.
Can you guys help me?
This design looks for me to fit the BorderLayout, where in the NORTH you have the values that changes the CENTER you have the main part, and the SOUTH you have the buttons.
Link to the Oracle Border Layout
You can apply this BorderLayout to the JFrame, then create 3 JPanels for each of the NORTH,CENTER and SOUTH sections. If you want to use responsive design for the components and panels, take a look at GridBagLayout which is much more flexible than the GridLayout
Layout management is a very complex problem, I don't think people really appreciate just how complex it really is.
No one layout is ever going to achieve everything your want, in most cases, you will need to resort to two or more layouts, especially as your requirements become more complex.
For example, the following is simply a BorderLayout at the base and the buttons on a JPanel using a FlowLayout
Which is achieved by using
JList listOfThings = new JList(...);
JTextField tf = new JTextField();
JButton add = new JButton("Add");
JButton delete = new JButton("Delete");
JButton go = new JButton("Go...");
JPanel buttons = new JPanel();
buttons.add(add);
buttons.add(delete);
buttons.add(go);
add(new BorderLayout());
add(tf, BorderLayout.NORTH);
add(new JScrollPane(listOfThings));
add(buttons, BorderLayout.SOUTH);
For more complex layouts, I would consider using something like GridBagLayout. You may also want to consider MigLayout as an alternative
Take a look at Laying Out Components Within a Container for more details about using layout managers
I'd like to use the combination of BorderLayout and BoxLayout. BorderLayout let me put the component based on their relative location's relation and BoxLayout let me manage the subtle distance ( create some white space). You can use component.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right)); to achieve this goal too.
Here is a demo and hope it can help you.
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class LayoutTest{
private JTextField jTextField;
public void createUI(){
JFrame frame = new JFrame("Layout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.add(new TextFieldPanel());
mainPanel.add(Box.createVerticalStrut(8));
mainPanel.add(new ListPanel());
mainPanel.add(Box.createVerticalStrut(8));
mainPanel.add(new ButtonPanel());
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
LayoutTest layoutTest = new LayoutTest();
layoutTest.createUI();
}
#SuppressWarnings("serial")
class TextFieldPanel extends JPanel{
public TextFieldPanel(){
setLayout(new BorderLayout());
jTextField = new JTextField();
jTextField.setEditable(false);
add(jTextField,BorderLayout.CENTER);
}
}
#SuppressWarnings("serial")
class ListPanel extends JPanel implements ListSelectionListener{
private JList<String> list;
public ListPanel(){
setLayout(new BorderLayout());
String stringArr[] = new String[30];
for (int i = 0; i < 30; i++) {
stringArr[i] = "JList :This line is item" + i;
}
list = new JList<String>(stringArr);
JScrollPane scrollPane = new JScrollPane(list);
add(scrollPane,BorderLayout.CENTER);
setBackground(new Color(211,211,211));
list.addListSelectionListener(this);
}
#Override
public void valueChanged(ListSelectionEvent e) {
// TODO Auto-generated method stub
jTextField.setText(list.getSelectedValue());
}
}
#SuppressWarnings("serial")
class ButtonPanel extends JPanel{
public ButtonPanel(){
JButton button1 = new JButton("Button1");
JButton button2 = new JButton("Button2");
JButton button3 = new JButton("Button3");
setLayout(new BorderLayout());
add(button1,BorderLayout.WEST);
add(button2,BorderLayout.CENTER);
add(button3,BorderLayout.EAST);
}
}
}
Here is the effect:
You can use BoxLayout for ButtonPanel if you don't want to let the button's size change.
#SuppressWarnings("serial")
class ButtonPanel extends JPanel{
public ButtonPanel(){
JButton button1 = new JButton("Button1");
JButton button2 = new JButton("Button2");
JButton button3 = new JButton("Button3");
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(button1);
add(Box.createHorizontalStrut(8));
add(button2);
add(Box.createHorizontalStrut(8));
add(button3);
}
}
And the effect is like this:
For more infomation about using BoxLayout to generate whitespace, you can refer to https://stackoverflow.com/a/22525005/3378204
Try GridBagLayout.
Your sketch is actually quite close to the one of the examples in the official tutorial.
HVLayout keeps the relative size of the components with respect to the size of the window, that is, if you configure components to have a relative size (e.g. buttons usually do not grow or shrink - they stick to their preferred size). This SO question was one of the motivations for me to push HVLayout to a release and a screenshot is included (showing big window size, smalll size and preferred "default" size):
Source code for the window is in RelativeToWindowSize.java
A number of helper-classes from HVLayout are used to build the window, so I don't think it will be of much use here, but to get an impression, the "build window" part shown below:
public RelativeToWindowSize build() {
CSize cs = new CSize();
CForm form = new CForm(new VBox(new Insets(2, 4, 2, 4)), cs);
addTitledBorder(form.get(), "Vertical box", Color.BLACK);
form.add(new JScrollPane(
tfield = new JTextArea("Value that changes with value choosen from list.\nhttp://stackoverflow.com/questions/24462297/layout-relative-to-screensize/")
)).csize().setAreaSize(1.0f, 2.5f).fixedMinHeight().setMaxHeight(4.0f);
// tfield shows mono-spaced font by default.
tfield.setFont(SwingUtils.getUIFont());
form.add(new JScrollPane(vlist = new JList<String>(getListValues())))
.csize().setAreaSize(1.0f, 5.0f);
form.addChild(new HBox());
addTitledBorder(form.get(), "Horizontal box", Color.RED);
form.addChild(new HBox(SwingConstants.CENTER));
addTitledBorder(form.get(), "Centered box.", Color.BLUE);
form.add(createButton(cs, "Add"));
form.add(createButton(cs, "Modify"));
form.up();
form.addChild(new HBox(SwingConstants.TRAILING));
addTitledBorder(form.get(), "Trailing box", Color.GREEN);
form.add(createButton(cs, "Delete"));
setContentPane(form.getRoot());
pack();
setLocationByPlatform(true);
//applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
vlist.addListSelectionListener(this);
log.debug(getClass().getName() + " build.");
return this;
}
private Component createButton(CSize cs, String text) {
// For purpose of demo, let button shrink in width.
return cs.set(new TButton(text)).setFixed().shrinkWidth(0.33f).get();
}
I have a Java program where i would prefer if i could get a very specific layout.
This is what I get:
JLabel JToggleButon JLabel JToggleButon
This is what I want:
JLabel JToggleButon
JLabel JToggleButon
This is the code:
package Main;
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
public class SystemWindow {
static JFrame window = new JFrame("System statistics");
static JToggleButton button = new JToggleButton("Push me");
static JLabel status = new JLabel("Status: ");
static JLabel status2 = new JLabel("Status: ");
static JToggleButton button2 = new JToggleButton("Push me");
static FlowLayout layout = new FlowLayout();
public static void openWindow(){
window.setLayout(new GridBagLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(status);
window.add(button);
window.add(status2);
window.add(button2);
window.setSize(100, 100);
window.pack();
window.setSize(200,70);
window.setVisible(true);
while(true){
status.setText("Status: "+button.isSelected());
status2.setText("Status: "+button2.isSelected());
}
}
}
p.s: Wrote the code in eclipse.
you can use GridLayout where you can specify rows, columns and spacings
i.e. add a jpanel with gridlayout and add these elements inside this panel
new JPanel(new GridLayout(2,2,5,5));
first parameter is the rows, second the columns and the others are the horizontal and vertical spacing between controls
I guess this works
JPanel panel = new JPanel(new GridLayout(2,2,5,5));
window.add(panel);
panel.add(status);
panel.add(button);
panel.add(status2);
panel.add(button2);
The behaviour you are getting is the default behaviour for FlowLayout. Read more about it here. Read morea bout layouts here and choose what you prefer.
As you are using GridBayLayout you have to provide some position constraints when adding controls to container. Here you have complete guide. 3rd party layout manager as MigLayout should suit your needs too.
while(true){
status.setText("Status: "+button.isSelected());
status2.setText("Status: "+button2.isSelected());
}
your computer is going to explode thanks to that code :)
I am trying to create a form manually with code rather than the designer, I have already created using the designer.
This is the manual code that I came up with so far but I am having problem aligning the label and textfield side by side
mport java.awt.*;
import javax.swing.*;
/**
*
* #author jackandjill
*/
public class summinup_copy extends JFrame
{
private JLabel lblTitle, lblOctal, lblDecimal, lblMessage ;
private JTextField txtOctal, txtDecimal;
private JButton calculate_btn;
public summinup_copy()
{
JPanel panel = (JPanel)this.getContentPane();
panel.setLayout(new BorderLayout());
JPanel panCentre = new JPanel();
panCentre.setLayout(new GridLayout(3,3));
lblTitle = new JLabel("Area of Triangle");
lblTitle.setFont(new Font("Arial", 1, 20));
lblTitle.setHorizontalAlignment(JLabel.CENTER);
lblOctal = new JLabel("Octal");
lblOctal.setHorizontalAlignment(JLabel.CENTER) ;
//lblDecimal = new JLabel("Decimal");
//
//lblDecimal.setHorizontalAlignment(JLabel.CENTER);
lblMessage = new JLabel("Result will be displayed here");
lblMessage.setForeground(Color.red);
lblMessage.setHorizontalAlignment(JLabel.CENTER);
txtOctal = new JTextField("0", 5);
txtOctal.setHorizontalAlignment(JLabel.CENTER);
//txtDecimal = new JTextField("0", 5);
//
//txtDecimal.setHorizontalAlignment(JLabel.CENTER);
calculate_btn = new JButton("Calculate Area");
//AHandlerClass aListener = new AHandlerClass() ;
//btnOtoD.addActionListener(aListener);
//btnDtoO.addActionListener(aListener);
panCentre.add(lblOctal);
//panCentre.add(lblDecimal);
panCentre.add(txtOctal);
//panCentre.add(txtDecimal);
panCentre.add(calculate_btn);
//panCentre.add(btnDtoO);
panel.add(lblTitle, BorderLayout.NORTH);
panel.add(lblMessage,BorderLayout.SOUTH);
panel.add(panCentre, BorderLayout.CENTER);
}
public static void main(String args[]) {
summinup_copy myGui = new summinup_copy();
myGui.setTitle("Bharath");
myGui.setSize(400, 200);
myGui.setVisible(true);
}
}
As you have already figured out, you have to use LayoutManagers when coding a Swing GUI by hand. Here are some links that can help you figure out which LayoutManager is appropriate for a given look:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html
In order to place a JLabel next to a JTextField or other component, I usually use GridLayout or GridBagLayout. I find that it takes a lot of trial and error trying to get components to look the way I want. Often you have to have layers of embedded JPanels to get it just right.
I have some troubles with positioning my label/password field.
With this code they both get positioned in the center next to each other, while I actually want them in the middle of my panel on top of each other.
Does anyone know how I should do that?
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
public class Paneel_Pincode extends JPanel {
Paneel_Pincode() {
setLayout(new FlowLayout());
JPasswordField pincode = new JPasswordField(15);
pincode.setLocation(500, 500);
JLabel pinInvoer = new JLabel();
ImageIcon pin1 = new ImageIcon("images/voerPincodeIn.jpg");
pinInvoer.setIcon(pin1);
pinInvoer.setLocation(500,700);
add(pincode);
add(pinInvoer);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000,1000);
f.setLocationRelativeTo(null);
f.add(new Paneel_Pincode());
f.setVisible(true);
}
}
To get the hang of layouts, I'd recommend reading my article on them (http://java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/). It's old, but the concepts and how FlowLayout works are detailed.
What do you mean by "on top of each other"?
If you mean like
Password
<field>
EDIT: I REMEMBERED AN EASIER WAY TO DO THIS (completely in the JDK/JRE)...
(This is similar to what I'm doing with the BoxBeans below, but you don't need the BoxBeans. I created BoxBeans to be able to use BoxLayout in a UI builder a long time ago...)
JLabel label = new JLabel("Password") {
#Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
JPasswordField field = new JPasswordField() {
#Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
field.setColumns(10);
Box verticalBox = Box.createVerticalBox();
verticalBox.add(Box.createVerticalGlue());
verticalBox.add(label);
verticalBox.add(field);
verticalBox.add(Box.createVerticalGlue());
//
Box horizontalBox = Box.createHorizontalBox();
horizontalBox.add(Box.createHorizontalGlue());
horizontalBox.add(verticalBox);
horizontalBox.add(Box.createHorizontalGlue());
add(horizontalBox);
Previous answer for reference...
I DO NOT RECOMMEND THE FOLLOWING BUT IT MAY HELP OTHER READERS WITH IDEAS
You can do something like
setLayout(FlowLayout());
JPanel group = new JPanel(new BorderLayout());
group.add(new JLabel("Password"), BorderLayout.NORTH);
group.add(passwordField, BorderLayout.SOUTH);
add(group);
This will create a little panel in the top-center of the overall UI that contains the Password and field.
Note that the nested BorderLayout ensures that the label and field each get their preferred size. You'll need to call setColumns on the field to the number of chars you'd like displayed.
If you want to center the label/field vertically as well, you could do the following
setLayout(new GridBagLayout());
//
add(new JLabel("Password"),
new GridBagConstraints(0,0,1,1,1,1,
GridBagConstraints.SOUTH,GridBagConstraints.NONE,
new Insets(3,3,3,3), 0,0));
field.setColumns(10);
add(field, new GridBagConstraints(0,1,1,1,1,1,
GridBagConstraints.NORTH,GridBagConstraints.NONE,
new Insets(3,3,3,3), 0,0));
I hate using GridBagLayout in general, so I'll add a version using BoxLayout (but it's a bit trickier due to the preferred size settings)
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
//
JPanel stuffH = new JPanel();
f.add(stuffH, BorderLayout.CENTER);
stuffH.setLayout(new BoxLayout(stuffH, BoxLayout.X_AXIS));
//
JPanel stuffV = new JPanel();
stuffV.setLayout(new BoxLayout(stuffV, BoxLayout.Y_AXIS));
//
JLabel label = new JLabel("Password");
BoxAdapter labelAdapter = new BoxAdapter();
labelAdapter.add(label);
JPasswordField field = new JPasswordField();
field.setColumns(10);
BoxAdapter fieldAdapter = new BoxAdapter();
fieldAdapter.add(field);
//
stuffV.add(new VerticalGlue()); // for vertical spacing
stuffV.add(labelAdapter);
stuffV.add(fieldAdapter);
stuffV.add(new VerticalGlue()); // for vertical spacing
//
stuffH.add(new HorizontalGlue()); // for horizontal spacing
stuffH.add(stuffV);
stuffH.add(new HorizontalGlue()); // for horizontal spacing
//
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
A few notes on this:
I'm using my BoxBeans helper classes - see http://javadude.com/tools/boxbeans. This page is based on VisualAge for Java, but the jar at the bottom of the page can be used outside VAJ. I just tried it in eclipse, for example.
AFAICS, you cannot set a jframe's layout directly to BoxLayout, so I added an extra panel in between. There's a check in BoxLayout that has trouble with the automatic indirection of the content pane.
I nested the BoxLayouts so there's horizontal centering (the stuffH panel) containing a vertical centering (the stuffV panel). They are centered by surrounding them with "Glue" components, which are simply components that allow themselves to expand.
I had to put the label and field in a BoxAdapter which limits their maximum size to their preferred size. If you don't want to use BoxAdapter, you can acheive the same effect by using the following for the field and label:
JLabel label = new JLabel("Password") {
#Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
JPasswordField field = new JPasswordField() {
#Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
Hope this proves helpful to you and anyone else!
-- Scott
I would recommend the JGoodies FormLayout. Once you learn it, it's quite powerful and easy to do by hand coding.