Control Keys

move to next slide (also Enter or Spacebar).
move to previous slide.
 d  enable/disable drawing on slides
 p  toggles between print and presentation view
CTRL  +  zoom in
CTRL  -  zoom out
CTRL  0  reset zoom

Slides can also be advanced by clicking on the left or right border of the slide.

Java Foundation Classes (JFC)

  • In this chapter, the Java Foundation Classes (JFC) are used to create cross-platform desktop applications
  • The Java Foundation Classes consist of:
    APIFunktion
    Abstract Window Toolkit (AWT)Base classes for GUI components, events, and layouts
    SwingGUI components, changeable look-and-feel
    Java 2DDrawing of 2D elements
    Java AccessibilityAccessibility support, e.g., for people with visual impairments
    Data TransferCut-and-paste, drag-and-drop

Install, compile, and run Java

  • Installing the Java SE Development Kit (Download)
  • Compile: (in a Shell)
    javac sourcefile.java
  • Execute:
    java sourcefile

The first GUI

The first GUI

  • Using the JFrame component as a top-level container
  • Displaying of text using JLabel
gui1


Source code of the example: HelloGUI.java

The first GUI

import javax.swing.*;

class MyGui extends JFrame { // class with own GUI components
  ...
}

public class HelloGUI {
  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        MyGui myGUI = new MyGui(); // Create instance of own class
        myGUI.createGUI();         // in the event dispatching thread 
      }
    });
  }
}

The first GUI

import javax.swing.*;

class MyGui extends JFrame {
  public void createGUI() {
    setTitle("HelloGUI");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(320, 240);
    JLabel label = new JLabel("Hello World");
    getContentPane().add(label);
    setVisible(true);
  }
}

public class HelloGUI {
  ...
}

Adding a Menu

  • Creating a menu with JMenuBar, JMenu und JMenuItem
gui1


Source code of the example: MyMenuBar.java

Adding a Menu

class MyGui extends JFrame {
  public void createGUI() {
    ...
    JMenuBar menuBar = new JMenuBar();
    JMenu menu = new JMenu("File");
    menuBar.add(menu);
    JMenuItem item = new JMenuItem("Open");
    menu.add(item);
    setJMenuBar(menuBar);

    setVisible(true);
  }
}

Adding a Button

  • Creating a button with JButton
gui1


Source code of the example: MyButton.java

Adding a Button

class MyGui extends JFrame {
  public void createGUI() {
    ...
    setLayout(null); // keine automatisches Layout
   
    JLabel label = new JLabel("Hello World");
    label.setBounds(120, 0, 150, 30); // manuelles Positionieren
    getContentPane().add(label);
    
    JButton button = new JButton("Button Text");
    button.setBounds(120, 30, 150, 30);
    getContentPane().add(button);
    ...
  }
}

Composition hierarchy for the example ("is part of")

containment_hierarchy


gui1

Inheritance hierarchy ("is a")

class_hierarchy

Event Processing

Event Processing

  • Event: Something has been activated, changed, moved, etc.
  • Event Source: The component that is directly affected by the event, for example, a pressed AbstractButton
  • Event Listener: The class that would like to be informed about the event
  • An event listener must register with an event source if it wants to be informed about its events.
  • The Event Dispatching Thread (EDT) runs in the background and sequentially processes the events from all event sources.

Inheritance Hierarchy: Event

event_class_hierarchy

Example: ActionEvent

public class ActionEvent extends AWTEvent
{

  // constructors
  public ActionEvent(Object source, int id, String command) { ... }
  ...
  // public members
  public String getActionCommand() { ... } 
  public long getWhen() { ... } 
  public int getModifiers() { ... } 
  public String paramString() { ... }
}

Interface Hierarchy: EventListener

event_class_hierarchy

Event Source and Event Listener

Example for an event listener: ActionListener
public interface ActionListener extends EventListener {
  void actionPerformed(ActionEvent event);
}

Example for an event source: AbstractButton
public abstract class AbstractButton extends ... {
  ...
  public void addActionListener(ActionListener l) {... }
  public void removeActionListener(ActionListener l) {... }
  public ActionListener[] getActionListeners() {... }
  ...
}

Adding an Event Processing for the Button

  • Clicking on the button increments a counter and displays the result in a label text
gui1


Source code of the example: ActionButton

Adding an Event Processing for the Button

class MyGui extends JFrame implements ActionListener{

  private int counter = 0;
  JLabel label = new JLabel("Hello World");
  
  public void createGUI() {
    ...
    JButton button = new JButton("Increment");
    button.addActionListener(this);
    getContentPane().add(button);
    ...
  }
  public void actionPerformed(ActionEvent event) {
    counter++;
    label.setText("Click #" + Integer.toString(counter));
  }
}

Adding an Event Processing for the Menu

  • Selection of the MenuItem "Reset" resets the counter
gui_action_menu


Source code of the example: ActionMenu.java

Adding an Event Processing for the Menu

