BlueJ: Cannot find symbol - method addMouseMotionListener - java

I'm trying to make a drawing program that will draw circles onto a canvas using the mouseDragged() method from MouseMotionListener. Inside my init() method, I put in this.addMouseMotionListener(this) and got this error message:
Cannot find symbol - method addMouseMotionListener(Canvas).
I am trying to make it so that every time the mouse is dragged, the Brush (which is just a circle), will draw onto the DrawingBoard which has a Canvas on it
Here is the code for the DrawingBoard:
import java.awt.*;
import java.awt.geom.*;
import java.awt.PointerInfo;
import java.awt.MouseInfo;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;
public class DrawingBoard implements MouseMotionListener
{
private Canvas myCanvas;
private Brush myBrush;
private PointerInfo a = MouseInfo.getPointerInfo();
private Point p = a.getLocation();
private int x = (int)p.getX();
private int y = (int)p.getY();
private Brush b1 = new Brush(x, y, 10, Color.red, myCanvas);
// instance variables - replace the example below with your own
public void init() {
this.addMotionListener(this);
}
public DrawingBoard(int canvasSizeX, int canvasSizeY)
{
myCanvas = new Canvas("Drawing Board", canvasSizeX, canvasSizeY);
myCanvas.setVisible(true);
myCanvas.setForegroundColor(Color.lightGray);
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
b1.draw();
}
The code for the Canvas can be found here:
http://pastebin.com/RzMpkKhy

Your DrawingBoard needs to extend some kind of AWT/Swing-Component like Frame, JFRame, Panel etc, that contains the method addMouseMotionListener(). Because your not doing this, the compiler assumes that addMouseMotionListener() is a method you defined somewhere in your class. But he can't find it (because it doesn't exist) so it throws an error. Try adding this method to the Canvas code:
public void addMouseMotionListener(MouseMotionListener ml){
canvas.addMouseMotionListener(ml);
}
and put
myCanvas.addMouseMotionListener(this);
into your init() method.
Because the Canvas you are using is a custom class (there is another Canvas in the java.awt package), you have to alter its code to support user input (it doesn't look like it was designed to do this).

Related

Images no displaying in my java program

Recently i decided to start learning how to make 2D games With JAVA ( eclipse ) so i found a tutorial online that shows how to make superMari game with java, i wrote the same code he wrote and i followed step by step what he did, which wasn't a big thing to talk about, unfortunately he's code shows, after excuting, a window with two images in it while mine shows just the window with no images, i ensure you that i imported the two images and put them in one package to avoid all kind of problems but it still shows nothing.
my code has two classes, "main" and "Scene", here it is, hopefully someone will find a solution for me, thank you guys!
Main.java :
package AiMEUR.AMiN.jeu;
import javax.swing.JFrame;
public class Main {
public static Scene scene;
public static void main(String[] args) {
JFrame fenetre = new JFrame("Naruto in mario World!!");
fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fenetre.setSize(700, 360);
fenetre.setLocationRelativeTo(null);
fenetre.setResizable(false);
fenetre.setAlwaysOnTop(true);
scene = new Scene();
fenetre.setContentPane(scene);
fenetre.setVisible(true);
}
}
Scene.java :
package AiMEUR.AMiN.jeu;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Scene extends JPanel{
private ImageIcon icoFond;
private Image imgFond1;
private ImageIcon icoMario;
private Image imgMario;
private int xFond1;
public Scene(){
super();
this.xFond1 = -50;
icoFond = new ImageIcon(getClass().getResource("/Images/fond.gif"));
this.imgFond1 = this.icoFond.getImage();
icoMario = new ImageIcon(getClass().getResource("/Images/1.png"));
this.imgMario = this.icoMario.getImage();
// paintComponent(this.getGraphics());
}
public void paintCompenent(Graphics g){
super.paintComponent(g);
Graphics g2 = (Graphics2D)g;
g2.drawImage(this.imgFond1, this.xFond1, 0, null);
g2.drawImage(imgMario, 300, 245, null);
}
}
You have not named the paintComponent method correctly, and therefore it is not being overridden.
The correct name is paintComponent not paintCompenent:
public class Example extends JPanel {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
}
}
You can determine the loading status of an ImageIcon by doing something like this:
public Scene(){
super();
this.xFond1 = -50;
icoFond = new ImageIcon(getClass().getResource("/Images/fond.gif"));
int status = icoFond.getImageLoadStatus();
switch (status) {
case (MediaTracker.COMPLETE): {
System.out.println("icoFond image has successfully loaded");
}
case (MediaTracker.ERRORED): {
System.out.println("The icoFond image didn't load successfully");
// probably because the image isn't actually at "/Images/fond.gif"
}
}
this.imgFond1 = this.icoFond.getImage();
icoMario = new ImageIcon(getClass().getResource("/Images/1.png"));
this.imgMario = this.icoMario.getImage();
// paintComponent(this.getGraphics());
}

