Implementing GUIs in Java

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

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

119 εμφανίσεις

Implementing GUIs in Java


The Java Foundation Classes (JFC) are a set of
packages encompassing the following APIs:


Abstract Window Toolkit (AWT)
: native GUI
components


Swing
: lightweight GUI components


2D
: rendering two
-
dimensional shapes, text, and
images


Accessibility
: allowing compatibility with, for
example, screen readers and screen magnifiers

Abstract Window Toolkit (AWT)


Provides basic UI components:


Buttons, lists, menus, textfields, etc


Event handling mechanism


Clipboard and data transfer


Image manipulation


Font manipulation


Graphics


Platform independence is achieved through
peers
,
or native GUI components

AWT Packages

java.awt
Basic component functionality

java.awt.accessibility
Assistive technologies

java.awt.color
Colors and color spaces

java.awt.datatransfer
Clipboard and data transfer support

java.awt.dnd
Drag and drop

java.awt.event
Event classes and listeners

java.awt.font
2D API font package

java.awt.geom
2D API geometry package

java.awt.im
Input methods

java.awt.image
Fundamental image manipulation classes

java.awt.peer
Peer interfaces for component peers

java.awt.print
2D API support for printing

java.awt.swing
Swing components

Peers and Platform Independence


The first AWT (Java 1.0) was rolled out in an
incredible 6 weeks using peers


Thus an AWT menu on the Solaris platform, for
example, actually creates a Motif menu object as
its peer


UI components that have peers are called
heavyweight because


they are rendered in their own (opaque) windows and
thus are expensive to use,


they must be rectangular and cannot have transparent
backgrounds, and


they are not amenable to being subclassed

Using Peers

Java

Program

Java

AWT

Native

Window

System

Peers

A Java program creates and displays an AWT component,

which creates and displays a native component, or peer.

Lightweight Components


AWT 1.1 introduced the notion of
lightweight

components which:


are contained within a heavyweight component's
window


do not have peers


are rendered in their container's window rather than
one of their own


do not incur performance penalties and can have
transparent backgrounds


Almost all Swing components are lightweight
ones that extend either
java.awt.Component

or
java.awt.Container

Some

AWT Components

Object

Component

Container

Button

List

Scrollbar

Label

Canvas

Button

JComponent

AWT vs. Swing


Swing does not
replace

the AWT; it is built on
top

of it


All 1.0 AWT components are
heavyweight;
corresponding Swing components are lightweight


Swing component names begin with ``J'':


Component

(AWT) vs.
JComponent

(Swing)


Button

(AWT) vs.
JButton

(Swing)


Always use Swing components; however, since
Swing is built on top of AWT, you will need to
know some AWT methods

Some

Swing Components

JComponent

AbstractButton

JButton

JMenuIte
m

JToggleButton

JCheckBox

JLabel

JList

JScrollBar

JFileChooser

JComponent
s


Note that
JComponent
s are containers


JComponent
s do not extend their AWT
counterparts:


For example, the
JButton

class is not a subclass
(direct or indirect) of
Button



However, some Swing components are not
JComponent
s


For example, some Swing containers are direct
subclasses of their AWT counterparts

Some AWT

Containers

Container

JComponent

Panel

ScrollPane

Window

Dialog

Frame

Applet

Swing

Components That Are Not
JComponents (in
red
)

Container

JComponent

Panel

ScrollPane

Window

Dialog

Frame

Applet

JDialog

JWindow

JFrame

JApplet

Some More Swing

Components That
Are

JComponents

JComponent

JLayeredPane

JPanel

JScrollPane

JInternalFrame

JDesktopPane

JTable

JTree

Some AWT
Component

Methods


void setBackground(Color c)


void setForeground(Color c)


void setEnabled(boolean b)


void setVisible(boolean b)


void setFont(Font f)


void setSize(Dimension d)


void setLocation(int x, int y)

All but
setSize

and
setLocation