class MyGui extends JFrame implements ActionListener{
    ...
    JMenuItem item2 = new JMenuItem("Reset", KeyEvent.VK_R);
    item2.addActionListener(this);
    item2.setActionCommand("ResetCmd");
    menu.add(item2);
    setJMenuBar(menuBar);
    ...
  }
  
  public void actionPerformed(ActionEvent event) {
    counter++;
    if(event.getActionCommand().equals("ResetCmd") ) counter = 0;
    label.setText("Click #" + Integer.toString(counter));
  }

MouseEvent and MouseListener

public class MouseEvent extends InputEvent {
  ... 
  public int getX() {...}
  public int getY() {...}
  public Point getPoint() {...}
  public int getButton() {...}
  public String paramString() {...}
  ...
}
public interface MouseListener extends EventListener {
  void mouseClicked(MouseEvent event);
  void mousePressed(MouseEvent event);
  void mouseReleased(MouseEvent event);
  void mouseEntered(MouseEvent event);
  void mouseExited(MouseEvent event);
}

MouseEvent Example

  • When clicking with the mouse on the JFrame, the position of the mouse pointer is displayed
gui_mouselistener


Source code of the example: MyMouseListener.java

MouseEvent Example

class MyGuiMouseListener implements MouseListener {
  ...
}

class MyGui extends JFrame {
  public void createGUI() {
    ...
    JLabel label = new JLabel("Position: 0, 0");
    label.setBounds(120, 0, 150, 30);
    getContentPane().add(label);
    
    MyGuiMouseListener mouseListener = new MyGuiMouseListener();
    mouseListener.setLabelRef(label);
    addMouseListener(mouseListener);
    ...
  }
}

MouseEvent Example

class MyGuiMouseListener implements MouseListener {
  private JLabel labelRef;
  public void setLabelRef(JLabel label) { labelRef= label; }
  
  public void mousePressed(MouseEvent event) {
    labelRef.setText("Position: " + Integer.toString(event.getX()) +
                     ", " + Integer.toString(event.getY()));
  }
  public void mouseClicked(MouseEvent event) {}
  public void mouseReleased(MouseEvent event){}
  public void mouseEntered(MouseEvent event) {}
  public void mouseExited(MouseEvent event) {}
}

Adapter Classes

  • As seen in the previous example, when implementing an event listener interface (e.g. MouseListener) all methods must exist, even if they are not needed
  • Adapter classes implement empty methods such that only the required methods must be implemented in a derived class

Mouse Event Processing with Adapter Classes

class MyGuiMouseAdapter extends MouseAdapter {
  private JLabel labelRef;
  public void setLabelRef(JLabel label) { labelRef= label; }
  public void mousePressed(MouseEvent event) {
    labelRef.setText("Position: " + Integer.toString(event.getX()) +
                     ", " + Integer.toString(event.getY()));
  }
}

class MyGui extends JFrame {
  public void createGUI() {
    ...
    MyGuiMouseAdapter mouseAdapter = new MyGuiMouseAdapter();
    mouseAdapter.setLabelRef(label);
    addMouseListener(mouseAdapter);
  }
}

Layout-Manager

Layout-Manager

  • In the previous examples, no layout manager was used
  • This is not a problem as long as the window size is not changed
class MyGui extends JFrame {
  public void createGUI() {
    ...
    setLayout(null); // keine automatisches Layout
    setResizeable(false); // Fenstergröße ist nicht veränderbar
    
    JLabel label = new JLabel("Hello World");
    label.setBounds(120, 0, 150, 30); // manuelles Positionieren
    getContentPane().add(label);
  }
}

Layout-Manager

  • A layout manager automates the placement of components
  • The layout is automatically adjusted when the window size is changed
  • To this end, the individual components communicate their minimum, maximum, and desired layout size

LayoutManager Interface

public interface LayoutManager {
  void addLayoutComponent(String name, Component component);
  void removeLayoutComponent(Component component);
  Dimension preferredLayoutSize(Container parent);
  Dimension minimumLayoutSize(Container parent);
  void layoutContainer(Container parent);
} 

Hierarchy LayoutManager

class_hierarchy

Layout-Manager: BorderLayout

  • The BorderLayout manager is the default for many windows, such as JFrame
  • The layout divides the window into 5 areas: north, east, south, west and center
gui_borderlayout

Source code of the example: MyBorderLayout.java

Layout-Manager: BorderLayout

class MyGui extends JFrame{
  public void createGUI() {
    ...
    Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout(0,0));
    contentPane.add(BorderLayout.NORTH, new JButton("North"));
    contentPane.add(BorderLayout.EAST, new JButton("East"));
    contentPane.add(BorderLayout.SOUTH, new JButton("South"));
    contentPane.add(BorderLayout.WEST, new JButton("West"));
    contentPane.add(BorderLayout.CENTER, new JButton("Center"));
    
    setVisible(true);
  }
}

Layout-Manager: GridLayout

  • The grid layout manager arranges the components on a regular grid
  • The components are trying to fill their assigned grid cell
gui_Gridlayout


Source code of the example: MyGridLayout.java

Layout-Manager: GridLayout

