Java Graphics Programming
-
Upload
riccardo-cardin -
Category
Software
-
view
1.684 -
download
1
Transcript of 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]
2Programmazione concorrente e distribuita
SUMMARY Introducing Swing Main components Layout management Event handling
Riccardo Cardin
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
4Programmazione concorrente e distribuita
INTRODUCTION
Riccardo Cardin
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
6Programmazione concorrente e distribuita
INTRODUCTION Swing Ocean look-and-feel
Riccardo Cardin
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); }}
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!!!
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();
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 }}
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
12Programmazione concorrente e distribuita
MAIN COMPONENTS
Riccardo Cardin
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
14Programmazione concorrente e distribuita
LAYOUT MANAGEMENT
Riccardo Cardin
Container class stores references to
itself
15Programmazione concorrente e distribuita
LAYOUT MANAGEMENT
Riccardo Cardin
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
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
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); }
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
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); }
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));
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; }
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
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
25Programmazione concorrente e distribuita
LAYOUT MANAGEMENT
Riccardo Cardin
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
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
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
29Programmazione concorrente e distribuita
EVENT HANDLING
Riccardo Cardin
30Programmazione concorrente e distribuita
EVENT HANDLING
Riccardo Cardin
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);
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);
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); } }}
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); } });}
35Programmazione concorrente e distribuita
EVENT HANDLING
Riccardo Cardin
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");
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);}
38Programmazione concorrente e distribuita
EVENT HANDLING Adapter pattern
Class adapter
Object adapter
Riccardo Cardin
Target interfaceSource interface
Adapt source interface to target
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());
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
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
42Programmazione concorrente e distribuita
CONCLUSIONS
Riccardo Cardin
43Programmazione concorrente e distribuita
EXAMPLES
Riccardo Cardin
https://github.com/rcardin/pcd-snippets
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