I've made a simple program where you should be able to hold and drag the mouse to paint something. Now, this program works fine on my Windows, but when I try the exact same code on my Mac, the 10x10 dot I'm trying to draw with just follows the cursor, but doesn't leave a track behind it.
First, I thought it was a problem with the JDK, so I've reinstalled and installed different versions. Same with both Eclipse And Netbeans, reinstalled multiple times, but it did not work.
public class panelDraw extends JPanel {
int x, y;
/**
* Create the panel.
*/
public panelDraw() {
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
});
}
public void paintComponent(Graphics g) {
g.fillRect(x, y, 10, 10);
}
Here is the panel that I then put in a JFrame to run the program. As I said, no problem on my Windows, but on the Mac, it doesn't "draw" anything the dot just follows the cursor.
Thank you for the help!
Related
I have the following code that draws an invisible window on the entire screen:
Window w=new Window(null)
{
private int x = 200; private int y=200;
private int dx = 2; private int dy = 2;
private final int CIRCLE_DIAMETER = 400;
#Override
public void paint(Graphics g)
{
g.setColor(Color.ORANGE);
g.fillOval(x, y, CIRCLE_DIAMETER, CIRCLE_DIAMETER);
}
#Override
public void update(Graphics g)
{
if(x<=0)
dx*=-1;
if(y<=0)
dy*=-1;
if(x+CIRCLE_DIAMETER>=this.getWidth())
dx*=-1;
if(y+CIRCLE_DIAMETER>=this.getHeight())
dy*=-1;
x+=dx;
y+=dy;
this.paint(g);
}
};
w.setAlwaysOnTop(true);
w.setBounds(w.getGraphicsConfiguration().getBounds());
w.setBackground(new Color(0, true));
w.setVisible(true);
//Lazy way of making calls to paint for testing
while(true){
w.repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This draws an orange circle on the screen at the coordinates x and y. When I call repaint in my infinite loop, paint gets called and the x and y get updated, but the circle never gets drawn in another position. If I print the values of x and y to every call of paint they are getting updated properly, so I do not know why it isn't getting drawn. Does anyone know what I am doing wrong here?
Thanks for any suggestions!
I am new here so I may be wrong.
I think that your problem is something to do with how you are using a Window object and not a JPanel. So change your Window object to a JPanel. You should probably close that up with a JFrame in order to complete the final window.
You should be using a JPanel I think so that the methods that you can use to perform the drawing of the ball to move are implemented properly.
Instead of overriding the paint() method you need to override the paintComponent() method.
Following the cycle of drawing your objects.
Like so...
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.ORANGE);
g.fillOval(x, y, CIRCLE_DIAMETER, CIRCLE_DIAMETER);
}
The super.paintComponent() should empty the original image out of the JPanel and you should then be able to draw your updated image.
These may help you as well(I haven't really looked at them properly):
Java ball moving
http://docs.oracle.com/javase/tutorial/uiswing/painting/
Java Bouncing Ball
Sorry if I missed something. (I haven't tested your code)
I am trying to develop a very basic game and it involves mouse. So what i am trying to do is getting coordinates of mouse to write a integer. I searched internet and find this.
mouse_x=MouseInfo.getPointerInfo().getLocation().getX();
mouse_y=MouseInfo.getPointerInfo().getLocation().getY();
It partially worked and gave me coordinates of mouse on desktop. But what i need is coordinates of mouse on frame. So if only i knew the coordinates of frame's starting (0,0) point (not the window's. the white area without toolbars.) I could calculate mouse's coordinates.
Thanks in advance.
Or if thats not possible i could use how to develop it in fullscreen.
And i need to know location of mouse always. It should refresh position when i run it in a never ending while loop.
I just use e.getPoint() which returns the point of the mouse clicked. You could either have your Frame implement MouseListener of you can register a MouseListener to the frame if it is not the main GUI component.
public class MyFrame extends JFrame implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int x = (int) p.getX();
int y = (int) p.getY();
// do something withe the x and y points
}
}
If you do the above, you also need to override the other MouseListener methods. Though you don't need to implement any action for them
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
If your GUI class didn't extend JFrame, then you can just register the listener to the Frame, in which case you only need to use the MouseAdapter, which allows you to just implement 0 or more action method (i.e. just mouseClicked)
frame.addMouseListener(new MouseAdapter() {
void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int x = (int) p.getX();
int y = (int) p.getY();
// do somthing withe the x and y points
}
});
Edit for MouseMotionListener
"I want to know location of mouse always not just when clicked."
If you wan't to know the location of the mouse at any given time, you should implement MouseMotionListener and override the mouseDragged and mouseMoved
public class MyFrame extends JFrame implements MouseMotionListener {
....
public void mouseMoved(MouseEvent e){
Point p = e.getPoint();
int x = (int) p.getX();
int y = (int) p.getY();
// do something withe the x and y points
}
public void mouseDragged(MouseEvent e){
}
}
The mouseMoved will fire an event every time the mouse is moved, and the mouseDragged will fire an event whenever the mouse is dragged
You need to add a MouseListener to your JFrame and then you can just get the relative coordinates with MouseEvent.getPoint
frame.addMouseListener(new MouseAdapter() {
void mouseClicked(MouseEvent e) {
System.out.println(e.getPoint());
}
});
If you, for some obscure reason, need the coordinates in a situation when mouse events are not available (in which case, take a look at the other answers), you can use SwingUtilities.convertPointFromScreen() to convert the coordinates from MouseInfo to the coordinate system of a Component.
I'm trying to call repaint from another class. But it does not work. I have to draw on a frame.
public class Tester extends JFrame{
public static dtest d ;
public static void main(String[] args) {
Tester t = new Tester();
d = new dtest();
test tnew = new test();
}
public static class dtest extends JFrame implements MouseMotionListener{
public static int x,y;
dtest()
{
super("title");
setSize(500,500);
setVisible(true);
addMouseMotionListener(this);
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
public void paint(Graphics g)
{
System.out.println("I am called");
}
}
public static class test {
public test()
{
for(int i = 0 ; i < 5 ; i++)
{
System.out.println("I am called from run");
d.repaint();
}
}
}
}
this prints
I am called from run
I am called from run
I am called from run
I am called from run
I am called from run
so it does not executing the paint() portion. d.repaint() is not working. why?
Take a look at this page and look at the first answer. It's a similar if not exact question to yours.
JFrame's paint() method has been deprecated. The compiler, or your IDE, should be complaining a bit, especially if you place the #Override tag directly above the method (use this to test if this method can be rewritten... aka what you're trying to do).
This means that its use has been discouraged and some functionality may have been removed. When using javax.swing, you'll want to learn the system completely about JPanels and JComponents. To paint something on a screen, you'll want to add a custom class that extends JPanel with the add(Component c) method. Then, override the paintComponent(Graphics g) method in that class. Make sure to have the first line in that method be super.paintComponent(g); so that the window can refresh itself.
For completeness:
public class MyWindow extends JFrame {
MyPanel thePanel;
public MyWindow(int x, int y) {
setSize(x, y);
thePanel = new MyPanel(x, y);
this.add(thePanel);
}
}
public class MyPanel extends JPanel {
public MyPanel(int x, int y)
setSize(x, y);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(ImageManager.getImage("Cute Puppy"), 40, 40, null); // Or whatever
}
}
So, when the repaint() or revalidate() method is called on the MyWindow, the Panel will recieve a paintComponent call.
Please let me know in the comments if you need any additional help.
Edited:
Since you need to use MouseMotionListener, and I'm still not quite understanding the context and trouble of "I need to call repaint from another class"... I will try my best.
Firstly, check out this tutorial on the Oracle pages. Also, check out the others on GUI's. You'll learn a lot about organization and displaying that will make you realize how their system can work with yours.
Now, for your questions:
i have to use MouseMotionListener.
Not quite... it is a good way for set up but you can run a Thread (something that constantly runs methods over and over) to check the Mouse coordinates. You'll want to start doing this when you get into games and other miscellaneous applications.
new Thread() {
public void run() {
Point mouse;
int mousex;
int mousey;
while (true) {
mouse = MouseInfo.getPointerInfo().getLocation();
mousex = mouse.x - theWindow.getLocationOnScreen().x - 3; // You'll need to get the
// x coordinate, subtract the window's x coordinate, and subtract 3 because of
// the blue border around a standard pc window.
mousey = mouse.y - theWindow.getLocationOnScreen().y - 29; // 29 is top bar height
SomeOtherClass.processMove(mousex, mousey);
}
}
}.start();
Next: I tried that with JPanel but i could not do that. If you read the tutorial at the top of my edit, you see they implement MouseMotionListener with ease.
Next: I prefer to do it with JFrame. If you wish to process the mouse in the JFrame, do the following: Have your JFrame the listener, but the JPanel be where the mouse data comes from. As follows:
public class MyWindow extends JFrame implements MouseMotionListener {
public MyPanel thePanel;
public int x;
public int y;
public MyWindow() {
thePanel = new MyPanel();
thePanel.addMouseMotionListener(this);
// Make this JFrame get called when the mouse
// moves across the panel.
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
thePanel.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Other painting stuff
}
}
Next: Now i have to update the frame from another class. I could not find a way to update the GUI(the frame) from another class.
Simple. Since the JPanel is what needs to be updated, add the following method to the MyWindow class:
public void repaintWindow() {
thePanel.repaint();
}
And add this to whenever you need to update it:
MyWindow theWindow = new MyWindow();
theWindow.repaintWindow();
Next: all the answers here extended JPanel. So i could not find my answer.
I apologize, but you NEED a panel. It is possible to do with JFrames, but if you want to start doing things raw and low-level, you need to learn how these things work by learning to read the oracle tutorials and the oracle documentation. For now, use JPanels in any ways I've shown you.
Next: from another class I have to draw something on JFrame.Is that possible?
Yes, indeed! Whenever you want to draw something:
MyWindow theWindow = new MyWindow();
Graphics g = theWindow.thePanel.getGraphics();
BufferedImage someRandomImage = SomeRandomClass.getRandomImage();
g.drawImage(someRandomImage, 200, 481, null);
theWindow.repaintWindow();
I really hope I've helped but to program in java you need to use the tools they give you, especially when it comes to high level things like Swing. There are tutorials everywhere for this stuff. Please read them before asking for specific help in the future.
Hey guys I need help I am trying to make a program where I can draw in a window with the mouse. So far I have it to where when I click a dot appears but I need to add a drag method so that when I drag the mouse across the page it draws stuff. Can someone look at my code and help me out where you can?
Here is my code:
import javax.swing.*;
import java.awt.event.*;
public class mouse {
private static int x,y;
private static draw object = new draw ();
public static void main(String[] args){
JFrame frame = new JFrame ("Mouse");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.add(object);
object.addMouseListener(new AL());
}
static class AL extends MouseAdapter{
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
object.drawing(x, y);
}
public void mouseDragged( MouseEvent e) {
x= e.getX();
y= e.getY();
object.drawing(x, y);
}
}
}
and
import javax.swing.*;
import java.awt.*;
public class draw extends JPanel {
private static int x,y;
public void drawing (int xx, int yy){
x=xx;
y=yy;
repaint();
}
public void paintComponent (Graphics g){
g.setColor(Color.black);
g.fillOval(x, y, 10, 10);
}
}
One idea that I have is to add your mouse coordinates each to a separate list whenever the mouse is clicked and draw based on the size of the lists, however since you are using mouse dragged you could just use Path2D.lineTo(x, y) and use e.getX() and e.getY() for the x and y coords. After this use Path2D.moveTo(x, y) to make sure line path is appended for each pixel the mouse moves (this makes sure that each movement doesn't look like a straight line, but rather like a line moving whatever direction you're "drawing" in). Also, a few tips:
The void mouseDragged usually works better when used in mouseMotionAdapter because from my experience it usually doesn't register the event in just mouseAdapter.
Since this is a drawing program, personally I'd set a variable for the size of your circle to be used in the future if you actually are planning to expand this into something bigger (example: g.fillOval(x, y, brushSize, brushSize)).
I'm working on these online Stanford lessons on Java, and we just made the leap to events, and I'm having difficulty wrapping my head around it. I'm playing around with a program that is in the "Art and Science of Java" book. This program will move a rectangle and oval around on the canvas if you click on them.
I modified the run method to try and get the listener to only work on the rectangle, but I was surprised to see even with my changes, both objects are being listened to...why?
Original run method:
public void run() {
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
addMouseListeners();
}
My changed program (with the MouseListener in the private createRectangle method):
import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;
/** This class displays a mouse-draggable rectangle and oval */
public class DragObjects extends GraphicsProgram {
public void run() {
createRectangle();
createOval();
}
private void createOval(){
GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
}
private void createRectangle(){
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
addMouseListeners();
}
/** Called on mouse press to record the coordinates of the click */
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
/** Called on mouse drag to reposition the object */
public void mouseDragged(MouseEvent e) {
if (gobj != null) {
gobj.move(e.getX() - lastX, e.getY() - lastY);
lastX = e.getX();
lastY = e.getY();
}
}
/** Called on mouse click to move this object to the front */
public void mouseClicked(MouseEvent e) {
if (gobj != null) gobj.sendToFront();
}
/* Instance variables */
private GObject gobj; /* The object being dragged */
private double lastX; /* The last mouse X position */
private double lastY; /* The last mouse Y position */
}
It would be helpful if you would point out that the method addMouseListeners() is in the superclass, GraphicsProgram. What it does is adds the listener to the canvas, not just to the individual shape. From there, you'll need to somehow determine whether the mouseclick occurred in the rectangle or in the oval.
Or there might be a way to add the listener just to a single shape. Check the Javadoc for the GRect and GOval classes. I'm assuming those are also in one of the acm.* packages, which means they're not built in to the Java language. (This is why I recommend using an IDE like Eclipse that can automatically import each class automatically, instead of importing an entire package.)
It might also be helpful to post a link to the online lessons you're following.
I haven't looked at the source other than what you have posted. But you will need to other modify gOval and gRect or a superclass to accept a mouseListener, or in your listener do something like the following.
in the MouseClicked, MouseMoved, etc. methods. Get the point of the event, and then go through your Objects and query them to see if the point exists withing their bounds.
You would need a list of objects to loop through and then call something like gRect.containsPoint(myPoint) in this method check to see if the point exists in the shape. You will still have issues where shapes overlap, so you will need some concept of a z-axis or depth to determine which shape is on top.
You need to post the source for the addMouseListeners.
If you take a look at this post over here you might get some ideas on how listeners can work (if you post the addMouseListener source we can help with your specific question of course!)