class MyGui extends JFrame{
  public void createGUI() {
    ...
    Container contentPane = getContentPane();
    // 3 Zeilen mit Abstand 15, und 2 Spalten mit Abstand 5
    contentPane.setLayout(new GridLayout(3, 2, 5, 15));
    contentPane.add(new JButton("Button 1"));
    contentPane.add(new JButton("Button 2"));
    contentPane.add(new JButton("Button 3"));
    contentPane.add(new JButton("Button 4"));
    contentPane.add(new JButton("Button 5"));
    contentPane.add(new JButton("Button 6"));
    
    setVisible(true);
  }
}

Layout-Manager: SpringLayout

  • The SpringLayout manager is relatively difficult to handle and is actually designed for use with visual GUI editors
  • For example, it is a good choice when the task is to create a form


Source code of the example:
MySpringLayout.java, SpringUtilities.java

Layout-Manager: SpringLayout

public void createGUI() { ...
  String[] labels = {"Firstname: ", "Lastname: ", 
                     "Student ID: ", "Enrolled since: "};
  Container cp = getContentPane();
  cp.setLayout(new SpringLayout());
  for (int i = 0; i < labels.length; i++) {
    JLabel label = new JLabel(labels[i], JLabel.TRAILING);
    cp.add(label);
    JTextField textField = new JTextField(10);
    label.setLabelFor(textField);
    cp.add(textField);
  }
  SpringUtilities.makeCompactGrid(cp, labels.length, 2, 5, 5, 5, 5);
  pack(); // dense packing
  setVisible(true);
}

Threads

Example: Long calculations within its own thread

  • A JButton starts a long calculation
  • The progress is displayed by a JProgressBar
  • The user can abort the calculations at any time

gui_action_menu

Source code of the example: MyProgressBar.java

Example: Long calculations within its own thread

class MyGui extends JFrame implements ActionListener {
  final JProgressBar progressBar = new JProgressBar(0, 100);
  final JButton button = new JButton("Compute");
  boolean userStopped = false, threadAlive = false;
  int percent;
  Runnable updateUI = new Runnable() { ... }; // for UI update
  Runnable workerThread = new Runnable() { ... }; // for computation
  
  public void createGUI() {... }
  public void actionPerformed(ActionEvent event) { // button pressed
    if(!threadAlive) {
      threadAlive = true; userStopped = false;
      new Thread(workerThread).start(); 
    } 
    else userStopped = true;
  }
}

Example: Long calculations within its own thread

  Runnable workerThread = new Runnable() { // for computation

    public void run() {
      for (int i=0; i < 100 && !userStopped; i++) {
        try {
          Thread.sleep(50); // compute something here
          percent = i;
          // run updateUI in the Event Dispatching Thread
          SwingUtilities.invokeLater(updateUI); 
        } catch (InterruptedException e) {}
      }
      percent = 100;
      SwingUtilities.invokeLater(updateUI);
      threadAlive = false;
    }
  };

Example: Long calculations within its own thread

  Runnable updateUI = new Runnable() { // for UI update

    public void run() {
      if(percent < 100) {
        progressBar.setString("Computing " + percent + "%");
        button.setText("Stop");
      }else{
        progressBar.setString("Done");
        button.setText("Compute");
      }
      progressBar.setValue(percent);
    }
  };

Java 2D

Java 2D

  • Java 2D is useful for creating 2D dimensional drawings
  • The graphical output of an AWT component is modified (such as, for example, JFrame) by overriding its paint() method

Example: Line, Rectangle, and Circle

  • The example draws a line, a rectangle, and a circle

gui_linerectcircle

Source code of the example: LineRectCircle.java

Example: Line, Rectangle, and Circle

class MyGui extends JFrame {
  public void createGUI() {...}

  public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g; // cast to Graphics2D
    Line2D.Double line = new Line2D.Double(20.0, 50.0, 
                                           50.0, 200.0);
    g2d.draw(line); 
    Rectangle2D.Double rect = new Rectangle2D.Double(100.0, 50.0, 
                                                      60.0, 80.0);
    g2d.draw(rect); // also try g2d.fill(rect);
    Ellipse2D.Double circle = new Ellipse2D.Double(200.0, 100.0, 
                                                   80.0, 80.0);
    g2d.draw(circle); // also try g2d.fill(circle); 
  }
}

Example: Drawing a general path

  • The example draws a "T" with the help of the GeneralPath class

gui_generalpath

Source code of the example: MyGeneralPath.java

Example: Drawing a general path

  public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g; // cast to Graphics2D
    GeneralPath gp = new GeneralPath(); 
    gp.moveTo( 50,  50); // start here
    gp.lineTo( 50,  70); // going down
    gp.lineTo(100,  70); // going right
    gp.lineTo(100, 180); // going down
    gp.lineTo(120, 180); // going right
    gp.lineTo(120,  70); // going up
    gp.lineTo(170,  70); // going right
    gp.lineTo(170,  50); // going up
    gp.lineTo( 50,  50); // going left (back to start)
    
    g2d.draw(gp); // also try g2d.fill(gp); 
  }

Are there any questions?

questions

Please notify me by e-mail if you have questions, suggestions for improvement, or found typos: Contact

More lecture slides

Slides in German (Folien auf Deutsch)