Java painting program giving many errors

I want to make a simple painting program. So,when you drag your mouse a line will draw in a GUI. The problem is when the user drags the mouse, it will paint automatically, but my code doesn't work. Can someone please tell me how do this? Sorry for my English and if you don't understand my question, look at my code maybe you will than.
My main class:
import javax.swing.JFrame;
public class MainClass {
public static void main(String args[]){
tuna kip = new tuna();
kip.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
kip.setSize(800,600);
kip.setVisible(true);
}
}
This is my other class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class tuna extends JFrame {
JPanel jpanel = new JPanel();
public tuna(){
super("Painting Program");
jpanel.setBackground(Color.WHITE);
add(jpanel);
hand handler = new hand();
jpanel.addMouseListener(handler);
jpanel.addMouseMotionListener(handler);
}
private class hand implements MouseListener ,MouseMotionListener { //THE ERRORS START TO APPEAR HERE
public void mouseDragged(MouseEvent event){
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(event.getX(), event.getY(), 5, 5);
}
}
}
}
When I try to run the code I get too much error messages:
You mean when you try to compile the code you get compile errors.
class hand implements MouseListener ,MouseMotionListener
Your class does not implement all the methods in those listeners. You only implement one method.
Read the section from the Swing tutorial on How to Write a MouseMotionListener for a working example.
If you only care about the mouseDragged() method then you only need to implement the MouseMotionListener.
Or as a simpler solution you can extend MouseMotionAdapter. This class implements all the methods of the MouseMotionListener so you only need to override the methods you want to change. The tutorial also discusses adapters.
Finally class names SHOULD start with an upper case character. Look at the Java API and you will notice this. Follow the Java conventions and don't make up your own.
Yes, there are so many issues in your codes. I just edited it and make it runnable at least. Just study and experiment on it. I hope you will learn something out of this even if I don't explain all of the changes.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class tuna extends JFrame {
int x, y, w, h;
MyPanel jpanel = new MyPanel();
public tuna(){
super("Painting Program");
setLayout(new BorderLayout());
jpanel.setBackground(Color.WHITE);
add(jpanel);
hand handler = new hand();
jpanel.addMouseListener(handler);
jpanel.addMouseMotionListener(handler);
}
private class hand implements MouseListener , MouseMotionListener { //THE ERRORS START TO APPEAR HERE
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
x=e.getX();
y=e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
w = e.getX() - x;
h = e.getY() - y;
jpanel.repaint();
}
public void mouseMoved(MouseEvent e) {
}
}
class MyPanel extends JPanel {
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(x, y, w, h);
}
}
}

Drawing lines and deleting lines

