Saurish Suman Saurish Suman - 8 days ago 6
Java Question

Need help positioning in java

I created this java program and I wanted an output of which if int x and int y are above 100, it would draw a rectangle. But it doesn't. How can I make it work?Is there another line of code I need to add?
Here's my code:

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


@SuppressWarnings("serial")
public class GameSetup extends JPanel implements MouseMotionListener{

public static JFrame njf = new JFrame("Test");
public static int x, y;

public static void main(String[] args){

GameSetup gs = new GameSetup();
njf.add(gs);

}

public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(Color.GREEN);
g.fillRect(150, 75, 200, 100);
g.setColor(Color.ORANGE);
g.drawString("Play", 239, 123);
njf.addMouseListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
x = e.getX();
y = e.getY();

}
});
if(x > 100 && y > 100){
g.drawRect(10, 10, 100, 100);
}
}

public GameSetup(){
njf.setSize(500,500);
njf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
njf.setResizable(false);
njf.setLocationRelativeTo(null);
njf.setVisible(true);
}

@Override
public void mouseDragged(MouseEvent arg0) {

}

@Override
public void mouseMoved(MouseEvent e) {

}
}

Answer

Okay, there are several things wrong with the code that you included above.

The first that stood out to me was the way that you are adding the mouse action listener to frame. There are multiple things that are wrong with this.

First of all, you are doing this in the paintComponent method, which, if it works, is still considered to be bad practice because the paintComponent method may be called multiple times. Do that, as pointed out by the comments, in the constructor of the panel.

The second is that you are adding the mouse listener to the frame, not the panel, which doesn't work because the panel is "above" the frame, so the mouse event will only be recognized within the panel. Your best bet here is to add a MouseMotionListener directly to the panel itself.

The third is that you are implementing the MouseMotionListenerinterface in the GameSetup class, but never actually doing anything with this implementation. So what I did was that I got rid of the inner class, and just had the panel be its own MouseMotionListnener

The second thing that is wrong with the code is that the paintComponent method is only called at certain points in time (see this). That means that even though the mouse might have moved within the zone, your paintComponent method isn't being called to update the screen accordingly. For this, you need to call the repaint method for your panel.

The third is that you didn't set a size for your panel, and the default one is 0x0, so you need to set a size of your panel (which should be the same as the frame itself) (if you want to keep the default layout).

All of that being said, here is your code that I fixed up. I added a variable called enteredZone to keep track of if the mouse had previously entered the zone, so that the rectangle would stay up even if the mouse left the zone after entering it (its your choice if you want to keep it). Note that there are other things with this code that might be considered bad practice, but this is enough to get you started:

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


@SuppressWarnings("serial")
public class GameSetup extends JPanel implements MouseMotionListener {

    public static JFrame njf = new JFrame("Test");
    public static int x = 0, y = 0;
    public static boolean enteredZone = false;

    public static void main(String[] args) {
        GameSetup gs = new GameSetup();
        gs.addMouseMotionListener(gs);
        njf.add(gs);
        njf.setVisible(true);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        this.setBackground(Color.BLACK);

        g.setColor(Color.GREEN);
        g.fillRect(150, 75, 200, 100);
        g.setColor(Color.ORANGE);
        g.drawString("Play", 239, 123);


        if (x > 100 && y > 100 || enteredZone){
            g.drawRect(10, 10, 100, 100);
            enteredZone = true;
        }
    }

    public GameSetup() {
        super();
        setSize(500, 500);
        njf.setSize(500,500);
        njf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        njf.setResizable(false);
        njf.setLocationRelativeTo(null);
    }

    @Override
    public void mouseDragged(MouseEvent arg0) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        x = e.getX();
        y = e.getY();

        if (x > 100 && y > 100) repaint();
    }

}
Comments