I am trying to make a PacMan alternative with a tiger chasing bagels (don't ask why). I'm on the first stage still, trying to make the tiger move around the JFrame. However, now that I implemented the KeyEvent, the image is no longer showing up. I have been stuck on this for an hour, and I don't understand where I went wrong.
Edit: I have got the image to show up, but the image does not update or change location when pressing on the arrow keys, probably something to do with the connection between the KeyEvent and the PacMan class.
Main:
public Main() {
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
UI frame = null;
try {
frame = new UI();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
});
}
UI:
public PacMan PacMan;
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_RIGHT){
PacMan.moveRight();
}
if (key == KeyEvent.VK_LEFT){
PacMan.moveLeft();
}
if (key == KeyEvent.VK_UP){
PacMan.moveUp();
}
if (key == KeyEvent.VK_DOWN){
PacMan.moveDown();
}
}
public UI() throws IOException {
this.PacMan = new PacMan();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setTitle("PacMan");
frame.setResizable(false);
frame.setSize(1200, 700);
frame.setMinimumSize(new Dimension(1200, 700));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setBackground(Color.BLACK);
panel.add(PacMan.getImage());
frame.add(panel);
frame.setVisible(true);
}
PacMan:
public int xCoords = 570;
public int yCoords = 320;
JLabel pacManImage = new JLabel();
Icon tigerLeft;
Icon tigerRight;
public PacMan() throws IOException {
ImageIcon tigerLeft = new ImageIcon(new ImageIcon("textures/tigerLeft.png").getImage().getScaledInstance(60, 40, Image.SCALE_DEFAULT));
ImageIcon tigerRight = new ImageIcon(new ImageIcon("textures/tigerRight.png").getImage().getScaledInstance(60, 40, Image.SCALE_DEFAULT));
pacManImage.setIcon(tigerRight);
pacManImage.setVisible(true);
}
public void initialDraw() {
pacManImage.setBounds(xCoords, yCoords, 60, 40);
pacManImage.setIcon(tigerRight);
pacManImage.repaint();
}
public void moveRight() {
System.out.println("here: " + tigerRight);
//xCoords = xCoords + 2;
pacManImage.setIcon(tigerRight);
pacManImage.setLocation(pacManImage.getLocationOnScreen().x + 2, pacManImage.getLocationOnScreen().y);
pacManImage.repaint();
}
public void moveLeft() {
//xCoords = xCoords + 2;
pacManImage.setIcon(tigerLeft);
pacManImage.setLocation(pacManImage.getLocationOnScreen().x - 2, pacManImage.getLocationOnScreen().y);
pacManImage.repaint();
}
public void moveUp() {
//yCoords = yCoords + 2;
pacManImage.setLocation(pacManImage.getLocationOnScreen().x, pacManImage.getLocationOnScreen().y - 2);
pacManImage.repaint();
}
public void moveDown() {
//yCoords = yCoords + 2;
pacManImage.setLocation(pacManImage.getLocationOnScreen().x, pacManImage.getLocationOnScreen().y + 2);
pacManImage.repaint();
}
public JLabel getImage(){
return pacManImage;
}
Your UI class is not complete so I can't tell exactly what you are doing. I can only guess.
Ignoring the actual KeyListener code, my guess is you have code like:
public class UI extends JPanel
{
public UI() throws IOException
{
this.PacMan = new PacMan();
addKeyListener(this);
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
panel.add(PacMan.getImage());
frame.add(panel);
frame.setVisible(true);
}
}
So once again you have two JPanel components:
the UI class "is a" JPanel and you add the KeyListener to it.
then you create a second JPanel and add the "PacMan" to that panel and add that panel to the frame.
So the problem is the first panel has the KeyListener but it is never added to the frame.
Your class should look like:
public class UI extends JPanel
{
public UI() throws IOException
{
this.PacMan = new PacMan();
addKeyListener(this);
setBackground(Color.BLACK);
add(PacMan.getImage());
}
}
That's it. The creation of the frame does not belong in this class.
I found out that my keyReleased function was never being called, and I fixed that issue by issuing the simplest fix, moving the KeyListener within the UI method.
UI class code:
public class UI extends JPanel {
public PacMan PacMan;
public UI() throws IOException {
this.PacMan = new PacMan();
addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN){
PacMan.moveDown();
}
if (e.getKeyCode() == KeyEvent.VK_UP){
PacMan.moveUp();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
PacMan.moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
PacMan.moveRight();
}
}
#Override
public void keyReleased(KeyEvent e) {}
#Override
public void keyTyped(KeyEvent e) {}
});
setFocusable(true);
setBackground(Color.BLACK);
add(PacMan.getImage());
}
Related
So I am new to event handlers, and I wanted to create a program where I made a Purple panel inside a frame and if the user clicks the mouse button in the area of the panel and then types % with their keyboard, I want the panel to draw a line segment in the area of the panel. This is just testing the event handlers. Right now, I am trying it but it does not work. All help will be appreciated. After I get the hand of this, I want to try out the repaint() method, where if someone does the same actions as before, I wanted to check the background of the Panel. If you can help me with both, that'd be awesome but it is not a priority. Thank you.
import java.awt.Graphics; // for classes Graphics, Color, Font, Image
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyEvent; // for classes KeyListener, MouseListener
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame; // for classes JFrame, JPanel, JLabel
import javax.swing.JPanel;
public class GardenGrows
{
public GardenGrows()
{
}
public static void main(String[] args)
{
GardenGrows gg = new GardenGrows();
gg.runIt();
}
// makes the frame and handles all properties of the frame
// also instantiates the Garden.java object
public void runIt()
{
JFrame frame = new JFrame ("Garden");
frame.setDefaultCloseOperation( frame.EXIT_ON_CLOSE );
frame.setLayout(null);
frame.setBackground(Color.GRAY);
frame.setSize( 1200,700);
frame.setLocation( 50, 10);
frame.setResizable(true);
frame.setVisible(true);
Garden gar = new Garden();
frame.getContentPane().add(gar);
}
}
class Garden extends JPanel implements KeyListener, MouseListener
{
private boolean mouseClicked;
private boolean keyClicked;
private int xpos;
private int ypos;
public Garden()
{
mouseClicked = false;
keyClicked = false;
addKeyListener(this);
addMouseListener(this);
setBackground(Color.PINK);
setLocation(50,50);
setSize(1000,500);
}
public void mousePressed(MouseEvent evt)
{
int x = evt.getX();
int y = evt.getY();
if(x>=50 || x<=1050 && y<=50 || y>=550)
{
mouseClicked = true;
}
}
public void mouseClicked(MouseEvent evt){}
public void mouseReleased(MouseEvent evt){}
public void mouseEntered(MouseEvent evt){}
public void mouseExited(MouseEvent evt){}
public void keyReleased(KeyEvent evt){}
public void keyPressed(KeyEvent evt){}
public void keyTyped(KeyEvent evt)
{
int letter = evt.getKeyCode();
if (letter == 13)
{
keyClicked =true;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(keyClicked && mouseClicked)
g.drawLine(50,0,110,120);
}
}
Making a key listener work in a JPanel, will not be so simple, because it is not focusable. (Think about a JTextField, when you write text on it, it is focused). So, in order to make this work you will have to use KeyBindings. In practice, remove the KeyListener implementation from your JPanel, and use KeyBindings.
public class GardenGrows {
public GardenGrows() {
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// All swing applications must run on EDT Thread
GardenGrows gg = new GardenGrows();
gg.runIt();
});
}
// makes the frame and handles all properties of the frame
// also instantiates the Garden.java object
public void runIt() {
JFrame frame = new JFrame("Garden");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setBackground(Color.GRAY);
frame.setSize(1200, 700);
frame.setLocation(50, 10);
frame.setResizable(true);
frame.setVisible(true);
Garden gar = new Garden();
frame.getContentPane().add(gar);
}
}
class Garden extends JPanel implements MouseListener {
private boolean mouseClicked;
private boolean keyClicked;
private int xpos;
private int ypos;
public Garden() {
mouseClicked = false;
keyClicked = false;
addMouseListener(this);
setBackground(Color.PINK);
setLocation(50, 50);
setSize(1000, 500);
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_5, KeyEvent.SHIFT_MASK),
"percentageClicked");
getActionMap().put("percentageClicked", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
keyClicked = true;
repaint(); // Try to draw the line
}
});
}
public void mousePressed(MouseEvent evt) {
int x = evt.getX();
int y = evt.getY();
if (x >= 50 || x <= 1050 && y <= 50 || y >= 550) {
mouseClicked = true;
repaint(); // Try to draw the line
}
}
public void mouseClicked(MouseEvent evt) {
}
public void mouseReleased(MouseEvent evt) {
}
public void mouseEntered(MouseEvent evt) {
}
public void mouseExited(MouseEvent evt) {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (keyClicked && mouseClicked)
g.drawLine(50, 0, 110, 120);
}
}
At university we started Java programming and got the task to write a program that draws a vertical and a horizontal line at the location where the mouse currently is. Also we should add a Label that shows the coordinates of the mouse. I got the drawing thing working but when I try to add a label, it won't show up? I started with a test-label, but even that isn't shown inside the frame. Can someone help me?
public class Coordinates extends JPanel implements MouseListener, MouseMotionListener {
private Point currentPoint = new Point(-50, -50);
public Coordinates(){
addMouseListener(this);
addMouseMotionListener(this);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.blue);
g.drawLine(currentPoint.x, currentPoint.y+1000, currentPoint.x, currentPoint.y-1000);
g.drawLine(currentPoint.x+1000, currentPoint.y, currentPoint.x-1000, currentPoint.y);
}
public void mousePressed(MouseEvent e){
currentPoint = e.getPoint();
repaint();
};
static JLabel label = new JLabel();
public static void main(String[] args) {
JFrame frame = new JFrame("Koordinaten");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(label);
JComponent newContentPane = new Coordinaten();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
}
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
label.setText(currentPoint.toString());
currentPoint = e.getPoint();
repaint();
}
}
Do all your painting within the JPanel's paintComponent method not the paint method, and be sure to call the super's paintComponent method within your override, usually at the start of the override method.
You need to add a JLabel to your JPanel to have it display anything. Your code does not do this. And then in the MouseMotionListener, set the JLabel's text with the mouse coordinates.
For example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private JLabel locationLabel = new JLabel();
public DrawPanel() {
add(locationLabel);
addMouseMotionListener(new MyMouseAdapter());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // this allows JPanel to do housekeeping painting first
// do drawing here!
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
// get Point location and turn into a String
String location = String.format("[%d, %d]", e.getX(), e.getY());
// set the label's text with this String
locationLabel.setText(location);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
With the cross-hairs:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private JLabel locationLabel = new JLabel();
private int mouseX = 0;
private int mouseY = 0;
public DrawPanel() {
add(locationLabel);
addMouseMotionListener(new MyMouseAdapter());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // this allows JPanel to do housekeeping
// painting first
// do drawing here!
g.drawLine(0, mouseY, getWidth(), mouseY);
g.drawLine(mouseX, 0, mouseX, getHeight());
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
// get Point location and turn into a String
String location = String.format("[%d, %d]", mouseX, mouseY);
// set the label's text with this String
locationLabel.setText(location);
repaint();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DrawPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DrawPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Basically, a JLabel is made like this, defined outside of the main method:
static JLabel label = new JLabel();
In your main method
frame.add(label);
And in your mouseMoved method you would put this:
label.setText(currentPoint.toString());
I'm trying to create a hold button on Java for my bandit machine, when pressed it will hold that image and the other 2 images will keep spinning. Anyone know the code to allow that to happen?
if (e.getSource()== btnaddcash){
txtbalance.setForeground(Color.red);
cash = cash + 100;
txtbalance.setText(cash + "");
if (e.getSource() == btnpic1){
The basic concept is, you want to spin an image (or take some action) while the button is "armed".
A way by which you can achieve this is to add a ChangeListener to the button and monitor the ButtonModel#isArmed state.
public class ChangeButton {
public static void main(String[] args) {
new ChangeButton();
}
public ChangeButton() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new SlotPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SlotPaneextends JPanel {
private SpinPane spinPane;
private JButton button;
public SlotPane() {
spinPane = new SpinPane();
button = new JButton("Press");
// I've attached directly to the model, I don't
// think this is required, simply attaching a change
// listener to the button achieve the same result.
button.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
spinPane.setSpinning(button.getModel().isArmed());
}
});
setLayout(new BorderLayout());
add(spinPane);
add(button, BorderLayout.SOUTH);
}
}
public class SpinPane extends JPanel {
private BufferedImage mole;
private Timer timer;
private float angel = 0;
public SpinPane() {
try {
mole = ImageIO.read(new File("mole.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
timer = new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
angel += 15;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
}
#Override
public Dimension getPreferredSize() {
return mole == null ? super.getPreferredSize() : new Dimension(mole.getWidth(), mole.getHeight());
}
public void setSpinning(boolean spinning) {
if (spinning) {
if (!timer.isRunning()) {
timer.restart();
}
} else {
timer.stop();
}
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (mole != null) {
int x = (getWidth() - mole.getWidth()) / 2;
int y = (getHeight() - mole.getHeight()) / 2;
Graphics2D g2d = (Graphics2D) g.create();
g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angel), getWidth() / 2, getHeight() / 2));
g2d.drawImage(mole, x, y, this);
g2d.dispose();
}
}
}
}
I have a program where I am creating a JLabel on a click and then dragging that to another portion of the interface.
What I want is to click somewhere in the JPanel, have it drop a JLabel there, and then drag another JLabel all in the same click.
I am able to do this, but it takes multiple clicks. Can I do it in one click?
To illustrate what I mean, I created this sample program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DragTest extends JFrame implements MouseMotionListener,
MouseListener {
private JPanel panel = new JPanel(null);
private JLabel dragLabel = new JLabel("drag");;
private final JWindow window = new JWindow();
public DragTest() {
this.add(panel);
panel.addMouseListener(this);
dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
}
#Override
public void mouseDragged(MouseEvent me) {
dragLabel = new JLabel("drag");
dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
int x = me.getPoint().x;
int y = me.getPoint().y;
window.add(dragLabel);
window.pack();
Point pt = new Point(x, y);
Component c = (Component) me.getSource();
SwingUtilities.convertPointToScreen(pt, c);
window.setLocation(pt);
window.setVisible(true);
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
JLabel dropLabel = new JLabel("drop");
panel.add(dropLabel);
dropLabel.setForeground(Color.RED);
dropLabel.setFont(new Font("Serif", Font.BOLD, 48));
dropLabel.setBounds(e.getX(), e.getY(), 100, 60);
dropLabel.addMouseMotionListener(this);
dropLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
dragLabel.setVisible(false);
window.setVisible(false);
}
});
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args) {
DragTest frame = new DragTest();
frame.setVisible(true);
frame.setSize(600, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
So the initial click creates the "drop" JLabel, and then clicking on and dragging on the "drop" JLabel will create a "drag" JLabel that follows the mouse around.
How can I do this in one click and drag?
Don't create a new JLabel in the mouseDragged method but rather use the same JLabel. For example:
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class DragTest2 extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = 400;
private static final float LABEL_PTS = 24f;
private static final String LABEL_TEXT = "My Label";
private JLabel label = null;
public DragTest2() {
setLayout(null);
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
label = new JLabel(LABEL_TEXT);
label.setFont(label.getFont().deriveFont(LABEL_PTS));
Dimension labelSize = label.getPreferredSize();
label.setSize(labelSize);
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
add(label);
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (label != null) {
Dimension labelSize = label.getPreferredSize();
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
repaint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (label != null) {
Dimension labelSize = label.getPreferredSize();
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
repaint();
label = null;
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DragTest2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DragTest2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
The blue label is meant to move when you click and drag it. This works but the x / y position then jumps in a funny way.
Here's the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class test extends JFrame implements MouseListener, MouseMotionListener {
private JPanel panel = new JPanel(null);
private JLabel label1 = new JLabel();
private JLabel label2 = new JLabel();
private int mouseX = 200;
private int mouseY = 100;
private boolean drag = false;
public test() {
this.add(panel);
panel.setBackground(Color.WHITE);
panel.add(label1);
label1.setOpaque(true);
label1.setBackground(Color.BLUE);
label1.setBounds(mouseX, mouseY, 100, 50);
label1.addMouseMotionListener(this);
label1.addMouseListener(this);
panel.add(label2);
label2.setOpaque(true);
label2.setBackground(Color.RED);
label2.setBounds(mouseX + 200, mouseY, 100, 50);
label2.addMouseMotionListener(this);
label2.addMouseListener(this);
}
#Override
public void mousePressed(MouseEvent e) {
if (e.getSource() == label1) {
drag = true;
}
}
#Override
public void mouseReleased(MouseEvent e) {
drag = false;
}
#Override
public void mouseDragged(MouseEvent e) {
if (drag == true) {
mouseX = e.getX();
mouseY = e.getY();
label1.setBounds(mouseX, mouseY, 100, 50);
}
}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public static void main(String[] args) {
test frame = new test();
frame.setVisible(true);
frame.setSize(600, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Just put this on your MouseDragged method:
public void mouseDragged(MouseEvent e)
{
if (drag == true)
{
JComponent jc = (JComponent)e.getSource();
jc.setLocation(jc.getX()+e.getX(), jc.getY()+e.getY());
}
}
The coordinates returned by MouseEvent::getX() and MouseEvent::getY() represent the location of the event relative to the event's subject (i.e. relative to the label itself), which explains why your solution results in the label erratically jumping.
By using MouseEvent::getComponent() to grab the label and then querying its position (possibly relative to the position when dragging commenced), you can devise a working solution.
Your problem is your setting your bounds based on the mouse location in the MouseListener, but the MouseListener has its location relative to the JLabel itself, but the JLabel's location should be set relative to the panel. You'll need to do some simple vector addition to figure this out.
edit: oops, I didn't see that this was already answered, and they say the same thing... sorry.
Maybe try adding something like that
The red one will do it better
private int clicX = 0;
private int clicY = 0;
public void mousePressed(MouseEvent e) {
drag = true;
if (e.getSource() == label1) {
}
if (e.getSource() == label2) {
clicX = e.getX();
clicY = e.getY();
}
}
public void mouseDragged(MouseEvent e) {
if (e.getSource() == label2) {
JComponent jc = (JComponent)e.getSource();
jc.setLocation(jc.getX()+e.getX()-clicX, jc.getY()+e.getY()-clicY);
}
Create two global variables:
int x_pressed = 0;
int y_pressed = 0;
then create two events (mousePressed and mouseDragged over JLabel):
lbl_banner.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e) {
//catching the current values for x,y coordinates on screen
x_pressed = e.getX();
y_pressed = e.getY();
}
});
lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){
#Override
public void mouseDragged(MouseEvent e){
//and when the Jlabel is dragged
setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed);
}
});