Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Linking a button click to a mouse event?

Hi,

I'm pretty new to Java, and as such still struggle from basic problems.

My problem is how to do I link an action event from a button to a mouse event. This is being used in a program to allow users to draw a square, oval etc on a canvas by clicking their mouse button. They choose which shape to draw from the corresponding button. My problem is that the button is not reflecting the mouse click and vice-versa.

My code so far is as follows,

From the DrawToolCanvas class:

import java.awt.*;
import java.awt.event.*;

public class DrawToolCanvas extends Canvas implements MouseListener, ActionListener
{


public void paint(Graphics g)
{
}

public void actionPerformed(ActionEvent event)
{ if (event.getActionCommand().equals("square"))
square();
else if (event.getActionCommand().equals("circle"))
circle();
}

public void square()
{ Graphics g = getGraphics();
int x=e.getX(), y=e.getY();
g.setColor(Color.red);
g.fillRect( x, y, x = 40, y = 40 );
g.setColor(Color.black);
}

public void circle()
{ Graphics g = getGraphics();
int x=getX(), y=getY();
g.setColor(Color.blue);
g.fillOval( x, y, x = 40, y = 40 );
g.setColor(Color.black);

}

public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

}

Any help would be gratefully appreciated!

Many thanks :)
[1795 byte] By [fulcanelli] at [2007-11-11 7:12:56]
# 1 Re: Linking a button click to a mouse event?
You don't hava a button which you can link the event with.

You are basically drawing shapes on the canvas. I dont' think it is possible to do it like that, I might be wrong.

JButton square = new JButton("Square");

square.addMouseListener(new MouseListener()
{

public void actionPerformed(MouseListener I)
{
System.out.print("Clicked on Square");
}
});
Wizard1988 at 2007-11-11 22:39:00 >
# 2 Re: Linking a button click to a mouse event?
You can implement it like this:

/**
* DrawTool Canvas (awt)
*/

import java.awt.*;
import java.awt.event.*;

public class DrawToolAWT extends Canvas
implements MouseListener, ActionListener {

String drawType="square";
Point lastClickPoint=null;

public void paint(Graphics g) {
update(g);
}
public void update(Graphics g) {
System.out.println("update");
Color c=g.getColor();
coverBackground(g);
if (lastClickPoint==null) {
g.setColor(Color.black);
g.drawString("Click canvas first",20,20);
} else {
if (drawType.equals("square")) {
drawSquare(g);
}
else if (drawType.equals("circle")) {
drawCircle(g);
}
}
g.setColor(c);
}

private void coverBackground(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,getWidth(),getHeight());
}

public void actionPerformed(ActionEvent event) {
System.out.println("actionPerformed: "+event.getActionCommand());
if (event.getActionCommand().equals("square"))
drawType="square";
else if (event.getActionCommand().equals("circle"))
drawType="circle";
repaint();
}
public void mouseReleased(MouseEvent e) {
lastClickPoint=e.getPoint();
repaint();
}
public void drawSquare(Graphics g) {
g.setColor(Color.red);
g.fillRect(lastClickPoint.x, lastClickPoint.y, 40, 40);

}

public void drawCircle(Graphics g) {
g.setColor(Color.blue);
g.fillOval(lastClickPoint.x, lastClickPoint.y, 40, 40);

}
public static void main(String[] args) {
Frame f=new Frame("DrawTool");
f.setLayout(new BorderLayout());
DrawToolSwing dts=new DrawToolSwing();
Button btn1=new Button("circle");
Button btn2=new Button("square");
btn1.addActionListener(dts);
btn2.addActionListener(dts);
dts.addMouseListener(dts);

dts.add(btn1);
dts.add(btn2);
Panel btnPan=new Panel();
btnPan.add(btn1);
btnPan.add(btn2);

f.add(dts,BorderLayout.CENTER);
f.add(btnPan,BorderLayout.SOUTH);

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setBounds(20,20,500,400);
f.setVisible(true);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

}

The problem is that these drawings are stored nowhere else but in the display
graphical context, so if you minimize/restore the app window, or cover it
partially the drawing will disappear. You will either have to store the drawing
shapes in a list and/or use double buffering for the graphics.
sjalle at 2007-11-11 22:40:05 >
# 3 Re: Linking a button click to a mouse event?
Hi,