are overridden

by the
JComponent
class.

Example: A Simple Framed Window

import java.awt.*;

import javax.swing.*;


public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


frame.setVisible(true);


}


}

Notes on the Example


setSize

and
setLocation

require
java.awt.*
; the rest require
javax.swing.*



The
JFrame

constructor argument is used as a title


The
Dimension

constructor takes an integer width
and height, respectively


The
setLocation

method takes a pair of integer
coordinates (x,y) where (0,0) is the upper left corner of
the display


The visibility of a
JFrame

is set to
false

by default

Example Output Display


This window was managed by the K Desktop
Environment (KDE)


Clicking the Close button (X) will cause the display
to be hidden, but the program will continue since no
listeners are set up yet


Can use
ctl
-
C

to kill the Java Virtual Machine

Adding Color


Color.black


Color.blue


Color.cyan


Color.darkGray


Color.gray


Color.green


Color.lightGray


Color.magenta


Color.orange


Color.pink


Color.red


Color.white


Color.yellow

The
java.awt.Color

class has the following static

fields (data members):

Changing Background Color

import java.awt.*;

import javax.swing.*;


public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();


contentPane.setBackground(Color.red);


frame.setVisible(true);


}


}

Content Panes


Q: Why not just:
frame.setBackground(Color.red);
?


A: In order to be lightweight, Swing's top
-
level
window objects must be built on top of a
lightweight AWT
Container

object introduced
in version 1.1


This container is called a
content pane


Swing top
-
level window classes:


JWindow


JFrame


JApplet


JDialog


JInternalFrame

Adding a Label and Button

import java.awt.*;

import javax.swing.*;


public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();


JLabel label = new JLabel("HERE IS A LABEL");


contentPane.add(label, BorderLayout.NORTH);


JButton button = new JButton("BUTTON");


contentPane.add(button, BorderLayout.SOUTH);


frame.setVisible(true);


}


}

New Display

Resized

Notes on the Code


Since the frame is a top
-
level Swing window,
components must be
add
ed to its content pane


When components are added to a container, how
they are placed is dependent upon the container's
layout manager


The default layout manager for a
JFrame

is a
BorderLayout

manager (described later)


When adding to a container whose layout
manager is
BorderLayout
, the second
parameter should be a location defined in the
BorderLayout

class

Adding a List of Options

import java.awt.*;

import javax.swing.*;


public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();


JLabel label = new JLabel("HERE IS A LABEL");


contentPane.add(label, BorderLayout.NORTH);


JButton button = new JButton("BUTTON");


contentPane.add(button, BorderLayout.SOUTH);


String[] options = {"Option 1", "Option 2",


"Option 3"};


JList list = new JList(options);


contentPane.add(list, BorderLayout.CENTER);


frame.setVisible(true);


}

}

New Display

Note that "Option 3" has been selected.

Adding a Check Box and Slider

public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(400,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();


JLabel label = new JLabel("HERE IS A LABEL");


contentPane.add(label, BorderLayout.NORTH);


JButton button = new JButton("BUTTON");


contentPane.add(button, BorderLayout.SOUTH);



String[] options = {"Option 1", "Option 2", "Option 3"};


JList list = new JList(options);


contentPane.add(list, BorderLayout.CENTER);



JCheckBox cbox = new JCheckBox("Check");


contentPane.add(cbox, BorderLayout.WEST);



JSlider slider = new JSlider();


contentPane.add(slider, BorderLayout.EAST);



frame.setVisible(true);


}

}

New Display

Layout Management


A layout manager determines the location and size of
components placed into a container


Different layout managers use different algorithms for
determining size and location:


BorderLayout
: places at compass locations and center


FlowLayout:

places components in rows, left to right


GridLayout
: places in rectangular grid


BoxLayout
: places in a single row or column

Changing the Layout

