Swing - 2: Designing and Formatting a Window

paltryboarpigΛογισμικό & κατασκευή λογ/κού

3 Νοε 2013 (πριν από 3 χρόνια και 9 μήνες)

57 εμφανίσεις

Java Note

Swing
-

2
:
Designing and Formatting a
W
indow


1

Purpose

................................
................................
................

1

2

Starting example

................................
................................
.....

1

3

Variations

................................
................................
..............

3

3.1

Using only part of the positions

................................
...............

3

3.2

Specifying a position more than once

................................
........

4

3.3

Controlling the gaps

................................
............................

5

4

Refining the layout

................................
................................
...

5

4.1

Using JPanel objects

................................
...........................

5

4.2

Working out the final design

................................
..................

7

4.2.1

Overall layout

................................
..............................

7

4.2.
2

Radio button panel

................................
........................

8

4.2.3

The button panel

................................
........................

10

4.2.4

The editor panel

................................
.........................

10

4.2.5

The result

................................
................................
.

11


1

Purpose

In this document we build a window (JFrame) containing several components
whose placement we control through the use of a layout
manager
.

W
e use the
Border Layout Manager for
the main
window and other layout managers (box,
flow, grid) for the subordinate components
.

2

Starting

example

Let’s start again with the simplest possible example: a JFrame with five
buttons

each placed in one of the geographical positions of the Border Layout:

impo
rt java.awt.*;

import javax.swing.*;


public class Win3 {



JFrame jframe;


JButton jNorth, jSouth, jEast, jWest, jCenter;


Container fc;



Win3()


{


jframe = new JFrame("Frame Title");


jframe.setDefaultCloseOperation(JFrame.EXIT_ON_C
LOSE);



Dimension screenDim = jframe.getToolkit().getScreenSize();


int height = screenDim.height;


int width = screenDim.width;



jframe.setSize((int)(width*0.6), (int)(height*0.8));


jframe.setLocation(20, 20);



Container
fc = jframe.getContentPane();


BorderLayout border = new BorderLayout();


fc.setLayout(border);



jNorth = new JButton("North");


jSouth = new JButton("South");


jEast = new JButton("East");


jWest = new JButton("West");



jCenter = new JButton("Center");




fc.add(jNorth, BorderLayout.NORTH);


fc.add(jSouth, BorderLayout.SOUTH);



fc.add(jEast, BorderLayout.EAST);



fc.add(jWest, BorderLayout.WEST);



fc.add(jCenter, BorderLayout.CENTER);


}



void

setVisible()


{


jframe.setVisible(true);


}



public static void main(String[] args) {


Win3 gui = new Win3();


gui.setVisible();


}

}


The window is built up in the constructor of the Win3 class. The result looks as
follows:


The N
orth, South, East and West buttons take up the space required to display
the label text. North and South always occupy the full width; East and West
occupy the remaining height. This is always the case regardless of the order in
which the components are ad
ded (Horton, p.812).

3

Variations

3.1

Using only part of the positions

Here is the result if we do not use one of the positions, e.g. WEST:


The CENTER component will always fill the space not used by one of the other
components.

If the CENTER component itself

is omitted, it leaves an empty area. The other
four components still take up no more than their optimal space.


3.2

Specifying a position more than once

If you specify one of the positions more than once, then only the last
component added will be visible. E
xample:

fc.add(
new JButton(“South”)
, BorderLayout.SOUTH);

fc.add(
new JButton(“Sur”)
, BorderLayout.SOUTH);

This code will compile and run, but only the button with label “Sur” will be
visible and will occupy the entire South position.

3.3

Controlling the gaps

Y
ou can control the horizontal and vertical gaps between components with the
methods
setHgap()

and
setVgap()
. It is also possible to specify the gaps
directly in the constructor of
BorderLayout
.

This is the result with horizontal gap = 20 and vertical gap
= 60:


Code:

border.setHgap(20);

border.setVgap(60);

4

Refining the layout

4.1

Using JPanel objects

Obviously the window that comes out of our starting example is not very
useful. We can only have five components and apart from their geographic
al

position we ha
ve little or no control over their size and placement.

To get
more flexibility we place components of type
JPanel()

in the main frame. In
the sample code below we place five JPanel objects, adding a label and a
colour to make them more visible:


JPanel jNo
rth, jSouth, jEast, jWest, jCenter;



jNorth = new JPanel();


jSouth = new JPanel();


jEast = new JPanel();


jWest = new JPanel();


jCenter = new JPanel();



jNorth.add(new JLabel("In the North!"));


jNorth.setBackground(Color.LIGHT_GRAY);



jSouth.add(new

JLabel("In the South!"));


jSouth.setBackground(Color.ORANGE);



jEast.add(new JLabel("In the East!"));


jEast.setBackground(Color.GREEN);



jWest.add(new JLabel("In the West!"));


jWest.setBackground(Color.CYAN);



