Introduction to Computer Science I
Download
Report
Transcript Introduction to Computer Science I
Technische Universität Darmstadt
Telecooperation/RBG
Introduction to Computer Science I
Topic 21: Graphical User Interfaces
Nested Classes
Prof. Dr. Max Mühlhäuser
Dr. Guido Rößling
Copyrighted material; for TUD student use only
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
2
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Components
• Some common components and their main tasks are:
• Display text and symbols
– JLabel
• Dispatching actions
– JButton
– JMenu
Introduction to Computer Science I: T21
3
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Components
• Text input
– JTextField
• Choose from a given set of options
– JCheckBox
JRadioButton
• Choose from a variable set
– JList
JComboBox
Button or TextField +
expandable Listbox
Introduction to Computer Science I: T21
4
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Introduction to Computer Science I: T21
5
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Anatomy of a GUI-Application
GUI-Framework
Network of cooperating
objects with clear
responsibility:
Container
•
•
•
•
•
components
Events
Application logic
Method calls on
components
Listener
state:
value=3
Introduction to Computer Science I: T21
Components
Containers
Events
Listener
Layout
– Sets the alignment of
components
• Look & Feel
– Sets look and feel of
the components
• separate: application
logic
6
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Program
thread
• Concurrent programs
– Program can have multiple threads
– Multiple parts of the program can execute in parallel.
threads
Program
Introduction to Computer Science I: T21
7
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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 eventdispatching 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
Introduction to Computer Science I: T21
8
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Programming model
Application
GUI-Framework (Swing)
main
main
Add component
AWT-EventQueue
AWT-EventQueue
Event:
Draw component
AWT-EventQueue
Event:
User input
Introduction to Computer Science I: T21
9
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Window
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...");
Introduction to Computer Science I: T21
10
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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 program
Event handling is missing; more on this later.
Introduction to Computer Science I: T21
11
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Container
JFrame
• Container and components
JPanel
– JFrame: „top level container“
JLabel
• 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)
JFrame
...
• Container Hierarchy
JPanel
– Even the simplest application consists of a hierarchy of
containers and components
– (The diagram simplifies. The container linking JFrame and JLabel
JPanel are out of scope)
Introduction to Computer Science I: T21
12
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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).
contentPane
• JLabels
– Draw text and/or symbols
– Are passive components, not allowing
interaction
Introduction to Computer Science I: T21
JFrame
...
JPanel
JLabel
13
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Labels
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);
// ...
Introduction to Computer Science I: T21
14
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Buttons
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);
// ...
Introduction to Computer Science I: T21
15
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Introduction to Computer Science I: T21
16
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
17
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
GridLayout
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);
}
}
...
Introduction to Computer Science I: T21
18
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Introduction to Computer Science I: T21
19
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Listener
• Multiple listeners can register for an event source and get
informed about events of a certain type from then on
event
source
event object
event listener
event listener
event listener
• 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)
Introduction to Computer Science I: T21
20
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Events
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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");
}
}
// ...
}
This is a nested class. More later
Introduction to Computer Science I: T21
21
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
View-Updates
• The look of the components and the information
they present can be changed by calling appropriate
methods
• JLabel API (extract):
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
Introduction to Computer Science I: T21
22
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Events
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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]");
}
}
// ...
Introduction to Computer Science I: T21
23
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Window Events
• With a click on the close button, the
program should be terminated
Register a WindowListener
• Interface WindowListener:
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
Introduction to Computer Science I: T21
24
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Introduction to Computer Science I: T21
25
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
WindowEvents
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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);
Introduction to Computer Science I: T21
26
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
WindowEvents
// 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;
Introduction to Computer Science I: T21
27
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
28
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
Option 1: Frame class directly
implements the Listener Interface
©
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");
}
// ...
}
Introduction to Computer Science I: T21
29
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
Option 1: Frame-class directly
implements 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
Introduction to Computer Science I: T21
30
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
Option 2:
External class implements the Listener Interface
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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]");
}
}
Introduction to Computer Science I: T21
31
©
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
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 actionPerformed
Introduction to Computer Science I: T21
32
©
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
Option 2:
External class implements the Listener Interface
©
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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]");
}
}
Introduction to Computer Science I: T21
33
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
34
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Nested classes
import
import
import
import
import
import
import
- Nested Class can be “private”
- only visible in surrounding class
- has access to private members of surrounding class
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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]");
}
}
//
}
...
Introduction to Computer Science I: T21
35
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
36
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Anonymous Nested classes
import
import
import
import
import
import
import
java.awt.Container;
java.awt.GridLayout;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
javax.swing.JButton;
javax.swing.JFrame;
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);
}
}
Introduction to Computer Science I: T21
37
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
38
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
39
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
40
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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:
Separate application logic
from presentation logic
Introduction to Computer Science I: T21
41
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
42
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Model-View-Controller
event notification
handle Controller
user
input
controller updates
View
Display
output
Model
A
B
C
45 35 15
Application
data & behaviour
Introduction to Computer Science I: T21
43
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
44
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
45
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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.
Introduction to Computer Science I: T21
46
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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…:
Introduction to Computer Science I: T21
47
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
48
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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:
msg.en_US
msg.de_DE
hi=Hello!
hi=Hallo!
query=How are you today? query=Wie geht es Dir?
Introduction to Computer Science I: T21
49
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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);
Introduction to Computer Science I: T21
50
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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!”
Introduction to Computer Science I: T21
51
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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…)
Introduction to Computer Science I: T21
52
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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…
Introduction to Computer Science I: T21
53
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
I18N GUI Demo – Code I
import translator.TranslatableGUIElement; // for GUI elements
import 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
}
Introduction to Computer Science I: T21
54
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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();
Introduction to Computer Science I: T21
55
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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);
Introduction to Computer Science I: T21
56
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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
Introduction to Computer Science I: T21
57
I18N GUI Demo – Code V
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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);
}
}
Introduction to Computer Science I: T21
58
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Result of the GUI Demo
• Here is the window again:
JFrame
JMenuItem
“Exit” with
icon, hotkey x,
and tool tip
JMenuBar with
JMenu „File“,
hotkey F
JLabel
JButton, hotkey i
Tooltip of the
menu item
Bordered JPanel
JButton, hotkey
x, with icon
Introduction to Computer Science I: T21
59
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
Result of the GUI Demo
• And this is the same window in German:
JFrame
JMenuItem
“Verlassen” with
icon, hotkey v,
and tool tip
JMenuBar with
JMenu „Datei“,
hotkey F
JLabel
JButton, hotkey z
Tooltip of the
menu item
Bordered JPanel
JButton, hotkey
b, with icon
• To get this window, change main() to this line:
I18NDemo demo = new I18NDemo(Locale.GERMANY);
Introduction to Computer Science I: T21
60
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
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)
Introduction to Computer Science I: T21
61
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
English Resource File for the GUI Demo
hi=Hello!
personalized=Hello, {0}!
multi=One {0} two {1} three {2} parameters
noSuchKeyException=There is no ressource for element {0}
exitPanel=Exit Panel
exitButton.iconName=quit.gif
exitButton.label=Exit
exitButton.mnemonic=x
exitButton.toolTipText=Click this button to end the demo
clickButton.iconName=
clickButton.label=Increment counter
clickButton.mnemonic=i
clickButton.toolTipText=Click here to increment the counter
infoPanel=Info Area
clickMe=Click here:
fileMenu.label=File
fileMenu.mnemonic=f
fileMenu.toolTipText=Contains the Exit item
exitItem.iconName=quit.gif
exitItem.label=Exit
exitItem.mnemonic=x
exitItem.toolTipText=Exits the application
pressedTimes=The increment button was pressed {0} times.
bye=Good bye - and thank you for pressing the button {0} times.
guiDemo=Internationalization Demo
Introduction to Computer Science I: T21
62
Dr. G. Rößling
Prof. Dr. M. Mühlhäuser
RBG / Telekooperation
©
German Resource file for the GUI Demo
hi=Hallo!
personalized=Hallo, {0}!
multi=Eins {0} zwei {1} drei {2} Parameter
noSuchKeyException=Es gibt keine Ressource f\u00fcr Eintrag {0}
exitPanel=Beenden
exitButton.iconName=quit.gif
exitButton.label=Beenden
exitButton.mnemonic=b
exitButton.toolTipText=Dr\u00fccken Sie diesen Knopf zum Beenden
clickButton.iconName=
clickButton.label=Z\u00e4hler inkrementieren
clickButton.mnemonic=z
clickButton.toolTipText=Klicken Sie hier, um den Z\u00fchler zu inkrementieren
infoPanel=Info-Bereich
clickMe=Bitte hier klicken:
fileMenu.label=Datei
fileMenu.mnemonic=d
fileMenu.toolTipText=Enth\u0fe4lt nur den Eintrag 'Verlassen'
exitItem.iconName=quit.gif
exitItem.label=Verlassen
exitItem.mnemonic=v
exitItem.toolTipText=Beendet die Anwendung
pressedTimes=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
Introduction to Computer Science I: T21
63