I am trying to create a program that allows the user to drag and draw lines and also delete the lines after it have been drawn. Is there any ways i can do it? I have the code that draws the line but i am not sure how i could delete the lines after i have drawn it. Im looking to click any of the lines drawn and delete it with the delete button.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Drawing {
public Drawing() {
JFrame jf=new JFrame("Free Hand Drawing Example");
Board draw=new Board();
jf.add(draw);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(600,500);
jf.setVisible(true);
}
public static void main(String a[]){
new Drawing();
}
}
class Board extends JPanel implements MouseListener,MouseMotionListener {
ArrayList<pts> list = new ArrayList<pts>();
Point start,end;
public Board() {
start=null; /*Initializing*/
end=null;
//this.setBackground(Color.BLACK);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
#Override
public void paint(Graphics g)
{ Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
super.paint(g2);
//g.setColor(Color.BLACK);
for (pts p : list)
g.drawLine((int)p.getStart().getX(), (int)p.getStart().getY(), (int)p.getEnd().getX(), (int)p.getEnd().getY());
if(start!=null)
{
g.drawLine(start.x,start.y,end.x,end.y);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent me) {
start = me.getPoint();
}
#Override
public void mouseReleased(MouseEvent me) {
end = me.getPoint();
pts pt = new pts(start,end);
list.add(pt);
repaint();
for(pts p : list)
{
System.out.println(p.getStart()+""+p.getEnd());
}
start = null;
end = null;
}
#Override
public void mouseDragged(MouseEvent me) {
end = me.getPoint();
repaint();
}
#Override
public void mouseMoved(MouseEvent arg0) {}
}
class pts{
Point start = null;
Point end = null;
public pts(Point start, Point end){
this.start = start;
this.end = end;
}
public Point getStart(){
return this.start;
}
public Point getEnd(){
return this.end;
}
}
There is more than one way to go about this, but one simple approach would be to add a 'delete' button with an ActionListener that clears out the list of points you have when the button is pressed. You could also associate the clearing action with something like a MouseDragged event, but that doesn't seem very user friendly.
UPDATE:
So, to delete the line when the user clicks on it, you could use a simple function like this one:
public boolean intersects(Point linePoint1,
Point linePoint2,
Point usersClickPoint) {
return new Line2D.Float(linePoint1, linePoint2).
ptLineDist(usersClickPoint) <= 0.01;//some margin of error
}
in your MousePressed method.
Side Note: The way you've chosen to interpret the mouse events is a bit strange. You record the first point on MousePressed, and the second one on MouseReleased. Why not use MouseClicked and simply keep track of the first and second clicks when drawing the line?
One approach would be to create a Line object for each line your user draws and have the object store the locations on the screen where the line is drawn. Then when in delete mode, have an onClickListener that will select a line based upon the coordinates of the click matching up to a point contained in a line. Then just delete the line (probably could redraw using the same endpoints but with the pen set to the background color). There would need to be some logic for the possible case where lines intersect and you don't want to delete a portion of the other line, but that could be solved fairly easily. Keep in mind, I'm not a big graphics programmer. This is just my idea.

Drawing this Image in my Java Applet wont work

import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
public class MonoplyDriver extends JApplet {
boolean isFirst=true;
Player John = new Player(1500,"Circle","John");
Board board = new Board();
Image imgBoard;
public void init()
{
//imgBoard = new ImageIcon("res/board.png").getImage();
imgBoard = getImage(getDocumentBase(),"res/board.png");
setSize(750,750);
System.out.println(getDocumentBase());
}
public void paint(Graphics g)
{
//super.paint(g);
if(isFirst)
{
isFirst=false;
}
g.drawImage(imgBoard, 0, 0, this);
}
}
From the sounds of it, the image is not being found because it is a internal resource.
You could try something like...
imgBoard = ImageIO.read(getClass().getResource("res/board.png"));
This will throw an IOException if the image cannot be loaded for some reason, which is more useful than what you're getting right now
As an aside. You should avoid painting directly to top level containers, but instead using something that extends from JComponent and override it's paintComponent method
Take a look at Performing Custom Painting and Reading/Loading an Image for more details

Expanding on Java Swing/AWT Program

I've written a small Swing program that draws a head and when a JCheckBox instance is selected/unselected by the user a hat is drawn or removed from on top of the head. I'm having some trouble taking the next step with this program -- I'd like to add a boolean field to the Head class that causes this component to listen to mouse events with a MouseListener. From there, I'd like to use two methods to set this field to true/false and render the remaining three methods lame ducks. Also, how would I change the paintComponent method so that if the boolean value is true the object is drawn with open eyes, and if it's false, the head is drawn with the eyes closed? Please provide any advice you have. Many thanks!
import javax.swing.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class Head extends JPanel {
Rectangle2D.Double chapeau, chapeau2;
Ellipse2D.Double bouche, visage, oeil1, oeil2;
JCheckBox box;
public Head(){
this.setBackground(Color.WHITE);
visage = new Ellipse2D.Double (150,130,100,100);
bouche = new Ellipse2D.Double (170,180,60,27);
chapeau = new Rectangle2D.Double (170,80,60,40);
chapeau2 = new Rectangle2D.Double (125,120,150,10);
oeil1 = new Ellipse2D.Double (170,150,20,20);
oeil2 = new Ellipse2D.Double (210,150,20,20);
box = new JCheckBox("Hat");
this.add(box);
box.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie){
repaint();
}
});
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(3.0f));
g2.setPaint(Color.BLUE);
g2.draw(visage);
g2.draw(oeil1);
g2.draw(oeil2);
g2.draw(bouche);
if(box.isSelected()){
g2.draw(chapeau);
g2.draw(chapeau2);
}
}
public static void main(String[] args){
JFrame f = new JFrame("Face Display Window");
f.setSize(425,285);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
f.add(new Head());
}
}
----------------------------------- Second Try
import javax.swing.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Head extends JPanel implements MouseListener {
Rectangle2D.Double chapeau, chapeau2;
Ellipse2D.Double bouche, visage, oeil1, oeil2, oeil3, oeil4;
JCheckBox box;
boolean isClosed = false;
public Head(){
this.setBackground(Color.WHITE);
visage = new Ellipse2D.Double (150,130,100,100);
bouche = new Ellipse2D.Double (170,180,60,27);
chapeau = new Rectangle2D.Double (170,80,60,40);
chapeau2 = new Rectangle2D.Double (125,120,150,10);
oeil1 = new Ellipse2D.Double (170,150,20,20);
oeil2 = new Ellipse2D.Double (210,150,20,20);
oeil3 = new Ellipse2D.Double (175,155,25,25);
oeil4 = new Ellipse2D.Double (215,155,25,25);
box = new JCheckBox("Hat");
this.addMouseListener(this);
this.add(box);
box.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie){
repaint();
}
});
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(3.0f));
g2.setPaint(Color.BLUE);
g2.draw(visage);
g2.draw(oeil1);
g2.draw(oeil2);
g2.draw(bouche);
if(box.isSelected()){
g2.draw(chapeau);
g2.draw(chapeau2);
if(isClosed) {
g2.draw(oeil3);
g2.draw(oeil4);
}
else {
g2.draw(oeil1);
g2.draw(oeil2);
}
}
}
#Override
public void mouseClicked(MouseEvent e) {
isClosed = !isClosed;
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args){
JFrame f = new JFrame("Face Display Window");
f.setSize(425,285);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
f.add(new Head());
}
}
I'm intentionally being a little vague here because I'm not sure if this is homework or not since you already have a fair amount of code that does a lot of stuff that is very similar to what you want it to and modifying it shouldn't be very difficult. However, if you're actually stuck, please clarify and I'll add more details if required.
I'd like to add a boolean field to the Head class that causes this component to listen to mouse events with a MouseListener.
This isn't too hard, let's walk through it. It's trivial to add a boolean field to your Head class - you simply declare boolean isClosed = false; - indicating that you begin the execution with the field set to false which your code will later interpret as the instruction to draw eyes open.
Your core requirement is the MouseListener. If you haven't already, check out the Java Trail for events; it explains how to implement a simple MouseListener. At this point, note that MouseListener is an interface and thus, you'd necessarily need to provide an implementation for all it's methods, even if they're empty-bodied methods. You may want to check out the MouseAdapter abstract class. It provides empty implementations of all these methods (and more) so that you only need to override the ones you need - this makes your code cleaner since you don't have a bunch of empty methods just to satisfy the compiler. This would solve the problem I believe you're referring to when you say 'and render the remaining three methods lame ducks' Of course, since you're already extending JPanel, you can't extend MouseAdapter as well so this doesn't apply here. But this (with other Adapters) is a useful class to keep in mind for later.
From there, I'd like to use two methods to set this field to true/false
If I understand you correctly, what you want is to toggle the value of isClosed on mouse clicks. So right now, you have a MouseListener/ MouseAdapter that doesn't really do anything. What you need to do next is provide an implementation for, lets say, the MouseClicked() method where you toggle the value of your boolean field. This is really easy as well - you simply invert the current value using the ! (NOT) operator and assign it back the variable - isClosed = !isClosed;. You may wish to read up on operators in Java in more detail.
Also, how would I change the paintComponent method so that if the boolean value is true the object is drawn with open eyes, and if it's false, the head is drawn with the eyes closed?
One way of doing this is to create two more shapes for the two closed eyes, similar to the ones you have for open eyes. Once you've done that, it's a simple matter of deciding which ones to draw (i.e. the closed eyes or the open ones) on the basis of the value of isClosed. So you'd use an if clause to check the value of isClosed and draw the open eyes when it's false and the closed eyes when true. Note that since your value of isClosed is being modified in your click handler, you need to make sure that you call repaint() when you change the value otherwise Swing may not update the panel immediately to show the change so then you won't see anything happen.
To sum it up, one way to do what you want is to make the following modifications to Head:
public class Head
extends JPanel
implements MouseListener {
//...all your other declarations still go here
boolean isClosed = false;
//also declare new 'eyes' which are closed
public Head() {
//..all your existing code is still here
//add code to instantiate closed eyes
//need to register a new MouseListener
//since head itself is a MouseListener, we can pass this as the argument
this.addMouseListener(this);
}
//...all your existing code still goes here
public void paintComponent(Graphics g) {
//...all your existing code still goes here
//decide which eyes to draw depending on isClosed
if(isClosed) {
//draw closed eyes
}
else {
//draw open eyes
}
//draw everything else as before
}
//implementation for MouseListener
//don't forget the rest of the MouseListener events
//mousePressed, mouseReleased, mouseEntered, mouseExited
public void mouseClicked(MouseEvent e) {
//toggle the value of isClosed
isClosed = !isClosed;
//must repaint
repaint();
}

Categories

Resources