GUI Tutorial 2. What did we do last time? Basic flow instance variables, set up in ctor, close...

35
GUI Tutorial 2

Transcript of GUI Tutorial 2. What did we do last time? Basic flow instance variables, set up in ctor, close...

Page 1: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

GUI Tutorial 2

Page 2: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

What did we do last time? Basic flow

instance variables, set up in ctor, close operation, size, visible

JFrame Event-driven programming

action listener for buttons Simple pop-up dialogs (JOptionPane)

Layout managers BorderLayout, FlowLayout, GridLayout

JPanel JTextField, JLabel, Jbutton, JCheckBox, JComboBox,

JRadioButton, JRadioGroup Borders and Fonts

Page 3: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

What will we do this time? Add actions to other controls JMenu/JMenuItem JTextArea Panel Communication Simple Drawing

Page 4: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add a menu Menus are added to the JFrame – not a JPanel Menus are added via setJMenuBar – not add The menu system consists of one JMenuBar

and one or more objects of type JMenu containing JMenuItem

In the JFrame constructor:JMenuBar menuBar = new JMenuBar();

setJMenuBar(menuBar);

menuBar.add(createFileMenu());

Page 5: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

The menuprivate JMenu createFileMenu()

{

JMenu menu = new JMenu("File");

menu.add(createFileExitItem());

return menu;

}

private JMenuItem createFileExitItem()

{

JMenuItem item = new JMenuItem("Exit");

class MenuItemListener implements ActionListener {

public void actionPerformed(ActionEvent e)

{

System.exit(0);

}

}

item.addActionListener(new MenuItemListener());

return item;

}

Page 6: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Panel Communication – Remember this?

Main panel

Control Panel

Page 7: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Panel communication Remember that communication between objects

can be thought of as message passing. For our program, we’ll create a DisplayPanel to display a summary of the choices. This panel should be updated every time a change is made to one of the panels.

DisplayPanelToFromPanel

Update thestatusPreferencePanel

WillDrivePanel

Page 8: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Panel Communication - UML

Page 9: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

First create a DisplayPanelpublic class DisplayPanel extends JPanel {

// Variables for message

private String name, fromCity,toCity, willDrive, smoker;

// display – multiple lines allowed in JTextArea

private JTextArea display;

public DisplayPanel()

{ // set some default values

name = "Someone";

fromCity = "Somewhere";

toCity = "Somewhere";

willDrive = "needs a ride";

smoker = "no smoking";

display = new JTextArea(2, 20);

display.setLineWrap(true); // uses multiple lines

display.setWrapStyleWord(true); // breaks on word boundaries

updateDisplay();

add(display);

}

Page 10: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Update methodprivate void updateDisplay()

{

display.setText(name + " " + willDrive + " from " + fromCity

+ " to " + toCity + " and prefers " + smoker);

}

} // end class

Page 11: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Let’s display Update the constructor of the JFrame

(CarpoolGUI)// Create DisplayPanel first

DisplayPanel dp = new DisplayPanel();

add(dp, BorderLayout.SOUTH);

// The rest has not changed… yet!

PreferencePanel pPanel = new PreferencePanel();

add(pPanel, BorderLayout.EAST);

ToFromPanel tfPanel = new ToFromPanel();

add(tfPanel, BorderLayout.CENTER);

WillDrivePanel wdPanel = new WillDrivePanel();

add(wdPanel, BorderLayout.NORTH);

Page 12: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

All panels now display

Now we need to add some action

Page 13: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Panel communication Other panels will need to be able to send

values to set the variables for this message. Use Eclipse to create setters for DisplayPanel.

Page 14: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

How can other panels update the display? Other panels will need to have access to the

DisplayPanel. How to do this? Send a reference into the constructor.

In the PreferencePanel:private DisplayPanel dp;

public PreferencePanel(DisplayPanel dp)