public class SwingTest {



public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();



contentPane.setLayout(new FlowLayout());


JLabel label = new JLabel("HERE IS A LABEL");


JButton button = new JButton("BUTTON");


String[] options = {"Option 1", "Option 2", "Option 3"};


JList list = new JList(options);


JCheckBox cbox = new JCheckBox("Check");


JSlider slider = new JSlider();


contentPane.add(label);


contentPane.add(button);


contentPane.add(list);


contentPane.add(cbox);


contentPane.add(slider);



frame.setVisible(true);


}


}

New Display

Resized

Default Layout Managers


The default layout manager for content panes is
BorderLayout
. Recall that the following
Swing components have content panes:


JWindow


JFrame


JDialog


JApplet


JInternalFrame


The other Swing container is the
JPanel
, whose
default layout manager is
FlowLayout
.

JPanel
s


A
JPanel

object can be used for grouping
components into a container, which can then be
added to another container


The
JPanel

constructor with no arguments
creates a panel with a
FlowLayout

manager


Another
JPanel

constructor takes any layout
manager as an argument


A
JPanel

can also be used a a blank area for
drawing custom graphics

JPanel

Example


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();



JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);



JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");


JButton button3 = new JButton("BUTTON3");




JPanel panel = new JPanel();


panel.add(button1);


panel.add(button2);


panel.add(button3);



contentPane.add(label, BorderLayout.NORTH);


contentPane.add(panel, BorderLayout.CENTER);



frame.setVisible(true);

JPanel

Example Output

Note use of
SwingConstants.CENTER

argument

in
JLabel

constructor.

Changing
JPanel

Layout


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();



JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);



JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");


JButton button3 = new JButton("BUTTON3");




JPanel panel = new JPanel();


panel.setLayout


(new BoxLayout(panel, BoxLayout.Y_AXIS));


panel.add(button1);


panel.add(button2);


panel.add(button3);



contentPane.add(label, BorderLayout.NORTH);


contentPane.add(panel, BorderLayout.CENTER);


frame.setVisible(true);
New Output


The button panel is to the west because no other
component was placed there


The
BoxLayout

constructor requires both the
component being laid out and either:


BoxLayout.X_AXIS


BoxLayout.Y_AXIS

Tweaking Layouts


Some layout constructors allow
hgap

and
vgap
,
integers specifying the number of pixels
separating components horizontally and vertically


FlowLayout

allows the specification of
whether the line of components should be left
-
justified, right
-
justified, or centered

new FlowLayout(int align)

new FlowLayout(int align, int hgap, int vgap)

new BorderLayout(int hgap, int vgap)

new GridLayout(int rows, int cols)

new GridLayout(int rows, int cols,


int hgap, int vgap)

Tweaking Example


JFrame frame = new JFrame("Test Frame");


frame.setSize(new Dimension(300,200));


frame.setLocation(100,100);


Container contentPane = frame.getContentPane();


LayoutManager lm = contentPane.getLayout();


((BorderLayout)lm).setHgap(25);



JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);



JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");


JButton button3 = new JButton("BUTTON3");




JPanel panel = new JPanel();


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


panel.add(button1);


panel.add(button2);


panel.add(button3);



contentPane.add(label, BorderLayout.NORTH);


contentPane.add(panel, BorderLayout.CENTER);



frame.setVisible(true);

Tweaking Example Output


The
LayoutManager

returned by
getLayout()

is an interface type that the
BorderLayout

class implements


The
setHgap

method we want is in the
BorderLayout

class


So we must cast the
LayoutManager

to
BorderLayout

in order to use
setHgap

Sizing Hints


Layout managers often need to resize their
components to make things fit


For example, the widths and heights of components in
a
BoxLayout

are adjusted according to both
preferred

and
maximum

heights and widths


If you don't like the size of the components a
layout manager comes up with, you may have to
give sizing hints using the following methods
from the
JComponent

class:


void setMinimumSize(Dimension d)


void setPreferredSize(Dimension d)


void setMaximumSize(Dimension d)