Thanks for the reply. The buttons are specified in a seperate class, called DrawToolFrame. Here is the code for both classes,

1. DrawToolFrame class:

import java.awt.*;
import java.awt.event.*;

public class DrawToolFrame extends Frame
implements WindowListener
{
DrawToolCanvas myCanvas;

public DrawToolFrame()
{
setTitle("Draw Tool Frame");
addWindowListener(this);
Button square, circle;
Panel myPanel = new Panel();
square = new Button("square"); square.setActionCommand("square");
circle = new Button("circle"); circle.setActionCommand("circle");
myPanel.add(square); myPanel.add(circle);
add("South", myPanel);
DrawToolCanvas myCanvas = new DrawToolCanvas();
add("Center", myCanvas);
square.addMouseListener(myCanvas);
circle.addMouseListener(myCanvas);
}


public void windowClosing(WindowEvent event) { System.exit(0); }
public void windowOpened(WindowEvent event) {}
public void windowIconified(WindowEvent event) {}
public void windowDeiconified(WindowEvent event) {}
public void windowClosed(WindowEvent event) {}
public void windowActivated(WindowEvent event) {}
public void windowDeactivated(WindowEvent event) {}

}

2. DrawToolCanvas class:

import java.awt.*;
import java.awt.event.*;

public class DrawToolCanvas extends Canvas implements MouseListener, ActionListener
{
MouseEvent e;


public void paint(Graphics g)
{
}

public void actionPerformed(ActionEvent event)
{ if (event.getActionCommand().equals("square"))
square();
else if (event.getActionCommand().equals("circle"))
circle();
}

public void square()
{ Graphics g = getGraphics();
int x=e.getX(), y=e.getY();
g.setColor(Color.black);
g.fillRect( x, y, x = 40, y = 40 );
g.setColor(Color.black);

}

public void circle()
{ Graphics g = getGraphics();
int x=e.getX(), y=e.getY();
g.setColor(Color.blue);
g.fillOval( x, y, x = 40, y = 40 );
g.setColor(Color.black);

}

public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseClicked(MouseEvent e)
{
}

}

I'm getting really lost with this at the moment. Any help? :)
fulcanelli at 2007-11-11 22:40:58 >
# 4 Re: Linking a button click to a mouse event?
sjalle, thank you for your reply.

I have tried implementing the DrawToolCanvas class as recommended, but the program still doesn't display any image when the user clicks on the canvas.

Maybe my implementation of DrawToolFrame is incorrect. I'm really getting frustrated with this. Java does not seem to be my type of language.

Anyway, the code for the DrawToolFrame class is as follows:

import java.awt.*;
import java.awt.event.*;

public class DrawToolFrame extends Frame
implements WindowListener
{
DrawToolCanvas myCanvas;

public DrawToolFrame()
{
setTitle("Draw Tool Frame");
addWindowListener(this);
Button square, circle;
Panel myPanel = new Panel();
square = new Button("square"); square.setActionCommand("square");
circle = new Button("circle"); circle.setActionCommand("circle");
myPanel.add(square); myPanel.add(circle);
add("South", myPanel);
DrawToolCanvas myCanvas = new DrawToolCanvas();
add("Center", myCanvas);
square.addMouseListener(myCanvas);
circle.addMouseListener(myCanvas);
}


public void windowClosing(WindowEvent event) { System.exit(0); }
public void windowOpened(WindowEvent event) {}
public void windowIconified(WindowEvent event) {}
public void windowDeiconified(WindowEvent event) {}
public void windowClosed(WindowEvent event) {}
public void windowActivated(WindowEvent event) {}
public void windowDeactivated(WindowEvent event) {}

}

Again, any help would be really appreciated. :)
fulcanelli at 2007-11-11 22:41:58 >
# 5 Re: Linking a button click to a mouse event?
My first post here was wrong, I have edited it, sorry about that.

But, I have a swing version also here. Notice that I when I use this I am
able to add components (buttons) to the drawingArea.

Also, check out the oddities w. the AWT version. Among other things,
the println in the actionPerformed method is not happening, at least not on
my machine, although the method obviously is invoked. :confused:

So, I'd say; trash the Canvas and forget it. Use JPanel, not only does is
"work" better, it looks better too.