{

this.dp = dp;

. . .

Update all the panels.

notice use of this keyword

Page 15: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

How to access the DisplayPanel Update the constructor of the JFrame

(CarpoolGUI)// Create DisplayPanel first

DisplayPanel dp = new DisplayPanel();

add(dp, BorderLayout.SOUTH);

// Send it into other 3 panels

PreferencePanel pPanel = new PreferencePanel(dp);

add(pPanel, BorderLayout.EAST);

ToFromPanel tfPanel = new ToFromPanel(dp);

add(tfPanel, BorderLayout.CENTER);

WillDrivePanel wdPanel = new WillDrivePanel(dp);

add(wdPanel, BorderLayout.NORTH);

Page 16: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add action – radio button Need a radio listener

private class RadioListener implements ActionListener {

public void actionPerformed(ActionEvent e)

{

if (smokeButton.isSelected())

dp.setSmoker("smoking");

else

dp.setSmoker("no smoking");

}

}

Need to add listener to each buttonRadioListener listener = new RadioListener();

smokeButton.addActionListener(listener);

noSmokeButton.addActionListener(listener);

Page 17: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Need to call updateDisplay In DisplayPanel, the setters need to cause the

display to update, for example:public void setSmoker(String smoker) {

this.smoker = smoker;

updateDisplay();

}

Page 18: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add action - CheckBoxprivate class CheckboxListener implements ActionListener

{

public void actionPerformed(ActionEvent e)

{

if (willDriveCB.isSelected())

dp.setWillDrive("will drive");

else

dp.setWillDrive("needs a ride");

}

} Add the action listener to our check box:

willDriveCB.addActionListener(new CheckboxListener());

Page 19: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add action – Focus Listener The Java interpreter knows which component has

the “focus” – e.g., if the mouse is in the name field, it has focus. If you click on some other field, the name field “loses” focus.

FocusListener is an interface that can be used to respond to focus events.

Two methods must be defined: focusGained and focusLost. You must write both of these methods, even if you’re only interested in one type of event. The other method may have an empty body.

Be sure to include java.awt.event.*; (or specific classes)

Page 20: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Our focus listenerprivate class NameListener implements FocusListener

{

// We don’t care when we get focus

public void focusGained(FocusEvent e) {}

// When we lose focus, need to update the display

public void focusLost(FocusEvent e)

{

dp.setName(name.getText());

}

}

Add the focus listener to the name field. Since only one component uses this listener, we don’t bother creating a local variable.name.addFocusListener(new NameListener());

Page 21: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add action - ComboBox Fires both action events and item events.

Item events respond to any change of state, whether caused by the program or the user. Action events are called when the user interacts with the component.

For user actions, both events will be generated. You should only listen for one type of event. Typically you’re interested in the user’s actions, so use an action listener.

Page 22: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Add action - ComboBox We’ll use the same listener for both boxes. We’ll use

the ActionEvent getSource method to determine which one changed. private class ComboListener implements ActionListener {

public void actionPerformed(ActionEvent e)

{

if (e.getSource() == toCity)

dp.setToCity(toCity.getSelectedItem().toString());

else

dp.setFromCity(fromCity.getSelectedItem().toString());

}

}

Add the listener to both combo boses.ComboListener listener = new ComboListener();

fromCity.addActionListener(listener);

toCity.addActionListener(listener);

Page 23: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

That’s all, folks!

Page 24: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Eclipse Hint: Edit > Select All (Ctrl-A) Source > Correct Indentation (Ctrl-I)

All programs that are turned in for grading should be neatly formatted!

Page 25: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Drawing

Page 26: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

The Graphics class –Get the concept!From the Sun documentation:

The Graphics class is the abstract base class for all graphics contexts that allow an application to draw onto components that are realized on various devices, as well as onto off-screen images.

A Graphics object encapsulates state information needed for the basic rendering operations that Java supports. This state information includes the following properties: The Component object on which to draw. A translation origin for rendering and clipping coordinates. The current clip. The current color. The current font. The current logical pixel operation function (XOR or Paint). The current XOR alternation color (see setXORMode(java.awt.Color)).

Page 27: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Graphics class continued Sample methods:

drawImage drawLine/fillLine drawOval/fillOval drawRect/fillRect drawString setColor setFont

x: 0 ..

y 0 .. Example line from ~10 10 to ~20 20

Page 28: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Graphics class – VERY IMPORTANT Graphics is abstract, can’t call constructor directly Can be obtained by calling getGraphics on a component

Automatically created for the paintComponent method of any class that extends JComponent (either directly or indirectly)

paintComponent is called automatically when the component needs to be redrawn initial load when repaint() method called when screen is resized etc.

BEST STRATEGY: write the paintComponent method, call repaint() when you need to update the drawing

usually don’t need to!

Page 29: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Drawing – Basic Strategy1. As always, create a JFrame

2. Create a class that extends JComponent or JPanel to contain your drawing

3. Add that JPanel to your JFrame (often to the CENTER)

4. In that class, override paintComponent(Graphics g) method.

5. Inside the method, use draw commands as needed to create your image (e.g., g.drawLine(…))

6. paintComponent will be called automatically when the screen needs to be redrawn (e.g., when first displayed, if minimized then maximized, etc).

7. Inside paintComponent, call super.paintComponent for required housekeeping – IMPORTANT!

8. If you need to update the drawing, do not call paintComponent directly. Instead, call repaint(). Example: change player’s position in Clue, call repaint() on your board (either board.repaint(); or

repaint(); depending on what method is updating the player’s location).

Page 30: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Create a JPanelimport javax.swing.*;

import java.awt.*;

public class DrawPanel extends JPanel {

public void paintComponent(Graphics g)

{

super.paintComponent(g);

g.setColor(Color.BLUE);

g.drawRect(10, 15, 20, 20);

}

}

Remember this for housekeeping (e.g., background)

Page 31: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Create a frame, add the componentpublic class DrawFrame extends JFrame {

private DrawPanel drawPanel;

public DrawFrame()

{

drawPanel = new DrawPanel();

// paintComponent will automatically be

// called 1 time

add(drawPanel, BorderLayout.CENTER);

setSize(300, 300);

}

public static void main(String[] args) {

DrawFrame frame = new DrawFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

Page 32: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Let’s make some changespublic class DrawPanel extends JPanel

{

private int x, y;

public DrawPanel()

{

x = 10;

y = 15;

}

public void paintComponent(Graphics g)

{

super.paintComponent(g);

g.setColor(Color.BLUE);

g.drawRect(x, y, 20, 20);

}

public void translate(int dx, int dy)

{

x += dx;

y += dy;

// Must include this to see changes

repaint();

}

}

Page 33: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

And call it from main…

public void updateDrawing(int dx, int dy)

{

drawPanel.translate(dx, dy);

}

public static void main(String[] args) {

DrawFrame frame = new DrawFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

// This will cause rectangle to display in new location

frame.updateDrawing(100, 100);

}

Page 34: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Let’s put in a delaypublic void updateDrawing(int dx, int dy)

{

this.dx = dx; // need to add instance variables

this.dy = dy;

// 1000 millisecond delay

Timer t = new Timer(1000, new TimerListener());

t.start();

}

private class TimerListener implements ActionListener {

public void actionPerformed(ActionEvent e) {

drawPanel.translate(dx, dy);

}

}

Be sure to get javax.swing.Timer

Page 35: GUI Tutorial 2. What did we do last time?  Basic flow  instance variables, set up in ctor, close operation, size, visible  JFrame  Event-driven programming.

Complete Programpublic class DrawFrame extends JFrame {

private DrawPanel drawPanel;

private int dx, dy;

public DrawFrame() {

drawPanel = new DrawPanel(10, 15);

add(drawPanel, BorderLayout.CENTER);

setSize(300, 300); }

public void updateDrawing(int dx, int dy) {

this.dx = dx;

this.dy = dy;

Timer t = new Timer(1000, new TimerListener());

t.start(); }

private class TimerListener implements ActionListener {

public void actionPerformed(ActionEvent e) {

drawPanel.translate(dx, dy); } }

public static void main(String[] args) {

DrawFrame frame = new DrawFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

frame.updateDrawing(5, 10);

}

}

public class DrawPanel extends JPanel {

private int x, y;

public DrawPanel(int x, int y) {

this.x = x;

this.y = y;

}

public void paintComponent(Graphics g) {

super.paintComponent(g);

g.setColor(Color.BLUE);

g.drawRect(x, y, 20, 20);

System.out.println("Called paint component");

}

public void translate(int dx, int dy) {

x += dx;

y += dy;

// Must include this to see changes

repaint();

}

}