Java Graphics Programming

44
GRAPHICS PROGRAMMING PROGRAMMAZIONE CONCORRENTE E DISTR. Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in Informatica, A.A. 2015 – 2016 [email protected]

Transcript of Java Graphics Programming

Page 1: Java Graphics Programming

GRAPHICS PROGRAMMINGPROGRAMMAZIONE CONCORRENTE E DISTR.Università degli Studi di Padova

Dipartimento di Matematica

Corso di Laurea in Informatica, A.A. 2015 – [email protected]

Page 2: Java Graphics Programming

2Programmazione concorrente e distribuita

SUMMARY Introducing Swing Main components Layout management Event handling

Riccardo Cardin

Page 3: Java Graphics Programming

3Programmazione concorrente e distribuita

INTRODUCTION A little bit of history

Java 1.0 refers to the Abstract Window Toolkit (AWT) for simple GUI programming AWT delegates to the underlying OS the responsibility to

create graphical components («peers») Look and feel of target platform

It was very hard to create high-quality portable GUIs Java 1.2 intoduces Swing

Graphic components are painted onto blank windows The only functionality required from the underlying

windowing system is a way to put up windows and to paint onto them

Build on top of AWT

Riccardo Cardin

Page 4: Java Graphics Programming

4Programmazione concorrente e distribuita

INTRODUCTION

Riccardo Cardin

Page 5: Java Graphics Programming

5Programmazione concorrente e distribuita

INTRODUCTION Swing features

A little bit slower than AWT It’s not a real problem on modern machines

Rich and convenient set of user interface elementsFew dependencies on the underlying platformConsistent user experience across platforms

Drawback: different look-and-feel from native GUIsMany different look-and-feels (themes)

Metal, Ocean and Synth (JSE 5.0), Nimbus (JSE 7.0, vector drawings)

Package javax.swing: it is considered a Java ext.

Riccardo Cardin

Page 6: Java Graphics Programming

6Programmazione concorrente e distribuita

INTRODUCTION Swing Ocean look-and-feel

Riccardo Cardin

Page 7: Java Graphics Programming

7Programmazione concorrente e distribuita

MAIN COMPONENTS Frame

Top level window, Frame (AWT) or JFrame (Swing) The only Swing component that is not painted on the canvas Always use «J» components, which belong from Swing

Riccardo Cardin

EventQueue.invokeLater(new Runnable() { public void run() { SimpleFrame frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }});class SimpleFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public SimpleFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); }}

Page 8: Java Graphics Programming

8Programmazione concorrente e distribuita

MAIN COMPONENTS Let me explain what’s going on in here...

By default a frame as size of 0 x 0 pixels, so SimpleFrame set the size of the frame in its ctor

You have to define what should happen when the user closes the application’s frame JFrame.EXIT_ON_CLOSE: the program exit on close

Event dispatch thread

Finally, a frame has to be made visible, using setVisible(true)

Riccardo Cardin

