this is my code. It worked for drawing a circle but I am having troubles drawing a triangle now.. A triangle should appear using mouse clicks but it is showing a triangle immediately after running the application. Please help. Thanks.
package mouse;
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.event.*;
import java.awt.geom.*;
public class triangle extends JFrame implements ActionListener, MouseListener {
int xx[]= {20, 50, 80};
int yy[]= {80, 30, 80};
public triangle () {
setSize(2000,2000);
addMouseListener(this);
}
public static void main(String[] args) {
//TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
triangle frame = new triangle();
frame.setVisible(true);
}
});
}
public void actionPerformed(ActionEvent ae) {
}
public void drawPolygon(int x, int y, int i)
{
Graphics g = this.getGraphics();
g.setColor(Color.BLACK);
g.drawPolygon(xx, yy, 3);
}
int x, y;
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void paint(Graphics g) {
drawPolygon(x, y, 3);
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
}``
The problem you have is that you override the paint method and therefore the drawPolygon method is already called in the initial painting of the JFrame.
For the effect you want to have you should avoid overriding the paint method and only use the drawPolygon method when the MouseListener is invoked.
This should look like this:
#Override
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
drawPolygon(x,y,3);
repaint();
}
In order to paint the triangle where you click with the mouse you need to add the current position to the original triangle coordinates like this:
public void drawPolygon(int x, int y, int i)
{
Graphics g = this.getGraphics();
g.setColor(Color.BLACK);
int[] drawx = {xx[0]+x,xx[1]+x,xx[2]+x};
int[] drawy = {yy[0]+y,yy[1]+y,yy[2]+y};
g.drawPolygon(drawx, drawy, i);
}
I hope this answers you question.
Some general remarks on programming:
You should definitely include a
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
otherwise you program won't terminate on closing the frame and keep on running.
It would also help the readability of your code if you avoid having everything in one class and split your code into several classes.
The MVC model is something that is a very good general guideline for designing class structures.
Related
i am writing a program that when the mouse is clicked, a circle will be drawn. The below code i've wrote so far.
import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.event.*;
import java.awt.geom.*;
public class test extends JFrame implements ActionListener, MouseListener {
Shape circle = new Ellipse2D.Float(10, 10, 10, 10);
public test () {
setSize(250,150);
addMouseListener(this);
}
public static void main(String[] args) {
//TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
test frame = new test();
frame.setVisible(true);
}
});
}
public void actionPerformed(ActionEvent ae) {
}
public void drawCircle(int x, int y) {
Graphics g = this.getGraphics();
g.drawOval(x, y, x, y);
g.setColor(Color.BLACK);
g.fillOval(x, y, 2, 2);
}
public void mouseClicked(MouseEvent e) {
drawCircle(e.getX(), e.getY());
repaint();
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
}
The code is a 400X400 jframe, when clicked open display a circle at a half seconds, The problem is that, when i release the mouse, the circle disappear. why?
Change your mouseClick(...) to:
int x, y;
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
Override paint(...):
#Override
public void paint(Graphics g) {
drawCircle(x, y);
}
When you call repaint(), the component gets painted again from scratch. You're circle is wiped away. You will want to override paintComponent(Graphics) which is called every time the component is painted.
So, here is the thing. My lecturer taught us how to get mouse coordinates by clicking on an applet. Now, i was thinking that may be i can try drawing dynamic lines using mousemotionlistener class using the mousedrag method and the mouse coordinates. I tried it but couldn't really make it work. Can anyone please suggest me where i made the error. Thanks a lot.
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.applet.*;
public class drawing extends Applet
implements MouseMotionListener {
int mx,my;
Graphics2D g2;
public void init()
{
this.addMouseMotionListener(this);
}
public void paint(Graphics g)
{
this.setSize(800,600);
g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g2.drawLine(40,50,200,150); // I was experimenting to draw static lines using the drawLine() method.
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
mx = e.getX();
my = e.getY();
System.out.println(" "+ mx + " "+ my);
g2.setStroke(new BasicStroke(10));
g2.drawLine(mx,my,mx,my);
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
In order to draw a line, you need to know the start point (which would be the point the user clicked) and the end point (the point where the user dragged to), from there is a simple matter to simple use Graphics#drawLine.
Start by taking a look at How to Write a Mouse Listener, 2D Graphics and Painting in AWT and Swing for more details
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class Drawing extends Applet
implements MouseMotionListener, MouseListener {
private Point startPoint, endPoint;
public void init() {
this.addMouseMotionListener(this);
addMouseListener(this);
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (startPoint != null && endPoint != null) {
g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
endPoint = e.getPoint();
repaint();
}
#Override
public void mouseMoved(MouseEvent arg0) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
endPoint = e.getPoint();
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Now, my advice, don't use Applet or AWT directly. Instead, start with a JPanel and override it's paintComponent method and use it perform your custom painting. Then add this panel to a JFrame to display it on the screen.
AWT is more then 15 years out of date and applets have way to many gotchas which you just don't need to deal with right now.
Start by having a look at Creating a GUI With JFC/Swing or even do some research into JavaFX
this program is suppose to shift the two rectangles by 10 points to the right each time I click on the screen at the x coordinate 300 or greater, but it doesn't, whats the problem?
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* To change this template use File | Settings | File Templates.
*/
public class MasterMind extends JComponent implements ActionListener,MouseListener {
//private MouseEvent me;
private int screenX=0;
private int screenY=0;
private ActionEvent e;
private int xX=10;
public MasterMind() throws IOException {
}
public static void main(String [] args) throws IOException {
JFrame window = new JFrame("Master Mind");
MasterMind game= new MasterMind();
window.add(game);
window.pack();
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setVisible(true);
Timer t = new Timer(30, game);
t.start();
window.addMouseListener(game);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800,600);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.red);
g.drawRect(xX,30,200,200);
g.setColor(Color.red);
g.drawString("x,y coordinates: "+screenX+" , "+screenY,400,100);
g.setColor(Color.blue);
g.drawRect(xX+3, 33, 194, 194);
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
repaint();
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
#Override
public void mouseClicked(MouseEvent e) {
MouseEvent mouseIvent = (MouseEvent) e;
int screenX = mouseIvent.getX();
int screenY = mouseIvent.getY();
System.out.println("screen(X,Y) = " + screenX + "\t" + screenY);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
//To change body of implemented methods use File | Settings | File Templates.
if (screenX>300) {
xX=xX+10; }
//timer animation
repaint();
}
}
I am very new to Java. so please answer in details if I may ask. thank you all.
These lines should be in the mouseClicked method rather than in actionPerformed.
if (screenX > 300) {
xX = xX + 10;
}
immediately before the existing repaint method there. They ensure that X coordinate variable xX is updated for use later in the paintComponent method.
Unrelated but make sure to invoke super.paintComponent(g) as the first statement of paintComponent
Put this ,In your MouseClicked or MousePressed or MouseReleased Method
if(me.getX()>300)
xX=xX+10;
repaint();
Here is the code.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
public class Paint extends JPanel implements MouseMotionListener, MouseListener {
public Paint() {
setBackground(Color.RED);
addMouseMotionListener(this);
addMouseListener(this);
}
private boolean clicked = false;
public void paintComponent (Graphics g) {
super.paintComponent(g);
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int) b.getX() - 3;
int y = (int) b.getY() - 23;
if (clicked) {
g.drawLine(x, y-5000, x,y+5000);
g.drawLine(x+5000,y,x-5000,y);
g.setColor(Color.white);
}
g.drawLine(x, y-5000, x,y+5000);
g.drawLine(x+5000,y,x-5000,y);
g.setColor(Color.black);
// . . .
}
#Override
public void mouseDragged(MouseEvent e) {
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
clicked = true;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
clicked = false;
repaint();
}
}
public class Frame extends JFrame {
public Frame() {
this.setSize(500,500);
this.setTitle("Test painting");
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Paint panel = new Paint();
this.add(panel);
this.setVisible(true);
}
public static void main (String[] args) {
new Frame();
}
}
When I run the program, it looks like it works fine when the application is in the default position, but once I move the applet to where I like on the screen, the lines don't maintain the current mouse position on screen.
Can someone show me where I've gone wrong or how to fix this?
Painting is done from the context of the component. The Graphics context for any given component is translated so that the top, left corner is 0x0.
MouseInfo.getPointerInfo().getLocation() is returning the location of the mouse on the screen, not the position relative to the component.
While there is a way to fix it, a better solution would be to simply use a MouseMotionListener instead. The MouseEvent sent to this method has already been translated to the component coordinate space...
public void mouseMoved(MouseEvent me) {
myPoint = me.getPoint();
}
Then in you paintComponent method, simple refer to myPoint instead of trying to use MouseInfo
I think that you will be better off to change your class's state in the MouseAdapter, call repaint() and then have your paintComponent(...) method use this state to help it draw. This seems cleaner and safer to me than using MouseInfo in paintComponent(...).
Other than that, if you need more specific help, consider
telling us more about what it is exactly you're trying to do and how your program isn't working.
creating and posting an sscce, a small compilable and runnable program that demonstrates your problem for us.
I want to be able to draw using Java's paint() on a JFrame. When I click the JFrame (anywhere for now) I want the JFrame to be repainted with the co-ordinates of the click - similar to this Java applet http://www.realapplets.com/tutorial/MouseClickExample.html
Currently Working:
Everything is drawn initially and the JFrame is properly displayed
Not Working:
JFrame does not repaint and update even when repaint() is declared
Here is my code - Please be as stringent as possible with it - I would like to improve my Java programming technique so (if you have time that is) point out every aspect I could improve on.
Any help would be very much appreciated.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class AreaForText extends JPanel implements MouseListener {
int xpos;
int ypos;
JFrame myJFrame = new JFrame();
public void setJFrame() {
myJFrame.setSize(300, 150);
myJFrame.setTitle("Bigger Text!");
myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myJFrame.setVisible(true);
myJFrame.getContentPane().add(new AreaForText());
myJFrame.addMouseListener(new AreaForText());
}
public void mouseClicked(MouseEvent me) {
//Save the coordinates of the click lke this.
xpos = MouseInfo.getPointerInfo().getLocation().x;
ypos = MouseInfo.getPointerInfo().getLocation().y;
System.out.print("Click" + " x: " + xpos + " y: " + ypos);
myJFrame.invalidate();
repaint();
revalidate();
}
public void mouseEntered(MouseEvent e){
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void paint(Graphics g) {
System.out.print("hello");
g.drawString("Hello World", 30, 80);
g.fillRect(20,20,20,20);
g.drawString("("+xpos+","+ypos+")",xpos,ypos);
}
}
class EnlargeText {
public static void main(String args[]) {
AreaForText test = new AreaForText();
test.setJFrame();
}
}
You are creating 2 instances of AreaForText which is not what you want to do. One is added to the JFrame, and one is added to the listener. So the one that actually gets the mouse events and is calling repaint is not the same object that is being displayed.
Some of your code organization is not the best. You have a JPanel subclass that builds its own JFrame and puts itself into the panel. You should just pass in the JFrame if you really need it. I've made a few changes below.
EDIT. I fixed up some of the mouse listener stuff, you were getting the wrong X/Y co-ordinates, and also, you should just add the listener to the panel directly, not the JFrame, that way you don't have to translate the co-ordinates.
EDIT I changed the paint method to paintComponent, which is the preferred method to override here. Have a look at the Swing Paint Tutorial for more information.
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
class AreaForText extends JPanel implements MouseListener {
private int xpos;
private int ypos;
public AreaForText() {
super();
this.addMouseListener(this);
}
public void mouseClicked(MouseEvent me) {
// Save the coordinates of the click lke this.
xpos = me.getX();
ypos = me.getY();
System.out.print("Click" + " x: " + xpos + " y: " + ypos);
repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.print("hello");
g.drawString("Hello World", 30, 80);
g.fillRect(20, 20, 20, 20);
g.drawString("(" + xpos + "," + ypos + ")", xpos, ypos);
}
}
class EnlargeText {
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame myJFrame = new JFrame("Bigger Text!");
myJFrame.setSize(300, 150);
myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myJFrame.getContentPane().add(new AreaForText());
myJFrame.setVisible(true);
}
});
}
}
Your not calling the JFrames repaint() you are calling the JPanel repaint method ( the class you are in)
Try:
myJFrame.repaint();