Introduction to Swing Introduction and Background Swing is
Introduction to Swing
Introduction and Background • Swing is Sun’s second Java GUI kit • Built on AWT, but most programs will directly use only Swing classes • GUIs are built of components organized using containers • Swing components interact with the user using an event listener model
About JFC and Swing • JFC – Java. TM Foundation Classes • Encompass a group of features for constructing graphical user interfaces (GUI). • Implemented without any native code. • “Swing” is the codename of the project that developed the first JFC components (JFC 1. 11). • The name “Swing” is frequently used to refer to new components and related API. 1) Initially released as an extension to JDK 1. 1
About JFC and Swing (cont) • Swing features: – The Swing Components • Dialog, Tabbed pane, Buttons, File Chooser, . . . – Pluggable Look and Feel – Accessibility API • Screen readers, Braille displays, . . . – Java 2 DTM API (Java 2 Platform only) – Drag and Drop (Java 2 Platform only) • Between Java applications and native applications.
Pluggable Look and Feel Each picture shows the same program but with a different look and feel
Parts of a GUI • Widgets – objects like buttons, windows, and text fields – users interact with the widgets using the mouse and keyboard – listeners may be attached to one or more widgets • Listeners – objects which are notified when a particular event occurs – customized reaction to the event, provided by the GUI designer – standardized set of methods that the listener must implement, provided by the system • Event Objects – objects that contain information about the event • e. g. where it occurred
Swing Programs • Four basic types of Swing program: – JFrame, a top level window decorated like a native window – JWindow, an undecorated stand-alone window (splashscreen) – JApplet, an embeddable applet – JDialog, a popup dialog window • Each program type is implemented as a framework class How to write a Swing applet • Extend JApplet • Implement required framework methods: – init(), called when applet is first loaded – start(), start running – stop(), stop running – destroy(), clean up and terminate • In many cases, only init() is needed
Swing Components get. Size() set. Background() set. Font() set. Text() set. Icon() set. Current. Directory() set. File. Filter() set. Maximum() set. Minimum() set. Paint. Ticks() • Components are the “widgets” of Swing • Most concrete Swing class names start with a “J” • All Swing components subclass JComponent, which provides generic methods • Containers, e. g. JPanel, are also components
Swing Containers • Components can be grouped together into containers • Within a container, component positioning is controlled by a layout manager, e. g. Flow. Layout, Grid. Layout • Layout managers and containers manage generic AWT Components • Intermediate containers are useful for organization: they form a containment hierarchy
Event Listeners • User actions (mouse, keyboard) are represented as events • Event Listeners are objects that process events on behalf of Swing components • Listeners are registered using a component add-listener method, which takes the listener object as its argument • There are many classes of events, each of which may include several specific event types • Each event class has an associated Java interface, e. g. Key. Listener, Mouse. Listener • The listener interface specifies methods that the Swing infrastructure will call, one for each event type in the class, e. g. key. Pressed(), key. Released() • Event listener objects implement these interface methods
Swing Components • Swing provides many standard GUI components such as buttons, lists, menus, and text areas, which you combine to create your program's GUI. • Swing provides containers such as windows and tool bars. – top level: frames, dialogs – intermediate level: panel, scroll pane, tabbed pane, . . . – other Swing components: buttons, labels, . . .
Containers • Descendents of the java. awt. Container class • Components that can contain other components. • Use a layout manager to position and size the components contained in them. • Components are added to a container using one of the various forms of its add method – Depending on which layout manager is used by the container panel. add(component);
Top Level Containers • Every program that presents a Swing GUI contains at least one top-level container. • A Top level container provides the support that Swing components need to perform their painting and eventhandling. • Swing provides three top-level containers: – JFrame (Main window) – JDialog (Secondary window) – JApplet (An applet display area within a browser window)
Top Level Containers (cont) • To appear on screen, every GUI component must be part of a containment hierarchy, with a top-level container as its root. • Each top-level container has a content pane that contains visible components in that top-level container’s GUI. Don’t add a component directly to a top-level container.
JFrame • A frame implemented as an instance of the JFrame class, is a window that has decorations such as a border, a title and buttons for closing and iconifying the window. – The decorations on a frame are platform dependent. • Applications with a GUI typically use at least one frame.
Example import javax. swing. *; public class Hello. World. Swing { public static void main(String[] args) { JFrame frame = new JFrame("Hello. World. Swing"); final JLabel label = new JLabel("Hello World"); frame. get. Content. Pane(). add(label); frame. set. Default. Close. Operation(JFrame. EXIT_ON_CLOSE); frame. pack(); frame. set. Visible(true); } pack() causes a window to be } sized to fit the preferred size and layouts of its sub-components
Example import javax. swing. *; In this example a custom frame is created public class Hello. World. Frame extends JFrame { public Hello. World. Frame() { super(“Hello. World. Swing”); final JLabel label = new JLabel("Hello World"); get. Content. Pane(). add(label); set. Default. Close. Operation(JFrame. EXIT_ON_CLOSE); pack(); set. Visible(true); } public static void main(String[] args) { Hello. World. Frame frame = new Hello. World. Frame(); } }
JDialog • Every dialog is dependent on a frame – Destroying a frame destroys all its dependent dialogs. – When the frame is iconified, its dependent dialogs disappear from the screen. – When the frame is deiconified, its dependent dialogs return to the screen. • A dialog can be modal. When a modal dialog is visible it blocks user input to all other windows in the program.
JDialog (cont) • To create custom dialogs, use the JDialog class directly (as in the previous examples). • Swing provides several standard dialogs – JProgress. Bar, JFile. Chooser, JColor. Chooser, . . . • The JOption. Pane class can be used to create simple modal dialogs – icons, title, text and buttons can be customized.
Example Object[] options = {"Yes!", "No, I'll pass", "Well, if I must"}; int n = JOption. Pane. show. Option. Dialog( frame, "Duke is a cartoon mascot. n" + "Do you still want to cast your vote? ", "A Follow-up Question", JOption. Pane. YES_NO_CANCEL_OPTION, JOption. Pane. QUESTION_MESSAGE, null, options[2]);
JComponent • JComponent is the base class for all Swing components except top-level containers. – JLabel, JButton, JList, JPanel, JTable, . . . • To use a component that inherits from JComponent, it must be placed in a containment hierarchy who’s base is a toplevel container.
JComponent (cont) • The JComponent class provides the following (partial list): – – – Pluggable Look & Feel Keystroke handling Tooltip support Accessibility An infrastructure for painting Support for borders. • All descendents of JComponent are also Containers – A JButton can contain text, icons etc.
Borders • Every JComponent can have one or more borders. • The class Border. Factory may be used to create standard borders pane. set. Border(Border. Factory. create. Line. Border(Color. black)); • Using a compound border, you can combine any two borders, which can themselves be compound borders Border. Factory. create. Compound. Border(border 1, border 2);
Simple Borders
Titled Borders
Compound Border
Intermediate Level Containers • Also known as panels or panes • Simplify the positioning of other components. – JPanel • Play a visible and interactive role in a program’s GUI – JScroll. Pane – JTabbed. Pane • A panel’s default layout manager is Flow. Layout. – Other layout managers can easily be set panel. set. Layout(new Border. Layout());
Intermediate Level Containers (cont) • By default, panels don’t paint anything except for their background. • By default, panels are opaque. – An opaque panel can be set as a top-level container’s content pane. – transparent (non-opaque) panels draw no background.
AWT to Swing • AWT: Abstract Windowing Toolkit • import java. awt. * • Swing: new with Java 2 • • • import javax. swing. * Extends AWT Standard dialog boxes, tooltips, … Look-and-feel, skins Event listeners • API: • http: //java. sun. com/j 2 se/1. 3/docs/api/index. html
GUI Component API • Java: GUI component = class • Properties • • Methods • • Events • JButton
Using a GUI Component 1. Create it • Instantiate object: b = new JButton(“press me”); 2. Configure it • • Properties: b. text = “press me”; java] Methods: b. set. Text(“press me”); 3. Add it • panel. add(b); 4. Listen to it • Events: Listeners [avoided in JButton
Anatomy of an Application GUI Internal structure JFrame JPanel containers JPanel JButton JLabel
Using a GUI Component 2 1. 2. 3. 4. 5. Create it Configure it Add children (if container) Add to parent (if not JFrame) Listen to it order important
Build from bottom up Listener • Create: • • Frame Panel Components Listeners • Add: (bottom up) • listeners into components • components into panel • panel into frame JLabel JButton JPanel JFrame
Code JFrame f = new JFrame(“title”); JPanel p = new JPanel( ); JButton b = new JButton(“press me”); p. add(b); // add button to panel f. set. Content. Pane(p); // add panel to frame f. show(); press me
Application Code import javax. swing. *; class hello { public static void main(String[] args){ JFrame f = new JFrame(“title”); JPanel p = new JPanel(); JButton b = new JButton(“press me”); p. add(b); f. set. Content. Pane(p); // add button to panel // add panel to frame f. show(); } } press me
Layout Management • The process of determining the size and position of components. • Layout management can be done using absolute positioning – Size and position of every component within the container must be specified. – Does not adjust well when the top-level container is resized. – Does not adjust well to differences between users and systems, such as font size.
Layout Manager Heuristics null Flow. Layout none, programmer sets x, y, w, h Left to right, Top to bottom Border. Layout n w c s e Card. Layout One at a time Grid. Layout Grid. Bag. Layout JButton
Layout Management (cont) • Layout management is often performed using layout mangers – Components can provide size and position hints to layout managers, but layout managers have the final say on the size and position of those components.
Layout Management (cont) • Layout hints – Minimum, preferred and maximum size – X axis alignment, Y axis alignment • Customizing layout hints – Invoking setter methods: set. Minimum. Size, set. Alignment. X, . . . – Subclassing and overriding the getter methods: get. Minimum. Size, get. Alignment. X, . . .
Layout Management (cont) • The Java platform supplies five commonly used layout managers: – Border. Layout – Box. Layout – Flow. Layout – Grid. Bag. Layout
Layout Management (cont) • When using the add method to put a component in a container, the container’s layout manager must be taken into account. – Relative position (Border. Layout) panel. add(component, Border. Layout. CENTER); – Order of addition (Box. Layout, Grid. Layout, . . . ) panel. add(component);
Border. Layout • Has five areas available to hold components – north, south, east, west and center • All extra space is placed in the center area – Only the center area is affected when the container is resized. • Default layout manager of content panes.
Box. Layout • Places components in a single row (left to right) or column (top to bottom). • Respects component’s maximum size and alignment hints.
Flow. Layout • Places components from left to right, starting new rows if necessary. • Default Layout. Manager of JPanel
Grid. Layout • Places components in a requested number of rows and columns. • Components are placed left-to-right and top-tobottom. • Forces all components to be the same size – as wide as the widest component's preferred width – as high as the highest component’s preferred height
Layout Management (cont) • The following factors influence the amount of space between visible components in a container: – Layout manager • automatically, user specified, none – Invisible components • often used with Box. Layout – Empty borders • works best with components that have no default border such as panels and labels.
Combinations JButton JText. Area
Combinations JButton JFrame n JPanel: Flow. Layout JPanel: Border. Layout c JText. Area
Code: null layout JFrame f = new JFrame(“title”); JPanel p = new JPanel( ); JButton b = new JButton(“press me”); b. set. Bounds(new Rectangle(10, 100, 50)); p. set. Layout(null); // x, y layout p. add(b); f. set. Content. Pane(p); press me
Code: Flow. Layout JFrame f = JPanel p = Flow. Layout JButton b 1 JButton b 2 new JFrame(“title”); new JPanel( ); L = new Flow. Layout( ); = new JButton(“press me”); = new JButton(“then me”); p. set. Layout(L); p. add(b 1); p. add(b 2); f. set. Content. Pane(p); Set layout mgr before adding components press me then me
Applets JApplet • JApplet is like a JFrame • Already has a panel • Access panel with JApplet. get. Content. Pane( ) content. Pane import javax. swing. *; JButton public class hello extends JApplet { public void init(){ JButton b = new JButton(“press me”); get. Content. Pane(). add(b); }
Applet Methods • Called by browser: • init( ) - initialization • start( ) - resume processing (e. g. animations) • stop( ) - pause • destroy( ) - cleanup • paint( ) - redraw stuff (‘expose’ event)
Application + Applet import javax. swing. *; import java. awt. *; class hello. App { public static void main(String[] args){ // create Frame and put my main. Panel in it JFrame f = new JFrame(“title”); main. Panel p = new main. Panel(); f. set. Content. Pane(p); f. show(); } } class hello. Applet extends JApplet { public void init(){ // put my main. Panel in the Applet main. Panel p = new main. Panel(); get. Content. Pane(). add(p); } } // my main GUI is in here: class main. Panel extends JPanel { main. Panel(){ set. Layout(new Flow. Layout()); JButton b = new JButton(“press me”); add(b); } } Command line Browser JFrame JApplet or content. Pane JPanel JButton
Applet Security • • No read/write on client machine Can’t execute programs on client machine Communicate only with server “Java applet window” Warning
Typical command line program • Non-interactive • Linear execution program: main() { code; code; code; }
Interactive command line program: • User input commands • Non-linear execution • Unpredictable order • Much idle time main() { decl data storage; initialization code; loop { } } get command; switch(command) { command 1: code; command 2: code; … }
Typical GUI program: • User input commands • Non-linear execution • Unpredictable order • Much idle time • Event callback procs main() { decl data storage; initialization code; create GUI; register callbacks; } main event loop; Callback 1() { code; } Callback 2() { code; } … //button 1 press
GUI Events App 1 mouse click OK App 2 OK Cancel App 2 code: App 1 event loop Window System input device event loop which app? App 2 event loop which callback? OKbtn_click() { do stuff; } OKbtn_mouseover() { do more stuff; } Cancel. Btn_click() { do different stuff; }
Example: draw program My. Draw. Class{ main() { Data. Struct drawn_shapes; drawn_shapes. clear(); } create Frame, Panel, buttons, … register listeners; Draw. Panel_listener_click() { drawn_shapes. add(new shape); } Undo. Button_listener_click() { drawn_shapes. delete. Last(); } …
Events Handling • Every time a user types a character or pushes a mouse button, an event occurs. • Any object can be notified of an event by registering as an event listener on the appropriate event source. • Multiple listeners can register to be notified of events of a particular type from a particular source.
Java Listeners 1. Register with a component to receive events • • Give component a ref to your Listener object JButton 1. add. Mouse. Listener(new my. Mouse. Listener) 2. Receive events from component • • Component will callback procs on your Listener object my. Mouse. Listener. mouse. Clicked(event) click JButton 1 1. add. Mouse. Listener( ) 2. mouse. Clicked( ) my. Mouse. Listener
Types of Event Listeners Act that results in event Listener type User clicks a button, presses Return while typing in a text field, or chooses a menu item Action. Listener User closes a frame (main window) Window. Listener User presses a mouse button while the cursor is over a component Mouse. Listener User moves the mouse over a component Mouse. Motion. Listener Component becomes visible Component. Listener Component gets the keyboard focus Focus. Listener Table or list selection changes List. Selection. Listener
Implementing an Event Handler • • • Implement a listener interface or extend a class that implements a listener interface. Register an instance of the event handler class as a listener upon one or more components. Implement the methods in the listener interface to handle the event.
Example button. add. Action. Listener(new Action. Listener() { public void action. Performed(Action. Event e) { num. Clicks++; label. set. Text(label. Prefix + num. Clicks); }});
Listener API • Listeners must inherit from Java Listener base classes • Action. Listener, Key. Listener, Mouse. Motion. Listener, Window. Listener, … • Abstract base classes: xxxx. Listener • Stubbed base classes: xxxx. Adapter • Mouse. Listener: • mouse. Clicked(), mouse. Entered(), mouse. Exited(), mouse. Pressed(), mouse. Released()
Code button 1 = new JButton(“press me”); my. Listener = new my. Listen. Class; button 1. add. Mouse. Listener(my. Listener); // extending a class (“subclassing”): class my. Listen. Class extends Mouse. Adapter { public void mouse. Clicked(Mouse. Event e){ // button clicked, do stuff here } } // OR “implementing an interface”: class my. Listen. Class implements Mouse. Listener { public void mouse. Clicked(Mouse. Event e){ // button clicked, do stuff here An abstract } base class … (methods, } no code)
Event objects • mouse. Clicked(Mouse. Event e) • Mouse. Event: • get. X( ), get. Y( ), get. Click. Count( ), get. Source( ), … • For each listener type: • • Component. addxxxx. Listener( ) xxxx. Listener abstract base class xxxx. Adapter stubbed base class xxxx. Event
Inheritance with Swing class my. Panel extends JPanel { public my. Panel(){ //constructor // create buttons, … } public void paint. Component(Graphics g){ super. paint(g); //call overriden method // paint stuff here } } • my. Panel creates JPanel via inheritance • Override JPanel methods to add functionality
Simplifying: Implements abstract base class my. Panel extends JPanel implements Mouse. Listener { public my. Panel(){ //constructor button 1 = new JButton(“press me”); button 1. add. Mouse. Listener(this); add(button 1); } public void mouse. Clicked(Mouse. Event e){ // button clicked, do stuff here } … }
Simplifying: Anonymous classes class my. Panel extends JPanel { public my. Panel(){ button 1 = new JButton(“press me”); button 1. add. Mouse. Listener( new Mouse. Adapter() { public void mouse. Clicked(Mouse. Event e){ // button clicked, do stuff here } } Defining and ); instantiating a add(button 1); } class on the fly }
A Simple GUI
Creating a GUI • • import Java libraries - swing, awt construct a frame object declare widgets - instance variables choose, construct and set the layout add widgets Order doesn’t attach listeners matter here implement the listeners
Find Patterns in the Code for a Simple GUI import import javax. swing. JFrame; javax. swing. JText. Area; Swing - Newer GUI library javax. swing. JText. Field; May import many classes at once javax. swing. JButton; import javax. swing. *; java. awt. Container; java. awt. event. Action. Listener; java. awt. event. Action. Event; java. awt. Flow. Layout; AWT - Abstract Window Toolkit Older GUI library
Declare Widgets (Instance Variables) /** A simple program demonstrating input from Text. Fields and Buttons, and output to a Text. Area. */ Basic window public class First. Example. Demo extends JFrame widget { // Declare the GUI widgets we'll use. private JText. Area output. TA = new JText. Area(10, 30); private JText. Field input. TF = new JText. Field(30); private JButton clear. Button = new JButton("Clear");
Format the Main Window and Add the Widgets // Set up the GUI. public First. Example. Demo() { this. set. Size(400, 300); // Add all the GUI widgets to the frame Container contents = this. get. Content. Pane(); contents. set. Layout(new Flow. Layout()); contents. add(output. TA); contents. add(input. TF); contents. add(clear. Button); Must set the layout style of the window, and add the widgets to the associated Content Pane
Attach Listeners Clear. Listener cl = new Clear. Listener(); // Attach listeners clear. Button. add. Action. Listener(cl); input. TF. add. Action. Listener(new Add. Listener()); }
Define Listeners (Implement Interfaces) // Define a listener for the add textfield. private class Add. Listener implements Action. Listener { public void action. Performed(Action. Event e) { String text = input. TF. get. Text(); output. TA. append(text + "n"); Action. Listener input. TF. set. Text(""); invoked on mouse } click or enter key } // Define a listener for the clear button. private class Clear. Listener implements Action. Listener { public void action. Performed(Action. Event e) { output. TA. set. Text(""); } } }
Implementing a Listener • implement an interface – the system needs to know that when an event happens, the listener attached to one of your widgets has a predictable set of methods • using inner classes – the listener the GUI designer writes needs to be defined within the GUI class (helper class) – the listener typically needs access to the private instance variables (widgets) of the GUI class to update the display
Complex GUI A Calculator
Patterns from the Calculator GUI • Layout choices – Flow. Layout, Grid. Layout, Border. Layout, … • JPanel – allows a nested layout design • Action. Event object (Action. Listener parameter) methods – public Object get. Source() • returns the widget which invoked the listener – public String get. Action. Command() • returns text associated with the widget
Layout Choices & Nesting Panels // Add all the GUI widgets to the frame Container contents = this. get. Content. Pane(); contents. set. Layout(new Border. Layout()); contents. add(display. Screen, Border. Layout. NORTH); //A Border. Layout has 5 regions - north, south, east, west, center contents. add(add. Operations(), Border. Layout. EAST); contents. add(add. Numbers(), Border. Layout. CENTER); JPanel op. Buttons = new JPanel(); op. Buttons. set. Layout(new Grid. Layout(3, 2)); //Specify the number of rows, columns in the grid
Using Action. Event Objects in a Listener private class Digit. Listener implements Action. Listener { public void action. Performed (Action. Event e) { display. Screen. append(e. get. Action. Command()); } } Every digit button needs basically the same listener. All the listener needs to know is the number showing on the button.
… but it doesn’t do anything • To make the calculator work properly, we need more code • Separate the application logic from the GUI – create a new class, for example • Calc. App - program logic class • Calc. GUI - program GUI class • listeners need to call methods from Calc. App – need to have an object from Calc. App as an instance variable in the Calc. GUI class – may want to communicate to the GUI from the Calc. App class – send “this” as a parameter to the Calc. App constructor when initializing the instance variable in the Calc. GUI class
Create the Program Logic • Write code that will logically accept a number generated by clicking the digit buttons • Write the code that will logically calculate the sum of two numbers • Update the GUI listeners by calling methods from the application class
Conclusions • Swing is still buggy (e. g. painting glitches) • Lack of built-in support of Java 2 in today’s browsers makes using Swing more difficult BUT • Swing is powerful and easy to use • Java’s OO model is perfectly suited for GUI programming
References • http: //java. sun. com/j 2 se/1. 3/docs/api/ index. html • http: //java. sun. com/docs/books/tutorial/uiswing/compone nts/components. html
- Slides: 87