EventQueue.invokeLater(new Runnable() { public void run() { // Configuration statement } });

You have to do ALWAYS in this way!!!

Page 9: Java Graphics Programming

9Programmazione concorrente e distribuita

MAIN COMPONENTS Frame hierarchy

Component / Windows Component is the base class of

every GUI object Resize and reshape actions

Frame properties set / get methods

Toolkit class Used to bind some components

to a particular native toolkit impl.

Adapter pattern

Riccardo Cardin

Toolkit kit = Toolkit.getDefaultToolkit();

Page 10: Java Graphics Programming

10Programmazione concorrente e distribuita

MAIN COMPONENTS Display information in a component

DO NOT DRAW DIRECTLY ONTO A FRAME! A frame is considered a container for components

Use the content pane instead

Components are instances of JComponent / JPanel Implement paintComponent method, that is called by the

event handler every time a window needs to be redrawn

Riccardo Cardin

// Get the content pane and draw something on itContainer contentPane = frame.getContentPane();Component c = /* . . . */;contentPane.add(c);

class MyComponent extends JComponent { public void paintComponent(Graphics g) { // code for drawing }}

Page 11: Java Graphics Programming

11Programmazione concorrente e distribuita

MAIN COMPONENTS

Riccardo Cardin

Used to organize the menu bar and

content pane and to implement

look-and-feel

Used to add Components and to

draw something onto the frame

Page 12: Java Graphics Programming

12Programmazione concorrente e distribuita

MAIN COMPONENTS

Riccardo Cardin

Page 13: Java Graphics Programming

13Programmazione concorrente e distribuita

LAYOUT MANAGEMENT JDK has not form designer tools

You need to write code to position (lay out) the UI components where you want them to be

Buttons, text fields, and other UI elements extend the class Component. Components can be placed inside containers, such as panel. Containers can themselves be put inside other containers

Container extends Component Composite pattern

Riccardo Cardin

In general components are placed inside containers, and a layout manager determines the position and sizes of the components in the container

Page 14: Java Graphics Programming

14Programmazione concorrente e distribuita

LAYOUT MANAGEMENT

Riccardo Cardin

Container class stores references to

itself

Page 15: Java Graphics Programming

15Programmazione concorrente e distribuita

LAYOUT MANAGEMENT

Riccardo Cardin

Page 16: Java Graphics Programming

16Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Composite pattern

In Swing, the problem is that leaf components are subclasses of composite class

Riccardo Cardin

It is a composition of Component

objects

Page 17: Java Graphics Programming

17Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Flowlayout

Elements are put in a row, sized at their preferred size Default layout manager for a panel

If the horizontal space in the container is too small, the layout uses multiple rows. Elements are centered horizontally by default

Layout changes accordingly to container sizeConstructor permits to specify:

Left, right or center alignment Vertical or horizontal gaps

Riccardo Cardin

Elements are put in rows

Page 18: Java Graphics Programming

18Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Add 3 buttons to a JPanel

Riccardo Cardin

public class BorderLayoutExample extends JFrame { public BorderLayoutExample(String title) { super(title); // Set the size of the window setSize(300, 200); // Add component to frame addComponentsToPane(getContentPane()); }

private void addComponentsToPane(final Container pane) { // Panel with FlowLayout as default layout manager JPanel controls = new JPanel(); controls.add(new JButton("Button 1")); controls.add(new JButton("Button 2")); controls.add(new JButton("Button 3")); // Content pane of the frame, BorderLayout as default pane.add(controls, BorderLayout.SOUTH); }

Page 19: Java Graphics Programming

19Programmazione concorrente e distribuita

LAYOUT MANAGEMENT BorderLayout

Defines 5 regions in which elements can be placed Default layout manager of the JFrame content panel BorderLayout.NORTH, BorderLayout.EAST...

Center is the default positionThe edge components are laid first

When the container is resized, the dim. of the edge components are unchanged

It grows all components to fill the available space

Use an intermediate JPanel to contain the elements

Riccardo Cardin

Page 20: Java Graphics Programming

20Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Build a window with 3 buttons at the bottom

Riccardo Cardin

public class BorderLayoutExample extends JFrame { public BorderLayoutExample(String title) { super(title); // Set the size of the window setSize(300, 200); // Add component to frame addComponentsToPane(getContentPane()); }

private void addComponentsToPane(final Container pane) { // Panel with FlowLayout as default layout manager JPanel controls = new JPanel(); controls.add(new JButton("Button 1")); controls.add(new JButton("Button 2")); controls.add(new JButton("Button 3")); // Content pane of the frame, BorderLayout as default pane.add(controls, BorderLayout.SOUTH); }

Page 21: Java Graphics Programming

21Programmazione concorrente e distribuita

LAYOUT MANAGEMENT GridLayout

Arranges all components in rows and columns like a spreadsheet All components are given the same size (also in case of

resizing of the window) Usually used to model a small part of a UI, rather than the

whole windowsComponents are added starting from the first entry in

the first row, then the second entry and so on

Riccardo Cardin

// Get the content pane and draw something on it// Valuing with a 0 the number of rows will allow the layout to // use as many rows as necessarypanel.setLayout(new GridLayout(4, 4));

Page 22: Java Graphics Programming

22Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Build a windows with 4 buttons put in 2 rows

Riccardo Cardin

public class GridLayoutExample extends JFrame { public BorderLayoutExample(String title) { super(title); // Set the size of the window setSize(300, 200); // Add component to frame addComponentsToPane(getContentPane()); } private void addComponentsToPane(final Container pane) { // Set GridLayout to the panelb JPanel controls = new JPanel(); controls.setLayout(new GridLayout(2, 2)); controls.add(new JButton("Button 1")); controls.add(new JButton("Button 2")); controls.add(new JButton("Button 3")); controls.add(new JButton("Button 4")); pane.add(controls; }

Page 23: Java Graphics Programming

23Programmazione concorrente e distribuita

LAYOUT MANAGEMENT CardLayout

Used to model two or more components that share the same display space

It is like playing card in a stack, where only the top card (component) is visible at any time You can ask for either the first or the last card You can ask to flip the deck backwards or forwards You can specify a card with a specific name

Riccardo Cardin

Page 24: Java Graphics Programming

24Programmazione concorrente e distribuita

LAYOUT MANAGEMENT Build a window with two cards

Riccardo Cardin

public class CardLayoutExample extends JFrame { // ... private void addComponentsToPane(final Container pane) { // ... cards = new JPanel(new CardLayout()); cards.add(createCard1(), "Card 1"); cards.add(createCard2(), "Card 2"); } private JPanel createCombo() { // ... // Add combo a listener comboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { // Get the layout CardLayout layuot = (CardLayout) cards.getLayout(); layuot.show(cards, (String) e.getItem()); } });

We will introduce

listeners in a moment

Page 25: Java Graphics Programming

25Programmazione concorrente e distribuita

LAYOUT MANAGEMENT

Riccardo Cardin

Page 26: Java Graphics Programming

26Programmazione concorrente e distribuita

EVENT HANDLING An operating environment constantly monitors

events and reports them to the programThe program decides what to do in response to these

events Keystrokes, mouse clicks, and so on

In Java (AWT) the developer has the full control on how the events are transmitted from the event source to events listeners Every object can be an event listener (delegation model) Event listeners register themself to an event source

Obsever pattern Events are objects of type java.util.EventObject

Riccardo Cardin

Page 27: Java Graphics Programming

27Programmazione concorrente e distribuita

EVENT HANDLING Summarizing

A listener object implements a listener interface

An event source can register listener and send them event objects

The event source sends events to every registered listenerThe listener, using the event info, reacts accordingly

Riccardo Cardin

class MyListener implements ActionListener { public void actionPerformed(ActionEvent event) { // React to the event goes here }}

JButton button = new Jbutton("OK");button.addActionListener(listener); // Registering a listener

Page 28: Java Graphics Programming

28Programmazione concorrente e distribuita

EVENT HANDLING

Riccardo Cardin

An event source registers a listener

Event sourc

e

Event source notifies the

listener

The listener react accordingly

Page 29: Java Graphics Programming

29Programmazione concorrente e distribuita

EVENT HANDLING

Riccardo Cardin

Page 30: Java Graphics Programming

30Programmazione concorrente e distribuita

EVENT HANDLING

Riccardo Cardin

Page 31: Java Graphics Programming

31Programmazione concorrente e distribuita

EVENT HANDLING Let’s see a simple example

First of all, let’s create the buttons To create a button, simply create a JButton object, giving to

it a label or an icon

Riccardo Cardin

We will show a panel populated with three buttons. When a button is clicked, we want the background color of the panel to change to a particular color.

// Create the buttonsJButton blueButton = new JButton("Yellow");JButton blueButton = new JButton("Blue");JButton redButton = new JButton("Red");// Add them to a panel (flow layout anyone?)buttonPanel.add(yellowButton);buttonPanel.add(blueButton);buttonPanel.add(redButton);

Page 32: Java Graphics Programming

32Programmazione concorrente e distribuita

EVENT HANDLING Let’s see a simple example

Then, let’s define button listeners

Riccardo Cardin

class ColorAction implements ActionListener { private Color backgroundColor; // The color to set to the panel public ColorAction(Color c) { backgroundColor = c; } public void actionPerformed(ActionEvent event) { // set panel background color }}// Create the listenersColorAction yellowAction = new ColorAction(Color.YELLOW);ColorAction blueAction = new ColorAction(Color.BLUE);ColorAction redAction = new ColorAction(Color.RED);// Register listeners to buttonsyellowButton.addActionListener(yellowAction);blueButton.addActionListener(blueAction);redButton.addActionListener(redAction);

Page 33: Java Graphics Programming

33Programmazione concorrente e distribuita

EVENT HANDLING Let’s see a simple example

A problem rises: how can a listener modify a property of the panel? Please, do not try to add listener’s func. to the frame

Violation of separation of concerns Use inner classes instead!

Riccardo Cardin

class ButtonFrame extends JFrame { // The panel to change the color private JPanel buttonPanel; private class ColorAction implements ActionListener { private Color backgroundColor; public void actionPerformed(ActionEvent event) { // Changing the color to the main class panel buttonPanel.setBackground(backgroundColor); } }}

Page 34: Java Graphics Programming

34Programmazione concorrente e distribuita

EVENT HANDLING Let’s see a simple example

Can we go even further?Let’s use anonymous inner classes to handle events

The inner class mechanism automatically generates a constructor that stores all final variables that are used

Closure anyone?!Riccardo Cardin

public void makeButton(String name, final Color backgroundColor) { JButton button = new JButton(name); buttonPanel.add(button); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { buttonPanel.setBackground(backgroundColor); } });}

Page 35: Java Graphics Programming

35Programmazione concorrente e distribuita

EVENT HANDLING

Riccardo Cardin

Page 36: Java Graphics Programming

36Programmazione concorrente e distribuita

EVENT HANDLING Let’s see a simple example

If the anonymous inner class method calls one method only, EventHandler class can be used Reflection mechanism

The statement frame.loadData() is executed in response of an event

The statement frame.loadData(event.getSource.getText()) is executed

Riccardo Cardin

loadButton.addActionListener( EventHandler.create(ActionListener.class, frame, "loadData"));

EventHandler.create(ActionListener.class, frame, "loadData", "source.text");

Page 37: Java Graphics Programming

37Programmazione concorrente e distribuita

EVENT HANDLING Not all events are simply as button clicks

The listener WindowListener interface, that handles WindowEvent objects, has 7 methods

Probably you don’t need to defined them all!Each AWT listener interfaces with more than one method

comes with a companion Adapter Implements all methods with "do nothing" operations

Riccardo Cardin

public interface WindowListener { void windowOpened(WindowEvent e); void windowClosing(WindowEvent e); void windowClosed(WindowEvent e); void windowIconified(WindowEvent e); void windowDeiconified(WindowEvent e); void windowActivated(WindowEvent e); void windowDeactivated(WindowEvent e);}

Page 38: Java Graphics Programming

38Programmazione concorrente e distribuita

EVENT HANDLING Adapter pattern

Class adapter

Object adapter

Riccardo Cardin

Target interfaceSource interface

Adapt source interface to target

Page 39: Java Graphics Programming

39Programmazione concorrente e distribuita

EVENT HANDLING What if you need to share the same behaviour in

response to more than one event?Use Action interface, that extends ActionListener

It encapsulates the description of the «command» and parameters that are necessary to carry out the command

Command pattern AbstractAction is an adapter class provided by the JDK

Then simply add the action to your UI components using constructor

Riccardo Cardin

void actionPerformed(ActionEvent event)// Add a property to the action object indexed by keyvoid putValue(String key, Object value)// Get a property indexed by keyObject getValue(String key)

new JButton(new MyAction());

Page 40: Java Graphics Programming

40Programmazione concorrente e distribuita

EVENT HANDLING

Interface Method Params Generated by

ActionListener actionPerformed ActionEvent• getActionCommand• getModifiers

ActionButtonJComboBoxJTextFieldTimer

AdjustmentListener adjustementValueChanged

AdjustementEvent• getAdjustable• getAdjustableType• getValue

JScrollbar

ItemListener itemStateChanged ItemEvent• getItem• getItemSelectable• getStateChange

AbstractButtonJComboBox

FocusListener focusGainedfocusLost

FocusEvent• isTemporary

Component

KeyListener keyPressedkeyReleasedkeyTyped

KeyEvent• getKeyChar• getKeyCode• getKeyModifiersTex

t• getKeyText• isActionKey

Component

Riccardo Cardin

Page 41: Java Graphics Programming

41Programmazione concorrente e distribuita

EVENT HANDLING

...and so onRiccardo Cardin

Interface Method Params Generated by

MouseListener mousePressedmouseReleasedmouseEnteredmouseExitedmouseClicked

MouseEvent• getClickCount• getX• getY• getPoint• translatePoint

Component

MouseMotionListener mouseDraggedmouseMoved

MouseEvent Component

MouseWheelListener mouseWheelMoved MouseWheelEvent• getWheelRotation• getScrollAmount

Component

WindowListener windowClosingwindowOpenedwindowIconifiedwindowDeiconifiedwindowClosedwindowActivatedwindowDeactivated

WindowEvent• getWindow

Window

Page 42: Java Graphics Programming

42Programmazione concorrente e distribuita

CONCLUSIONS

Riccardo Cardin

Page 43: Java Graphics Programming

43Programmazione concorrente e distribuita

EXAMPLES

Riccardo Cardin

https://github.com/rcardin/pcd-snippets

Page 44: Java Graphics Programming

44Programmazione concorrente e distribuita

REFERENCES Chap. 7 «Graphics Programming», Core Java Volume I -

Fundamentals, Cay Horstmann, Gary Cornell, 2012, Prentice Hall Chap. 8 «Event Handling», Core Java Volume I - Fundamentals, Cay

Horstmann, Gary Cornell, 2012, Prentice Hall Chap. 9 «User Interface Components with Swing», Core Java

Volume I - Fundamentals, Cay Horstmann, Gary Cornell, 2012, Prentice Hall

How to Use FlowLayout https://docs.oracle.com/javase/tutorial/uiswing/layout/flow.html

How to Use CardLayout https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html

How to Use Actions https://docs.oracle.com/javase/tutorial/uiswing/misc/action.html

Riccardo Cardin