I am very new to Java, and I wanted to try to make a thing in BlueJ that requires BlueJ to know when the mouse is clicked, and to be able to determine the mouse's coordinates on the x,y plane.
In my class where I code, I have seen some imported class and things like Scanner and Graphics, so it might be something along those lines, but I am not sure.
I just mainly need
The thing to import (if it is a thing that needs to be imported)
How to make it tell if the mouse is clicked
How to make it be able to tell me the x, y position of the mouse when asked (like, what class method would I have to refer to to find this)
After I have that, I will work with that to try to make my program. Thank you!
EDIT: Upon request, here is my attempt
java.awt.event.MouseAdapter
public class main
{
MouseAdapter test = new MouseAdapter();
}
public void mouseMoved(test e)
{
System.out.println("hey your mouse moved");
}
I am clearly doing something horribly wrong
One way to achieve your goal would be to use java swing. The following code will print out a statement if the mouse is moved inside the created window:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame jFrame = new JFrame();
jFrame.setSize(720,480);
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jFrame.getContentPane().addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent mouseEvent) {
System.out.println("STUFF");
}
#Override
public void mouseMoved(MouseEvent mouseEvent) {
System.out.println("STUFF");
}
});
});
}
This is not an ideal solution but I hope it helps you to look in the right direciton.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import javax.swing.event.*;
import javax.swing.JPanel;
public class Triangle extends JFrame
{
public Triangle()
{
add(new PolygonsPanel());
}
public static void main(String [] args)
{
Triangle t = new Triangle();
t.setSize(500,500);
t.setTitle("Triangle");
t.setVisible(true);
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setLocationRelativeTo(null);
}
}
class PolygonsPanel extends JPanel implements MouseListener
{
private int x1,x2,x3,y1,y2,y3;
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Polygon p = new Polygon();
p.addPoint(x1,y1);
p.addPoint(x2,y2);
p.addPoint(x3,y3);
this.addMouseListener(this);
g.drawPolygon(p);
}
public void mouseExited(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
int i = 0;
if(i==0)
{
int x1= e.getX();
int y1= e.getY();
i++;
}
else if(i==1)
{
int x2= e.getX();
int y2= e.getY();
i++;
}
else if(i==2)
{
int x3= e.getX();
int y3= e.getY();
i++;
}
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
}
I want to make triangle using polygon and set the coordinate by click the mouse.
compiler did't show error, can anybody help ?
..........................................................................................................................................................................................................
In order to debug such applications, you can add println() lines in the right places. While this sounds a bit childish, this method of debugging, called printf-Debugging is even used by the most professional developers in some cases.
I suggest you add a System.err.println("1") resp. System.err.println("2") / System.err.println("3") in each of the if-branches of mouseClicked() to find out why it's not properly recording the points. Hint: You probably want variable i to have a different scope than now`.
Registering the MouseListener should not be done in paintComponent(). If you think a little bit about this, it should be obvious. Ask yourself: How often do I need to register the MouseListener? Only once. How often is paintComponent() called? Many times. So, the addMouseListener() is certainly in the wrong place.
Once you fixed these, you might notice that you have to hide/unhide, resize or (on some OS) move the window in order for your polygons to be redrawn. That's because once you've changed the appearance by recording a new coordinate for your polygon, you don't tell Java that the component needs to be redrawn.
The programming model usage by extension which you apply is still shown on many web pages and in many books as of today, but it's plainly wrong because it often violates the LSP - Liskov Substitution Principle. In your case, extending the JPanel for a PolygonsPanel is almost right, because that is a kind of Painting Canvas which in fact is a new component, so, creating a new class that is a component is perfect for that. Just JPanel might not be the best superclass for it, check out the class hierarchy of Swing class a bit and you will discover a better superclass. However, in Triangle, you do not really want to extend JFrame, you merely use JFrame without adding any new reusable features to it, so subclassing is not right in that case.
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.
So I have 3 rectangles drawn on my JPanel that are acting as buttons, and what I would like to do is when the mouse is hovered over one of them, the Jpanel will repaint, and change the color of only that rectangle to red.
The only way I can think to do it is to have 3 separate variables that determines if the mouse is over each component. Then there would be code in the repaint method that, if rect1hover is true, then draw using g.setColor to red.
#Override
public void mouseMoved(MouseEvent e) {
if(rect1.contains(e.getX(), e.getY())){
rect1hover = true;
}
}
But this seems really inefficient. Is there a better way to do this?
Sure. Put your drawn rectangles in a List. Then you can write this code.
#Override
public void mouseMoved(MouseEvent e) {
for (DrawnRectangle r : rectangles) {
if (r.contains(e.getX(), e.getY())){
r.setHoverBackground();
}
}
}
You'll have to create a DrawnRectangle class with a setHoverBackground method.
You can use real components, then just add a MouseListener to each component and you don't need to do any lookup or do custom painting.
See Playing With Shapes for more information.
Is there a way to detect the position of a JFrame while it's dragged?
The problem is that on MAX OS X the position of a window updates when you stop moving the mouse. I saw a tip of calculating the new position and setting the position of the window manual. But therefore i have to know the position of when i started dragging.
To make it a bit more clear, the JFrame is used to capture the screen, but when you move it around it doesn't update cause it still think it's at the old position. When you stop moving the dragging (but you can still hold the mouse button) then it updates.
import java.awt.event.ComponentListener;
import java.awt.Component;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
void setup() {
frame.addComponentListener(new ComponentListener()
{
public void componentMoved(ComponentEvent evt) {
Component c = (Component)evt.getSource();
println("moved "+frameCount);
}
public void componentShown(ComponentEvent evt) {}
public void componentResized(ComponentEvent evt) {}
public void componentHidden(ComponentEvent evt) {}
}
);
}
void draw() {
}
If what you mentioned regarding the update happening only when the window has stopped moving, and if knowing the position of when you started dragging can really solve the issue, then I see an option that you store the last location in some variable and update it each time you detect a move.
So declare a private variable in your JFrame class:
Point originLocation=new Point(0,0);
in your listener method you can:
public void componentMoved(ComponentEvent evt) {
Component c = (Component)evt.getSource();
Point currentLocationOnScreen=c.getLocationOnScreen();
// do your requirements here with the variables currentLocationOnScreen and originLocation
// update the originLocation variable for next occurrences of this method
originLocation=currentLocationOnScreen;
}
Simple question – why wouldn't an object move if it's the object of .move() inside onMouseMoved()? I'm trying to write Breakout as part of the Stanford 106A exercises on iTunes U and for some reason I can't get the paddle to track the mouse. I'm a java noob, so I'm sure it's something really simple. Could someone please take a look at this code?
/** Runs the Breakout program. */
public void run() {
setupBoard();
addMouseListeners();
}
/** Provides the initial GCanvas and blocks for the game */
private void setupBoard(){
this.setSize(APPLICATION_WIDTH,APPLICATION_HEIGHT);
addBricks();
paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT);
add(paddle, WIDTH/2-PADDLE_WIDTH/2,HEIGHT-PADDLE_Y_OFFSET);
}
public void MouseMoved(MouseEvent e){
paddle.move(e.getX()-paddle.getX(), 0);
}
private GRect paddle;
}
I'm not sure if having paddle be an instance variable is appropriate in this case, since its "value" doesn't change (the paddle's always the paddle), but if I just define it as a new GRect within setupBoard I get an error in the MouseMoved() method.
Your class that has the mouseMoved() method needs to implement the interface MouseMotionListener, and add the motion listener. Moreover, the event handler is mouseMoved() not MouseMoved(). So, e.g.:
public class Game extends JPanel implements MouseMotionListener {
public void run() {
addMouseMotionListener(this);
//...
}
public void mouseMoved(MouseEvent e) {
paddle.move(e.getX()-paddle.getX(), 0);
}
//...
};