Assignment 8: Swingin’ with Callbacks Interfaces are fundamental to systems that
ID: 3599647 • Letter: A
Question
Assignment 8: Swingin’ with Callbacks Interfaces are fundamental to systems that use callbacks. Remember, these are objects that we set up to ’call back’ later, when the time is right. In java’s GUI package javax.swing, we build user interfaces (not Java interfaces) out of windows and buttons. To couple our custom code with these standard GUI elements, we must implement the interfaces expected by them. When set up correctly, our code is the thing that is ’called back’ when the button is pressed or other event occurs. For this lab, we will be implementing callback classes (in Swing-terminology, listeners) and adding them to Swing components. We will specifically listen for button presses and mouse activity. We often use inner classes for callbacks, since these classes are usually relevant to only a small section of code. In this assignment, all of our listeners will be written as inner classes in the main() method. 1 Your job I’ve provided java code called SwingLab. You should compile and run this code before you make any changes to it. When run, this code sets up a panel with 3 buttons labeled Red, Yellow, and Blue. This program will compile and run without any modifications, but the buttons do nothing. Your job is to make these buttons change the panel color to the color named on the button. You’re also going to print to System.out when the mouse enters and leaves a button’s area: The mouse has entered the yellow button area. The mouse has exited the yellow button area. 2 How to do it You will need to provide implementations of the java.awt interfaces ActionListener and MouseListener. Here’s an example: class RedButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { panel.setBackground(Color.RED); } } ActionListener redListener = new RedButtonListener(); bRed.addActionListener(redListener); Please note that MouseListener and ActionListener are interfaces that already exist and are imported – you do not need to write them. Also notice how RedButtonListener is referring to panel. This assumes you are including this class as an inner class directly in the main method, because panel is a local variable in the main method. (Notice that panel must be declared final – this does not mean that the object referred to by panel is a constant – it means that your panel variable will always refer to the same object.) Notice also how this class is referring to Color.RED. You can refer to all the colors needed for this assignment in a similar way. Read more about it in the Java documentation for the Color class. Here are the interfaces you will need to implement in your callbacjs. A single class can implement multiple interfaces! Do not cut and paste this code – it already exists in the Swing package. public interface ActionListener { public void actionPerformed(ActionEvent event); } public interface MouseListener { public void mouseEntered(MouseEvent event); public void mouseExited(MouseEvent event); public void mousePressed(MouseEvent event); public void mouseReleased(MouseEvent event); public void mouseClicked(MouseEvent event); } To implement MouseListener, you have to implement all five of those methods. To ignore a mouse event, provide an “empty” implementation of the corresponding interface method (a method with empty curly braces for a body) All of your implemented methods will probably just ignore the argument that is passed in. 3 Bonus There are two possibilities of bonus points for this lab. If you do either or both of these, make sure to make this clear when you submit your assignment. 1. 10 pts Implement the requirements using only one inner class. You can use more inner classes if needed to “do something cool.” You can instantiate this inner class multiple times. 2. 10 pts Usea javax.swing.Timer to reset the panel color 5 seconds after you change it. These timers use ActionListener like the buttons. 2 4 Turn In Make sure your name appears in comments at the top of every java file. Zip up your project directory and submit the zip file via blackboard.
Explanation / Answer
the code is correct and modified
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.GridLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JComponent;
public class SwingLab
{
// frame properties
private static final int FRAME_WIDTH = 400; private static final int FRAME_HEIGHT = 400;
public static void main(String[] args)
{
// Instantiate a frame (the main window)
JFrame frame = new JFrame();
// The buttons (one for each color)
JButton bRed = new JButton("Red");
JButton bYellow = new JButton("Yellow");
JButton bBlue = new JButton("Blue");
// Here we create a panel consisting of other panels (layed out in a
// Grid) to support the buttons and "Art" instance
final JPanel container = new JPanel(new GridLayout(2,1));
final JPanel panel = new JPanel(new GridLayout(1,1));
final JPanel buttonPanel = new JPanel( new GridLayout(3,1) );
// An instance of a special class for you to play with (Art is defined
// below)
Art artBox=new Art();
panel.add(artBox);
// add the buttons to the panel
buttonPanel.add(bRed);
buttonPanel.add(bYellow);
buttonPanel.add(bBlue);
// put the panels together and add them to the frame
container.add(panel);
container.add(buttonPanel);
frame.add(container);
/* YOUR CODE GOES HERE */
// declare your listener classes and add them to the buttons
// here.
// you are going to call addActionListener and
// addMouseListener for each button
// you want to deal with the JPanel named "panel" declared
// above
/* END YOUR CODE */
// Show the frame
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
// The code below is to give advanced users something to play
// with. Clicking in the upper pane of the window will cause it
// to redraw the lines, centering on the location you clicked.
public static class Art extends JComponent
{
// the center of the lines that are drawn
private int y;
private int x;
// constructor
public Art()
{
x=200;
y=100;
// this trivial MouseListener implementation handles
// clicks inside the "art box"
class ClickListener implements MouseListener
{
private Art a;
// we instantiate a ClickListener with an art object,
// so we can update the center position when a mouse
// event occurs
public ClickListener(Art a)
{
this.a = a;
}
public void mouseEntered(MouseEvent event) { }
public void mouseExited(MouseEvent event) { }
public void mousePressed(MouseEvent event)
{
a.setPoint(event.getX(), event.getY());
a.repaint();
}
public void mouseReleased(MouseEvent event) { }
public void mouseClicked(MouseEvent event) { }
}
ClickListener cListener = new ClickListener(this);
this.addMouseListener(cListener);
}
// this is the JComponent method that handles drawing the lines
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// Create the four lines
Line2D.Double l1 = new Line2D.Double(0, 0, x, y);
Line2D.Double l2 = new Line2D.Double(0, getHeight(), x, y);
Line2D.Double l3 = new Line2D.Double(getWidth(), 0, x, y);
Line2D.Double l4 = new Line2D.Double(getWidth(), getHeight(), x, y);
// Draw the lines
g2.draw(l1);
g2.draw(l2);
g2.draw(l3);
g2.draw(l4);
}
public void setPoint(int x, int y)
{
this.x = x;
this.y = y;
}
}
}