/**
* DrawTool JPanel (swing)
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawToolSwing extends JPanel
implements MouseListener, ActionListener {

String drawType="square";
Point lastClickPoint=null;

public void paintComponent(Graphics g) {
Color c=g.getColor();
coverBackground(g);
if (lastClickPoint==null) {
g.setColor(Color.black);
g.drawString("Click canvas first",20,20);
} else {
if (drawType.equals("square")) {
drawSquare(g);
}
else if (drawType.equals("circle")) {
drawCircle(g);
}
}
g.setColor(c);
}

private void coverBackground(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,getWidth(),getHeight());
}

public void actionPerformed(ActionEvent event) {
System.out.println("actionPerformed: "+event.getActionCommand());
if (event.getActionCommand().equals("square"))
drawType="square";
else if (event.getActionCommand().equals("circle"))
drawType="circle";
repaint();
}
public void mouseReleased(MouseEvent e) {
lastClickPoint=e.getPoint();
}
public void drawSquare(Graphics g) {
g.setColor(Color.red);
g.fillRect(lastClickPoint.x, lastClickPoint.y, 40, 40);
g.setColor(Color.black);
}

public void drawCircle(Graphics g) {
g.setColor(Color.blue);
g.fillOval(lastClickPoint.x, lastClickPoint.y, 40, 40);
g.setColor(Color.black);

}
public static void main(String[] args) {
JFrame f=new JFrame("DrawTool");
f.getContentPane().setLayout(new GridLayout());
DrawToolSwing dts=new DrawToolSwing();
JButton btn1=new JButton("circle");
JButton btn2=new JButton("square");
btn1.addActionListener(dts);
btn2.addActionListener(dts);
dts.addMouseListener(dts);
dts.add(btn1);
dts.add(btn2);
f.getContentPane().add(dts,null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(20,20,500,400);
f.setVisible(true);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

}
sjalle at 2007-11-11 22:43:02 >
# 6 Re: Linking a button click to a mouse event?
Hi sjalle,

Thank you so much for your help with this problem. One last question though.

Any idea how I can keep the shapes on the screen after each time a user clicks the canvas. At the moment, they are simply being replaced with a new shape.

Many thanks
fulcanelli at 2007-11-11 22:44:01 >
# 7 Re: Linking a button click to a mouse event?
I have isolated the drawing in a class, DrawShape , and the drawpanel is using an
ArrayList for storing DrawShape instances. The drawpanel loops this
list for every paint job and "tells" each DrawShape to draw itself.

/**
* DrawTool JPanel (swing)
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

class DrawShape {
public String type=null;
public Point location=null;
public DrawShape(String type, Point location) {
this.type = type;
this.location = location;
}

public void draw(Graphics g) {
Color c = g.getColor();
if (type.equals("square")) {
drawSquare(g);
}
else if (type.equals("circle")) {
drawCircle(g);
}
g.setColor(c);
}
private void drawSquare(Graphics g) {
g.setColor(Color.red);
g.fillRect(location.x, location.y, 40, 40);
g.setColor(Color.black);
}

private void drawCircle(Graphics g) {
g.setColor(Color.blue);
g.fillOval(location.x, location.y, 40, 40);
g.setColor(Color.black);

}

}
public class DrawToolSwing2 extends JPanel
implements MouseListener, ActionListener {

private ArrayList drawList=new ArrayList();
String drawType="square";
Point lastClickPoint=null;

public void paintComponent(Graphics g) {
coverBackground(g);
for (int i=0; i<drawList.size(); i++) {
DrawShape shape=(DrawShape)drawList.get(i);
shape.draw(g);
}
}

private void coverBackground(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,getWidth(),getHeight());
}

public void actionPerformed(ActionEvent event) {
System.out.println("actionPerformed: "+event.getActionCommand());
if (event.getActionCommand().equals("square"))
drawType="square";
else if (event.getActionCommand().equals("circle"))
drawType="circle";
repaint();
}
public void mouseReleased(MouseEvent e) {
drawList.add(new DrawShape(drawType, e.getPoint()));
repaint();
System.out.println("list: "+drawList.size());
}

public static void main(String[] args) {
JFrame f=new JFrame("DrawTool");
f.getContentPane().setLayout(new GridLayout());
DrawToolSwing2 dts=new DrawToolSwing2();
JButton btn1=new JButton("circle");
JButton btn2=new JButton("square");
btn1.addActionListener(dts);
btn2.addActionListener(dts);
dts.add(btn1);
dts.add(btn2);
dts.addMouseListener(dts);
f.getContentPane().add(dts,null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(20,20,500,400);
f.setVisible(true);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

}
sjalle at 2007-11-11 22:45:10 >
# 8 Re: Linking a button click to a mouse event?
Hi,

sjalle, you are a genius. Thank you so much for all your help. You are also right about swing. The result is alot better than AWT.

Quick bit of advice. What's the best way to add a couple of buttons to allow the user to increase or decrease the size of the shapes when they click on the canvas. ie: when they click increase, the subsequent circles or squares will be larger on the canvas.

Thanks!!! :WAVE:
fulcanelli at 2007-11-11 22:46:07 >
# 9 Re: Linking a button click to a mouse event?
.. than to just post the code. The changeWidth/Height methods are not
used yet, I thought maybe you could do that :)

/**
* DrawTool JPanel (swing)
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class DrawShape {
public String type=null;
public Point location=null;
private int width=40;
private int height=40;

public DrawShape(String type, Point location,
int width, int height ) {
this.type = type;
this.location = location;
this.width=width;
this.height=height;
}

public DrawShape(String type, Point location) {
this.type = type;
this.location = location;
}

public void draw(Graphics g) {
Color c = g.getColor();
if (type.equals("square")) {
drawSquare(g);
}
else if (type.equals("circle")) {
drawCircle(g);
}
g.setColor(c);
}
public void changeWidth(int change) {
if (width+change <= 0) return;
width+=change;
}
public void changeHeight(int change) {
if (height+change <= 0) return;
height+=change;
}

private void drawSquare(Graphics g) {
g.setColor(Color.red);
g.fillRect(location.x, location.y, width, height);
g.setColor(Color.black);
}

private void drawCircle(Graphics g) {
g.setColor(Color.blue);
g.fillOval(location.x, location.y, width, height);
g.setColor(Color.black);

}

}
public class DrawToolSwing2 extends JPanel
implements MouseListener, ActionListener {

private int shapeWidth=40;
private int shapeHeigth=40;
private int shapeStep=5;

private ArrayList drawList=new ArrayList();
private String drawType="square";
private Point lastClickPoint=null;

JButton circleBtn=new JButton("circle");
JButton squareBtn=new JButton("square");
JButton biggerBtn=new JButton("Bigger");
JButton smallerBtn=new JButton("Smaller");

public DrawToolSwing2 () {
add(circleBtn);
add(squareBtn);
add(biggerBtn);
add(smallerBtn);

circleBtn.addActionListener(this);
squareBtn.addActionListener(this);
biggerBtn.addActionListener(this);
smallerBtn.addActionListener(this);
addMouseListener(this);

}

public void paintComponent(Graphics g) {
coverBackground(g);
for (int i=0; i<drawList.size(); i++) {
DrawShape shape=(DrawShape)drawList.get(i);
shape.draw(g);
}
}

private void coverBackground(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,getWidth(),getHeight());
}

public void actionPerformed(ActionEvent event) {

if (event.getActionCommand().equals("square")) {
drawType = "square";
}
else if (event.getActionCommand().equals("circle")) {
drawType = "circle";
}
else if (event.getActionCommand().equals("Bigger")) {
shapeWidth += shapeStep;
shapeHeigth += shapeStep;
}
else if (event.getActionCommand().equals("Smaller")) {
if (shapeWidth-shapeStep > 0) {
shapeWidth -= shapeStep;
}
if (shapeHeigth-shapeStep > 0) {
shapeHeigth -= shapeStep;
}
}

repaint();
}
public void mouseReleased(MouseEvent e) {
DrawShape dS=new DrawShape(drawType, e.getPoint(),
shapeWidth, shapeHeigth);

drawList.add(dS);
repaint();

}

public static void main(String[] args) {
JFrame f=new JFrame("DrawTool");
f.getContentPane().setLayout(new GridLayout());
DrawToolSwing2 dts=new DrawToolSwing2();

f.getContentPane().add(dts,null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBounds(20,20,500,400);
f.setVisible(true);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

}
sjalle at 2007-11-11 22:47:10 >
# 10 Re: Linking a button click to a mouse event?
Hi,

sjalle, thank you for all your help with this problem.

Have a great weekend!! :WAVE:
fulcanelli at 2007-11-11 22:48:05 >