Using KeyEvents and Mouse events at the same time - java

I'm trying to create a simple Java applet that can detect both the location of the mouse within the applet and detect whether the shift key has been released or pressed. When I add a KeyListener, though, the program ignores the mouseMove event. How can I get the mouseMove event to work while also using KeyListener?
public class Test extends java.applet.Applet implements java.awt.event.KeyListener {
String message;
int moveX, moveY;
public Test() { this.addKeyListener(this); }
public void init() {
message = "";
moveX = moveY = 0;
}
public void paint(java.awt.Graphics g) {
new Test();
g.drawString(message,15,15);
g.drawString("(" + moveX + "," + moveY + ")",900,630);
}
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_SHIFT)
message = "Shift key pressed";
repaint();
}
#Override
public void keyReleased(java.awt.event.KeyEvent e) {
message = "Shift key released";
repaint();
}
#Override
public void keyTyped(java.awt.event.KeyEvent e) {}
public boolean mouseMove(java.awt.Event e, int x, int y) {
moveX = x;
moveY = y;
repaint();
return true;
}
}

If you want to check if someone was holding shift or another key while clicking, MouseEvent has a method called getModifiers()

I fixed the issue by replacing mouseMove(java.awt.Event e, int x, int y) with mouseMoved(java.awt.event.MouseEvent e), so now the coordinates change when the mouse's location changes and the message changes when the shift key is held down.

Related

How do I make a graphics change place randomly everytime I click on it

