telecooperation/rbg technische universität darmstadt copyrighted material; for tud student use only...
TRANSCRIPT
Telecooperation/RBG
Technische Universität Darmstadt
Copyrighted material; for TUD student use only
Introduction to Computer Science ITopic 21: Graphical User Interfaces
Nested Classes
Prof. Dr. Max MühlhäuserDr. Guido Rößling
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
AWT and Swing
• AWT = Abstract Window Toolkit– Package java.awt– Uses controls of the underlying operating system
• Native Code (= written for the machine, not the VM)• fast• Look depends on system: fonts, widgets…• Limited portability
• Swing– Package javax.swing (part of Java Foundation
Classes)– property: Swing classes start with a „J“: JButton, ...– Pure Java, distinct look– Builds on AWT– Uses a minimum of system-specific components
2
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Components
• Some common components and their main tasks are:
• Display text and symbols– JLabel
• Dispatching actions– JButton
– JMenu
3
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Components
• Text input– JTextField
• Choose from a given set of options– JCheckBox
• Choose from a variable set– JList
4
JRadioButton
JComboBox
Button or TextField +expandable Listbox
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Human Factors
• When designing interactive programs, there are many aspects beside functional completeness and correctness
• One of these is the kind of interaction and the ease of learning and using the program
• Some guidelines for good GUIs are:– Avoid modes. General operations should be
always accessible.– Have easy and consistent interaction sequences. – Do not offer too many options. – Show the available options clearly.– Give adequate feedback.– Enable the possibility to undo errors easily.
5
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Anatomy of a GUI-Application
• Components• Containers• Events• Listener• Layout
– Sets the alignment of components
• Look & Feel– Sets look and feel
of the components• separate: application
logic
6
GUI-Framework
Application logic
state:value=3
Events Method calls on components
components
Container
Listener
Network of cooperating objects with clear responsibility:
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Threads• Sequential programs
– Have start, defined execution sequence and finish.– At any point in time, exactly one statement is active– A thread is a single sequential control flow in a program.
• Concurrent programs– Program can have multiple threads– Multiple parts of the program can execute in parallel.
7
threadProgram
Program
threads
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Threads
• Threads…– use the resources of their parent process– do not have memory of their own– do have a set of registers (incl. program counter and state)
and their own stack– are also called lightweight processes
• GUI applications have the main thread and one so called event-dispatching thread.– This thread calls methods of the application, on certain
events (callback)– The event handler in the application are executed
sequentially– The drawing of components happens in this thread, too
8
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
AWT-EventQueue AWT-EventQueue
main
Programming model
9
Application GUI-Framework (Swing)
Add component
Event:Draw component
Event:User input
main
AWT-EventQueue
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Window
10
import javax.swing.JFrame;
public class GUITest extends JFrame { // The height of the window in pixels public static final int WIDTH = 400; // The width of the window in pixels public static final int HEIGHT = 300; // Constructs a new window with a given title public GUITest(String title) { super(title); } // Start test application. Creates a new window and displays it public static void main(String args[]) { // Construct a new window. It is initially invisible GUITest theWindow = new GUITest("My first GUI Application"); // Set width and height of the window theWindow.setSize(WIDTH, HEIGHT); // Open the window theWindow.setVisible(true);
System.out.println("Exiting main..."); }}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Window
• We observe...– main() exits, but the program continues
Multiple threads.The event-dispatching thread continues.
– Clicking on the close button does not end the programEvent handling is missing; more on this
later.
11
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Container
• Container and components– JFrame: „top level container“
• Uses windows of the OS– JPanel: „intermediate container“
• Used for grouping and placement of components• Nesting possible
– JLabel, JButton, ...: „atomic components“• Present information to the user• Allow interaction and input (controls)
• Container Hierarchy– Even the simplest application consists of a hierarchy
of containers and components– (The diagram simplifies. The container linking JFrame
andJPanel are out of scope)
12
JFrame
JPanel
JLabel
JFrame
JPanel
JLabel
...
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Components
• Adding components– JFrame creates a JPanel „contentPane“.– Here, the application can place new
components– Components are added while the
window is invisible. That is, between creation of the window object (using new) and the drawing with setVisible(true).
• JLabels– Draw text and/or symbols– Are passive components, not allowing
interaction
13
JFrame
JPanel
JLabel
...
contentPane
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Labels
14
import java.awt.Container;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { public GUITest(String title) { super(title);
// Retrieve the area where one can add elements Container pane = getContentPane();
// Create a new label that displays help information JLabel label = new JLabel( "Press the [X] in the top right corner to exit");
// Add the label to the content of the window pane.add(label); } // ...}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Buttons
15
import java.awt.Container;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { public GUITest(String title) { super(title);
Container pane = getContentPane();
JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit");
pane.add(label); // Create a new push button that may be used in addition to the [X] JButton button = new JButton("Exit");
// Add the button to the content of the window pane.add(button); } // ...}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Layout
• We observe...– The text is no longer visible, the button covers it.
• Layout management– …is the process to define size and position of
components– The layout is chosen by setting the layout objects for
the container:
Container pane = getContentPane();pane.setLayout(new GridLayout(ROWS, COLS));
– The Layout class implements the interface LayoutManager.
16
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Predefined Layouts
• GridLayout– Sets the components in a rectangular
grid– The sequence of adding the
components set their position• BorderLayout
– Positions in 5 regions, each with at most one component
– The regions N, E, S and W are as small as possible. The rest is reserved for CENTER.
– Selection of region by additional parameter for Container.add:add(new Button("SOUTH"), BorderLayout.SOUTH);
• More Layouts: BoxLayout, FlowLayout, GridBagLayout, ...
• Please see the Java API documentation and the tutorials
17
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
GridLayout
18
import java.awt.Container;import java.awt.GridLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { public GUITest(String title) { super(title); Container pane = getContentPane();
// Define a LayoutManager that places new elements properly // onto the pane. Here we use a grid with 3 rows and 1 column. pane.setLayout(new GridLayout(3, 1));
JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); JButton button = new JButton("Exit"); pane.add(button); } ...}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Events
• Each time the user presses a key or moves the mouse, an event is generated.
• Controls can take mouse and keyboard events and generate new events– If the mouse button is released over a button, an ActionEvent is
generated.• Events are described by event objects• The base classes for GUI event objects are descendants of
java.awt.AWTEvent (for GUI, more general: java.util.EventObject)
• The class type tells more about the event– ActionEvent: user clicked a button, pressed Return in a textbox,
chose a menu entry, ...– WindowEvent: user closed or iconified/deiconified the window,
…– ...
• The attributes offer additional information for the event– For example, which button was pressed.
19
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Listener
• Multiple listeners can register for an event source and get informed about events of a certain type from then on
• Programming a Listener:– The class of the event listener must implement the
interface of the corresponding event. • E.g. for ActionEvents, the ActionListener interface
– The class must implement all methods of the interface.– The client registers the listener object with the event
source via addActionListener(Listener)
20
eventsource
event objectevent listener
event listener
event listener
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); }
private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Change Label Text was clicked"); } } // ... }
Events
21
This is a nested class. More later
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
View-Updates
• The look of the components and the information they present can be changed by calling appropriate methods
• JLabel API (extract):
22
void setText(String)String getText()
Set or get the displayed text
void setHorizontalAlignment(int)int getHorizontalAlignment()
Text alignment: LEFT, CENTER or RIGHT
void setVerticalAlignment(int)int getVerticalAlignment()
Text alignment: TOP, CENTER or BOTTOM
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame {
private JLabel infoLabel; public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1));
infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); } } // ...}
Events
23
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Window Events
• With a click on the close button, the program should be terminated Register a WindowListener
• Interface WindowListener:
24
void windowActivated(WindowEvent e)
Window has been activated
void windowClosed(WindowEvent e)
Window was closed after a dispose()
void windowClosing(WindowEvent e)
User clicked “close”
void windowDeactivated(WindowEvent e)
Window has been deactivated
void windowDeiconified(WindowEvent e)
Window has ben de-iconified
void windowIconified(WindowEvent e)
Window has been iconified
void windowOpened(WindowEvent e)
Window has been opened
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Adapter
• With interfaces, every method must always be implemented. As this is not always useful, we can use an Adapter.
• WindowAdapter– implements WindowListener– Defines all methods with an empty body, doing
nothing. – is an abstract class.
• The application-specific event handler is derived from WindowAdapter and overrides only “interesting” methods.
25
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;
public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title);
// Now, also define that the [X] terminates the program correctly addWindowListener(new MyWindowListener());
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel);
// Create a new push button that may be used in addition to the [X]
JButton button = new JButton("Exit");
// Define that the program should exit if you click the button button.addActionListener(new ExitButtonListener()); pane.add(button);
WindowEvents
26
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
WindowEvents
27
// Create another button that changes the text of the Label button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); } }
// Exit the program when the window close button is clicked class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // Exit the program when the “Exit”-button is clicked class ExitButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.exit(0); } } public static void main(String args[]) { GUITest theWindow = new GUITest("My first GUI Application"); theWindow.setSize(WIDTH, HEIGHT); theWindow.setVisible(true); } public static final int WIDTH = 400; public static final int HEIGHT = 300;}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Nested classes: Motivation
• The GUI components expect as “Listener” an instance of XYZListener (e.g. ActionListener)
• How can we create a fitting object?• Option 1: Frame class directly implements
the Listener interface• Option 2: External class implements the
Listener interface
28
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Option 1: Frame class directlyimplements the Listener Interface
29
import java.awt.Container;import java.awt.GridLayout;
import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame implements ActionListener { public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(this); pane.add(button); }
public void actionPerformed(ActionEvent event) { System.out.println("Change Label Text was clicked"); } // ... }
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Option 1: Frame-class directlyimplements the Listener Interface
• This approach works, but not too well– What if we have more than one button?
• We need to determine the source object in the (single) actionPerformed method
– Besides buttons, there are labels, menus, …• Frame class implements many interfaces that do
not match its core functionality• Example for “God Class Antipattern”
– action-methods have to be public, although they are implementation details that do not have to be in the interface of a frame
• This is often a bad solution
30
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Option 2:External class implements the Listener
Interface
31
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); }}
class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); }}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Option 2:External class implements the Listener
Interface• Does not share the conceptual disadvantages of option 1
– Easy to define different actions for different buttons– The interface of frame stays clean
• Disadvantages– Clarity suffers
• Many classes– Reduced cohesion
• external Listener class might be used at exactly one point
– Time-consuming and tiresome to create a class for every Listener
– Access to properties of frame class bothersome• Everything must be put as parameter in the constructor• e.g., code on last slide would not work
– access to infoLabel in actionPerformed32
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Option 2:External class implements the Listener
Interface
33
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener(infoLabel)); pane.add(button); }}class ChangeButtonListener implements ActionListener { private JLabel infoLabel; public ChangeButtonListener(JLabel l) { infoLabel = l; } public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); }}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Nested classes
• Both options are unconvincing• Main motivation for Sun to introduce nested
classes (Java 1.1)
• Nested classes are classes within classes– Declared like normal classes, just inside other classes– Access rules change– Inner classes have access to instance variables and
methods of outer classes
34
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
35
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title);
Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); } } // ...}
Nested classes
- Nested Class can be “private”- only visible in surrounding class
- has access to private members of surrounding class
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Nested classes
• Each nested class needs on creation a reference to its enclosing class– Implicitly on creation from the surrounding class– Explicit via myOuterInstance.new MyInnerClass()– The type of a nested class N inside C is “C.N”
• Within class C, the type N suffices (implicit scoping)– Rule of thumb: if you need the name of a nested class
outside the enclosing class, something is wrong.• Nested classes can also be declared “static”
– Semantics like static methods: no access to instance variables of enclosing class, just static methods/variables
36
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Anonymous Nested classes
37
import java.awt.Container;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;
public class GUITest extends JFrame {public GUITest(String title) { super(title);
final JLabel infoLabel; // now a local variable Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1));
infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit"));
// Create another button that changes the text of the Label JButton button = new JButton("Change Label Text");
// Now, define what should happen if the button is pressed button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); } }); pane.add(button); }}
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Anonymous Nested Classes
• Anonymous Nested classes can be declared inside a method– They have no name– They are only used via super types– Syntax: new SuperClassName(args) { … } or
new InterfaceName() { … }– This implicitly creates a subclass of the given
super class or a new class that implements the interface
– An instance of the anonymous class is created– This can be used via the super class / interface
name– Local variables of the method can be used in
the implementation, if they are declared as final
38
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Anonymous Nested Classes• Advantages over “normal” nested classes
– If used in only one place, the class does not “waste” a name
– Definition “on the fly” – where it is needed– Simple access to local variables / parameters
• Anonymous classes are a lot like “lambda” from Scheme– Remember: “lambda” means “make-procedure”, can
create procedures on-the-fly
39
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Compiling nested classes
• Compiling nested classes results in a class file for each nested class called “OuterClass$InnerClass.class”
• Anonymous nested classes reside in files called “OuterClass$n.class”, with n of type int
• Inside the JVM, there are no inner classes• The compiler transforms the code:
– Each inner class results in a normal class that receives all needed parameters as parameters in the constructor
40
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
GUI and Software Design
• GUIs can be time consuming and complex• As can the base application• How do you structure an application with a complex GUI?• Rule Nr.1:
41
Separate application logic from presentation logic
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
GUI Antipatterns
• You are doing something wrong in your GUI class, if…– you access a database– have more than 50KB of code in the class– implement business processes– save user data– …
• Better: layered architecture– E.g. “Model-View-Controller Architecture”
• Separates application logic and data from user interaction
• Application logic and data do not depend on the GUI• Easy to support multiple views• Exchange of views easy
42
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Model-View-Controller
43
View
Model
controller updatesController
chan
ge
notifi
catio
nac
cessupdate
handleuserinput
Displayoutput
Applicationdata & behaviour
A B C
45 35 15
event notification
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
MVC – Model
• The Model keeps the data• Has methods to access and change data• Notifies Listener/Observer on change of
data• Can implement parts of the business
processes
44
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
MVC – Controller
• Processes user input– Validation, interpretation of all kind…
• Often controls user interaction with the GUI• Communicates with the model• May implement presentation-related parts of the
business logic– e.g., interaction flow– hard to strictly separate from the model
• May or may not be specific to a fixed GUI– i.e., controller may or may not have an instance variable
pointing to GUI• possibly decoupled by interface
– Better reuse in the latter case• layer structure
45
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
MVC – View
• View is a visual representation of the model• There can be many views on the same data
– Multiple instances of the same view– Completely different views– The finances of a company can be represented as table
and graph at the same time• If a view registers itself as listener with the model, the
view can update, if there are changes in the model.
46
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Internationalization (I18N)
• Internationalization: providing content in multiple languages
• Problematic for GUI elements – what has to change?
• Example - a menu item:– Item label– [optional] icon– Hotkey (here: ALT+G)– Tooltip (“Generate…”)
• The German version…:
47
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Internationalization (I18N)
• Java offers basic support for Internationalization• However, GUI Internationalization has to be done
by the programmer• Alternative: use the translator package
– See the examples on the next slides• Basic approach:
– All language-specific elements are placed in a separate file
• One file per supported language– File entries are a key=value pair
• key: a String that describes the element• value: the value to be output for this key
– Instead of “real” texts, only the key is accessed in source code
48
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Resource Files
• All resources are placed in a locale-specific file• These files all start with the same base name
– For example, “msg”• The file extension has the form
country_language– Thus, the German resources will be in “msg.de_DE”– The US-English resources go to “msg.en_US”– …
• Example file content:
49
hi=Hello!query=How are you today?
hi=Hallo!query=Wie geht es Dir?
msg.en_US msg.de_DE
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
translator Package: Translator
• Goal: translation of content for a target language• Uses java.util.Locale to determine the output type
– Predefined Locales: Locale.GERMANY, Locale.US, …– Target output is determined by up to three attributes:
• Language: “de”, “en”, “es”, …• Country: “de”, “us”, “uk”, …• Variant: specific code for browser etc., e.g.”WIN”
• Creating a new instance of Translator– Pass in the base file name and the Locale:Translator myTrans = new Translator(“msg”, Locale.US);
50
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
translator Package: Translator
• Translating a message:String myTrans.translateMessage(key)
• For example:– myTrans.translateMessage("hi") Hello!
• Occasionally, you may need parameters– How do you greet a person? “Hello, John Doe!”
51
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Translating Parameterized Messages
• The package can handle parameters placed in {}:– Assume we place this definition in our file:
personalized=Hello, {0}!– We can pass in a parameter to translate…:myTrans.translateMessage("personalized", "John Doe");
Hello, John Doe!
• Parameters use numbers starting with 0… placed in {}
• If more than one parameter is needed, you can …– place them in an array: translateMessage(key,
Object[])– pass in a series of Strings: translateMessage(key,
String…)
52
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
An Internationalized GUI Application
• We will now build a small GUI application with:– A JFrame as the main window– Containing a JMenuBar
• With a single “File” menu – This will have an “Exit” item
– Two bordered JPanels:• One with a JLabel and a JButton• The other with only an “Exit” Jbutton with an icon
• Each click on the “Info” button increments a counter
• If you leave the application with the Exit button, a message containing the number of clicks is shown
• Don’t worry, this is easier than it seems…
53
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
I18N GUI Demo – Code I
import translator.TranslatableGUIElement; // for GUI elementsimport translator.Translator; // for I18N of texts etc.// Swing & Event imports skipped – use Eclipse auto-completion!
public class I18NDemo { public int nrTimes = 0; // how often was the button clicked?
/** * create the I18NDemo instance * @param targetLocale the Locale used for the output */ public I18NDemo(Locale targetLocale) { // create the translator (resource file; target locale) Translator translator = new Translator("guiI18N",
targetLocale); buildGUI(translator); // create the GUI }
54
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
I18N GUI Demo – Code II
/** * builds the GUI elements with full I18N support * @param translator the Translator instance to be used */ public void buildGUI(final Translator translator) { // retrieve the GUI element builder TranslatableGUIElement guiBuilder = translator.getGenerator();
// create the window itself with an I18N title JFrame aFrame = guiBuilder.generateJFrame("guiDemo"); aFrame.getContentPane().setLayout(new BorderLayout());
// create a JMenuBar JMenuBar menuBar = new JMenuBar();
55
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
I18N GUI Demo – Code III
// generate the JMenu for this JMenu menu = guiBuilder.generateJMenu("fileMenu");
// generate a menu item with (key, useIconIfExists) JMenuItem exitItem = guiBuilder.generateJMenuItem("exitItem", true); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); // exit }});
// add the item to the JMenu menu.add(exitItem);
// add the menu to the menu bar and add this to the JFrame menuBar.add(menu); aFrame.setJMenuBar(menuBar);
56
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
I18N GUI Demo – Code IV
JPanel infoPanel = guiBuilder.generateBorderedJPanel("infoPanel"); aFrame.getContentPane().add(infoPanel, BorderLayout.CENTER);
// translatable JLabel JLabel label = guiBuilder.generateJLabel("clickMe"); infoPanel.add(label); // add the info button AbstractButton info = guiBuilder.generateJButton("clickButton"); info.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.err.println(translator.translateMessage("pressedN", String.valueOf(++nrTimes))); // show nr of button press } }); infoPanel.add(info); // add the info panel
57
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
I18N GUI Demo – Code V JPanel exitPanel = guiBuilder.generateBorderedJPanel("exitPanel"); aFrame.getContentPane().add(exitPanel, BorderLayout.SOUTH); AbstractButton exit = guiBuilder.generateJButton("exitButton"); // exit button exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.err.println(translator.translateMessage("bye", String.valueOf(nrTimes)); System.exit(0); // show good bye & # of pressed, exit }); exitPanel.add(exit); aFrame.pack(); aFrame.setVisible(true); } public static void main(String[] args) { I18NDemo demo = new I18NDemo(Locale.US); }}
58
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Result of the GUI Demo
• Here is the window again:
59
JFrameJMenuBar with JMenu „File“, hotkey F
JMenuItem “Exit” with icon, hotkey x, and tool tipJLabe
l JButton, hotkey i
Tooltip of the menu item
JButton, hotkey x, with iconBordered
JPanel
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
Result of the GUI Demo
• And this is the same window in German:
60
JFrameJMenuBar
with JMenu „Datei“, hotkey F
JMenuItem “Verlassen” with icon, hotkey v, and tool tipJLabe
l JButton, hotkey z
Tooltip of the menu item
JButton, hotkey b, with icon
Bordered JPanel
• To get this window, change main() to this line: I18NDemo demo = new I18NDemo(Locale.GERMANY);
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
A Few Final Notes• You may not have noticed, but…
– Both buttons, the menu and menu item have a shortcut (mnemonic)
– All GUI elements have a tool tip text• However, the texts etc. are not specified in the
source!– That is because they all come from the resource file– Shown on the next two slides
• Experiment a little with the API– Included on the web page with additional information– The source code can also be downloaded there!
• You can also do “on the fly” translation– Simply call translator.setTranslatorLocale(newLocale)
61
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
English Resource File for the GUI Demo
62
hi=Hello!personalized=Hello, {0}!multi=One {0} two {1} three {2} parametersnoSuchKeyException=There is no ressource for element {0}exitPanel=Exit PanelexitButton.iconName=quit.gifexitButton.label=ExitexitButton.mnemonic=xexitButton.toolTipText=Click this button to end the democlickButton.iconName=clickButton.label=Increment counterclickButton.mnemonic=iclickButton.toolTipText=Click here to increment the counterinfoPanel=Info AreaclickMe=Click here:fileMenu.label=FilefileMenu.mnemonic=ffileMenu.toolTipText=Contains the Exit itemexitItem.iconName=quit.gifexitItem.label=ExitexitItem.mnemonic=xexitItem.toolTipText=Exits the applicationpressedTimes=The increment button was pressed {0} times.bye=Good bye - and thank you for pressing the button {0} times.guiDemo=Internationalization Demo
Dr. G. RößlingProf. Dr. M. Mühlhäuser
RBG / Telekooperation©
Introduction to Computer Science I: T21
German Resource file for the GUI Demo
hi=Hallo!personalized=Hallo, {0}!multi=Eins {0} zwei {1} drei {2} ParameternoSuchKeyException=Es gibt keine Ressource f\u00fcr Eintrag {0}exitPanel=BeendenexitButton.iconName=quit.gifexitButton.label=BeendenexitButton.mnemonic=bexitButton.toolTipText=Dr\u00fccken Sie diesen Knopf zum BeendenclickButton.iconName=clickButton.label=Z\u00e4hler inkrementierenclickButton.mnemonic=zclickButton.toolTipText=Klicken Sie hier, um den Z\u00fchler zu inkrementiereninfoPanel=Info-BereichclickMe=Bitte hier klicken:fileMenu.label=DateifileMenu.mnemonic=dfileMenu.toolTipText=Enth\u0fe4lt nur den Eintrag 'Verlassen'exitItem.iconName=quit.gifexitItem.label=VerlassenexitItem.mnemonic=vexitItem.toolTipText=Beendet die AnwendungpressedTimes=Der Inkrementieren-Knopf wurde {0} Mal gedr\u00fcckt.bye=Auf Wiedersehen - und Danke, dass Sie den Knopf {0} Mal gedr\u00fcckt haben.guiDemo=Demo zur Internationalisierung
63