jCenter.add(new JLabel("In the middle!"
));


jCenter.setBackground(Color.YELLOW);



fc.add(jNorth, BorderLayout.NORTH);


fc.add(jSouth, BorderLayout.SOUTH);


fc.add(jEast, BorderLayout.EAST);


fc.add(jWest, BorderLayout.WEST);


fc.add(jCenter, BorderLayout.CENTER);


Result:


4.2

Working out the fin
al design

4.2.1

Overall layout

Let’s assume that the layout we actually want is like this:



A column of radio buttons on the left



An edit window on the right



A set of buttons at the bottom

Schematically:


Projecting this onto the Border Layout, we can assign the

radio buttons to
WEST, the editor window to CENTER and the buttons to SOUTH.

4.2.2

Radio button panel

The first step is to set up the radio button panel. For this panel we use a Box
Layout, which is a little tricky to instantiate because the constructor has to
reference the container to which the box layout will apply. We do this by first
instantiating the JPanel without specifying a layout set and the calling the
JPanel’s
setLayout()

method.

The complete code is shown below. The constructor now only handles the

main
frame. The radio button panel is created in the method
buildRadioButtonPanel()
.

import java.awt.*;

import javax.swing.*;


public class Win3 {


// The main frame with its content pane


JFrame jframe;


Container fc;


// The panels


JPanel jRadio
Buttons, jEditArea, jButtons;


// The radio buttons


ButtonGroup rb1;


JRadioButton radio1, radio2, radio3;



Win3()


{


jframe = new JFrame("Frame Title");


jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



Dimension screenDi
m = jframe.getToolkit().getScreenSize();


int height = screenDim.height;


int width = screenDim.width;



jframe.setSize((int)(width*0.6), (int)(height*0.8));


jframe.setLocation(20, 20);



fc = jframe.getContentPane();


Border
Layout border = new BorderLayout();


fc.setLayout(border);


}



void buildRadioButtonPanel()


{


jRadioButtons = new JPanel();


jRadioButtons.setLayout(new BoxLayout(jRadioButtons,
BoxLayout.Y_AXIS));


rb1 = new ButtonGroup();




radio1 = new JRadioButton("First choice");


jRadioButtons.add(radio1);


rb1.add(radio1);



radio2 = new JRadioButton("Second choice");


jRadioButtons.add(radio2);


rb1.add(radio2);



radio3 = new JRadioButton("Third choic
e");


jRadioButtons.add(radio3);


rb1.add(radio3);




fc.add(jRadioButtons, BorderLayout.WEST);


}



void setVisible()


{


jframe.setVisible(true);


}



public static void main(String[] args) {


Win3 gui = new Win3();


gui
.buildRadioButtonPanel();


gui.setVisible();


}

}

4.2.3

The button panel

Next we tackle the row of buttons at the bottom (South). For the buttons we
use the simple Flow Layout, which is also the default.

To do this we add the method
buildButtonPanel()

to o
ur program:

// The button row at the bottom of the window (panel jButtons)


JButton[] buttons;



(...)



void buildButtonPanel()


{


jButtons = new JPanel();


jButtons.setLayout(new FlowLayout());


buttons = new JButton[5];


buttons
[0] = new JButton("Up");


buttons[1] = new JButton("Down");


buttons[2] = new JButton("Left");


buttons[3] = new JButton("Right");


buttons[4] = new JButton("Don't Move");


for (int i=0; i<buttons.length; i++) {


jButtons.add(butt
ons[i]);


}



fc.add(jButtons, BorderLayout.SOUTH);


}

4.2.4

The editor panel

Finally we design the panel containing the editor pane. The method is
buildEditPanel()
:

// The editor anel (jEditArea)


JLabel editHeader;


JEditorPane edit;



(...)



void buildEditPanel()


{


jEditArea = new JPanel();


jEditArea.setLayout(new GridLayout(2,1));




editHeader = new JLabel("Edit your text here", JLabel.LEFT);


jEditArea.add(editHeader);



edit = new JEditorPane("text/plain", "
Text entry");


jEditArea.add(edit);



fc.add(jEditArea, BorderLayout.CENTER);


}

4.2.5

The result

The window now looks as follows:


All the elements are there. Aesthetically there is still some work to do because
the placement and size are not ideal.

An easy solution for this is to call the pack() method of the JFrame just prior to
making the frame visible. This will resize the window so that all components
take on their preferred size.

We change the code as follows:


void setVisible()


{


jfr
ame.pack();


jframe.setVisible(true);


}

And this is what our window now looks like:


Not surprisingly the window has become very much smaller; in fact it was
massively oversized for the few components needed. The layout is still not
ideal; for in
stance, the JLabel and JEditPane in the CENTER panel both occupy
50% of the vertical space, which does not make sense. A more

elaborate design
of the window

or the use of a more complex layout manager (e.g. Grid Bag)
could remedy this problem.