The code I made won't change the coordinates of the ball every time I click on it.
public class AimTrainerPanel extends JPanel implements MouseListener {
static final int WIDTH = 1300;
static final int HEIGHT = 750;
static final int SIZE = 10;
Random rand;
JLabel cd;
int x;
int y;
boolean running = false;
Timer timer;
AimTrainerPanel() {
rand = new Random();
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setBackground(Color.black);
this.setFocusable(true);
this.setLayout(null);
this.addMouseListener(this);
startGame();
}
public void startGame() {
newDot();
running = true;
timer = new Timer();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
public void draw(Graphics g) {
if (running) {
g.setColor(Color.white);
g.fillOval(x, y, SIZE, SIZE);
}
}
public void newDot() {
x = rand.nextInt((int)(WIDTH/SIZE)) * SIZE;
y = rand.nextInt((int)(HEIGHT/SIZE)) * SIZE;
}
#Override
public void mouseClicked(MouseEvent e) {
int mx = e.getX();
int my = e.getY();
if (mx >= x && mx <= x + 10) {
if (my >= y && my <= y + 10) {
newDot();
}
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
The newDot() method is suppose to create new coordinates every time it is called but the ball won't change places. I don't know if it's because I misswrote something or because my what I did doesn't change the coordinates or if I'm suppose to add something.
I'm not sure what your Timer is supposed to be doing, but it doesn't appear to be a Swing Timer, and since this is a Swing GUI I'd get rid of it.
Now to the crux of your problems:
You're using mouseClicked which isn't called if the mouse moves even slightly between mouse pressed and mouse released, and so often it is better to use mousePressed or mouseReleased methods and not mouseClicked
You don't call repaint() after changing the state of your program. Swing won't know that a repaint is needed unless you suggested, and so in your mouseListener or in code called by it, you should call this method after changing GUI state. Here you can call it at the end of the newDot(...) method or in the mouse listener after you call the same method.
Your if blocks within your mouse listener appear to be quite restrictive as to where they will allow the listener to respond to a mouse click -- is it too restrictive? I don't know since I'm not familiar with your requirements, but possibly.

How to change variables stored inside mouseMoved method in MouseMotionListener Java Class

I am trying to write a mouse listener for my game. The basic idea is that I use mouse listener to (constantly update) track the x and y coordinates of my cursor and change the position of the player accordingly. I decided to use the mouseMoved method inside MouseMotionListener to accomplish this. I am supposed to press on the screen once in order to initiate mouse tracking of player, and once to stop. However, it seems my variables will not update inside mouseMoved. How do I update the variables inside the method?
private Handler handler;
public static int vel=5;
boolean pressed = false;
int run=0;
int x;
int y;
public mouseListener(Handler handler){
this.handler = handler;
}
public void mouseClicked(MouseEvent event) {
run++;
}
public void mouseMoved(MouseEvent event) {
this.x = event.getX() - 16;
this.y = event.getY() - 16;
System.out.println("Click"+run);
int trun=run;
if(trun%2==1) {
System.out.println(x+" "+y);
updateField(x,y);
}
}
public void updateField(int tempx, int tempy) {
int x=tempx;
int y=tempy;
for(int i=0; i<handler.object.size();i++){
GameObject tempObject = handler.object.get(i);
if(tempObject.getID()== ID.Player){
if(x>tempObject.getX()) {
tempObject.setVelX(vel);
}
if(x<tempObject.getX()) {
tempObject.setVelX(-1*vel);
}
if(x==tempObject.getX()) {
tempObject.setVelX(0);
}
if(y>tempObject.getY()) {
tempObject.setVelY(vel);
}
if(y<tempObject.getY()) {
tempObject.setVelY(-1*vel);
}
if(y==tempObject.getY()) {
tempObject.setVelY(0);
}
if(pressed==false) {
tempObject.setVelY(0);
tempObject.setVelX(0);
}
}
}
}
By the end result, I should be able to click on the screen once, and the player should start following my mouse. I should then be able to click again to turn it off. Instead, the x and y values are updated but the player does not move and the on/off variable does not update inside mouseMoved().

can't draw on a JPanel after repaint method

I'm experimenting on a GUI that I programmed and I don't understand how I can fix my problem:
My GUI contains a jPanel that on receiving a mouseclick, paints a point with filloval command.
private void myPnlMousePressed(java.awt.event.MouseEvent evt) {
changed = true;
p.x = evt.getX();
p.y = evt.getY();
drewPoints(p.x, p.y);
}
private void drewPoints (int x, int y) {
if (gf == null) {
gf = (Graphics)myPnl.getGraphics();
}
myPointsList.add(new Point(x, y));
gf.fillOval(x, y, 5, 5);
xVal.setText("X = " + x);
yVal.setText("Y = " + y);
}
everything works fine but when I want to open an XML file that I created to save all the points it doesn't work.
The problem is that when I use the repaint method on the jPanel after choosing a file, all the points loads fine but the panel can't draw the points.
If I put the repaint method in the open button listener (before the choosing file) it works, but then if the user cancels the open option so the panel stays blank and I don't want to draw the points again.
I think it happens because the repaint process is not finished.
All the points added to a private List.
private void OpenFile() {
try {
File thisFile;
JFileChooser of = new JFileChooser();
int option = of.showOpenDialog(of);
if (option == JFileChooser.APPROVE_OPTION){
thisFileName = of.getSelectedFile().getPath();
thisFile = new File(thisFileName);
if (!of.getSelectedFile().getName().endsWith(".xml")) {
String error = "Error, You didn't select XML file";
JOptionPane.showMessageDialog(this, error, "Wrong type of file", JOptionPane.INFORMATION_MESSAGE);
return;
}
myPnl.repaint();
myPointsList.clear();
....
....
....
for (int i = 0; i < pointsList.getLength(); i++) {
Element point = (Element) pointsList.item(i);
p.x = Integer.parseInt(point.getElementsByTagName("X").item(0).getTextContent());
p.y = Integer.parseInt(point.getElementsByTagName("Y").item(0).getTextContent());
drewPoints(p.x, p.y);
}
....
how can I make it work??
Don't use gf = (Graphics)myPnl.getGraphics();, this is not how painting in Swing works. The getGraphics method can return null and is nothing more then a snap shot of the last paint cycle, any thing you paint to it will be erased on the next paint cycle (repaint).
Instead, override the JPanels paintComponent and put all you painting logic there. There is an expectation that when called, you are expected to fully re-paint the current state of the component.
See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing
You have to use the repaint() and override the paint() method:
class MyPanel extends JPanel implements MouseListener
{
private int x;
private int y;
public MyPanel() {
super();
addMouseListener(this);
}
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mousePressed(MouseEvent e) { }
#Override public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 10, 10);
}
}
If you want to draw all points, don't use x and y but a list of points:
class MyPanel extends JPanel implements MouseListener
{
private ArrayList<Point> points = new ArrayList<>();
public MyPanel() {
super();
addMouseListener(this);
}
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mousePressed(MouseEvent e) { }
#Override public void mouseReleased(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
#Override public void paint(Graphics g) {
super.paint(g);
for (Point p : points)
g.fillOval(p.getX(), p.getY(), 10, 10);
}
}
where:
class Point
{
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Then use it:
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
MyPanel myPanel = new MyPanel();
frame.add(myPanel);
frame.setVisible(true);
}

Moving a JFrame with custom title bar

How can I move a JFrame having a custom title bar?
I remove the default title bar and I did my own design. This is how it looks like:
I want to know how to drag a JFrame when the cursor is placed on the title bar only and not the whole frame. I've searched already and I have seen a lot of samples but I still don't get it. Do you guys have any simple code that I can understand?
I haven't started the code yet since I don't know how to start it. All I know is that, it is about mouseDragged or MouseMotionListener.
I implemented the following:
public class DragFrame extends JFrame {
int mpX, mpY;
public DragFrame() {
addMouseListener( new MouseAdapter() {
#Override
public void mousePressed( MouseEvent e ) {
mpX = e.getX();
mpY = e.getY();
}
} );
addMouseMotionListener( new MouseMotionAdapter() {
#Override
public void mouseDragged( MouseEvent e ) {
setLocation(
getLocation().x + e.getX() - mpX,
getLocation().y + e.getY() - mpY );
}
} );
}
}
Thanks to #peeskillet for giving the crucial link to Drag and Resize undecorated JFrame with the inspiration to save the mouse position on mousePressed(...).
Your guess that you'll need to overwrite the MoseMotionListener.mouseDragged method was correct. Then, you need to call JFrame.setLocation to move your JFrame, like this:
class FrameMoveListener extends MouseAdapter
{
private Point lastPos;
private Frame frame;
public FrameMoveListener (Frame f)
{
frame = f; // mustn't be null
}
public void mouseDragged (MouseEvent evt)
{
if (lastPos != null)
{
int x = lastPos.x - evt.getX();
int y = lastPos.y - evt.getY();
f.setLocation(f.getLocationOnScreen().x + x,
f.getLocationOnScreen().y + y);
}
lastPos = new Point(evt.getX(), evt.getY());
}
}
use this method is simple and perfec
final Component obj - your JFrame, JLabel, any Component
final boolean info - if you want display the position when release de left click
public static void Move(final Component obj,final boolean info) {
MouseInputAdapter d=new MouseInputAdapter() {int x,X,y,Y;
#Override public void mousePressed(MouseEvent e){if(SwingUtilities.isLeftMouseButton(e)){x=e.getXOnScreen();X=obj.getLocation().x;y=e.getYOnScreen();Y=obj.getLocation().y;}}
#Override public void mouseDragged(MouseEvent e){if(SwingUtilities.isLeftMouseButton(e)){obj.setLocation(X+(e.getXOnScreen()-x), Y+(e.getYOnScreen()-y));}}
#Override public void mouseReleased(MouseEvent e){if(info && SwingUtilities.isLeftMouseButton(e)){System.err.println(obj.toString().substring(0,obj.toString().indexOf("["))+" ("+obj.getLocation().x+","+obj.getLocation().y+")");}}};
obj.addMouseListener(d);obj.addMouseMotionListener(d);
}
this is the format code:
public static void Mover(final Component obj, final boolean info) {
MouseInputAdapter d = new MouseInputAdapter() {
int x, X, y, Y;
#Override public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
x = e.getXOnScreen();
X = obj.getLocation().x;
y = e.getYOnScreen();
Y = obj.getLocation().y;
}
}
#Override public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
obj.setLocation(X + (e.getXOnScreen() - x), Y + (e.getYOnScreen() - y));
}
}
#Override public void mouseReleased(MouseEvent e) {
if (info && SwingUtilities.isLeftMouseButton(e)) {
System.err.println(obj.toString().substring(0, obj.toString().indexOf("[")) + " (" + obj.getLocation().x + "," + obj.getLocation().y + ")");
}
}
};
obj.addMouseListener(d);
obj.addMouseMotionListener(d);
}

MouseListener is "halfway working" in my Applet

So I have been researching Applets and using Canvas and BufferStrategy on the applet. I have gotten it to buffer and show correctly but I'm thinking that it is somehow interfering with the MouseListener. When I run the Applet and re-size the screen, the MouseListener works outside my specified canvas. So when I move the mouse over where it is drawing, the mouse coordinates freeze. Then when I move the mouse off the canvas, it works. So it is nothing wrong with the MouseListener. I will include it anyway.
MouseMotion class:
public class MouseMotion implements MouseMotionListener{
private int x;
private int y;
public MouseMotion()
{
x = 0;
y = 0;
System.out.println("MouseMotion initialized");
}
public void mouseDragged(MouseEvent e) {}
public void mouseMoved(MouseEvent e)
{
x = e.getX();
y = e.getY();
}
//Return methods...
}
Mouse class:
public class Mouse implements MouseListener{
private int clickedX;
private int clickedY;
private int clickedButton;
private boolean pressed;
private int pressedX;
private int pressedY;
private int pressedButton;
public Mouse()
{
//Instantiates all the variables
System.out.println("Mouse initialized");
}
public void mouseClicked(MouseEvent e) {
clickedX = e.getX();
clickedY = e.getY();
clickedButton = e.getButton();
}
public void mousePressed(MouseEvent e) {
pressed = true;
pressedX = e.getX();
pressedY = e.getY();
pressedButton = e.getButton();
}
public void mouseReleased(MouseEvent e) {
pressed = false;
pressedX = 0;
pressedY = 0;
pressedButton = 0;
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
//Methods that return each variable...
}
The AppletMain class:
public class AppletMain extends Applet implements Runnable{
//Constants
private final int WIDTH = 720;
private final int HEIGHT = WIDTH / 16 * 9;
//Applet objects
private BufferStrategy bs;
private Canvas canvas;
//Game loop variables
...
//Engine objects
private Mouse mouse;
private MouseMotion mouseMotion;
public void init()
{
canvas = new Canvas();
mouse = new Mouse();
mouseMotion = new MouseMotion();
addMouseListener(mouse);
addMouseMotionListener(mouseMotion);
}
public void render()
{
//Setup graphics
Graphics2D g = (Graphics2D)bs.getDrawGraphics();
g.clearRect(0,0,WIDTH,HEIGHT);
//Just prints out the debugging stuff
g.setColor(Color.BLACK);
g.drawRect(0,0,WIDTH-1,HEIGHT-1);
g.drawString("TPS: " + Integer.toString(tps) + " FPS: " + Integer.toString(fps), 2,20);
g.drawString("MouseMotion: X - " + Integer.toString(mouseMotion.getX()) + " Y - " + Integer.toString(mouseMotion.getY()), 2,40);
g.drawString("Mouse(PRESSED): X - " + Integer.toString(mouse.getPressedX()) + " Y - " + Integer.toString(mouse.getPressedY()) + " button - " + Integer.toString(mouse.getPressedButton()), 2,60);
g.drawString("Mouse(CLICKED): X - " + Integer.toString(mouse.getClickedX()) + " Y - " + Integer.toString(mouse.getClickedY()) + " button - " + Integer.toString(mouse.getClickedButton()), 2,80);
//Cleanup graphics
g.dispose();
bs.show();
}
public void tick()
{
//Ticks the game
}
public void start()
{
if(bs == null)
{
setIgnoreRepaint(true);
canvas.setIgnoreRepaint(true);
canvas.setSize(WIDTH,HEIGHT);
setLayout(null);
add(canvas);
canvas.setLocation(0,0);
canvas.createBufferStrategy(3);
bs = canvas.getBufferStrategy();
}
new Thread(this).start();
canvas.requestFocus();
}
public void stop()
{
running = false;
}
public void destroy()
{
if(running)
running = false;
}
public void run()
{
init();
//Game loop that calls tick() and render() 60 times per second
}
}
In my code I drew black box around the canvas, and as I said before, when my mouse enters the black box the coordinates stop changing. The "fps" and "tps" keep going which are incremented by the game loop so I know that it is still running. When mouse exits the box, though, the coordinates again start changing as I move it around the window.
I tried to follow examples of other people and I believe I have. Maybe my approach to this is all wrong, I don't know, but any help, answers, comments, tips anything are greatly appreciated.

Categories

Resources