Reputation: 14371
I am using logic like the following with a touch interface, so I'd like to be able to use mousePressed to initiate a drag, yet at the same time be able to use mouseClicked or mouseReleased if the user does not drag.
On mousePressed, I have a drag being started. On mouseClicked, I want it to print out "mouseClicked", and to print mouseReleased on "mouseReleased" but for some reason the
dropLabel.getTransferHandler().exportAsDrag(dropLabel, e,
TransferHandler.COPY);
swallows the event causing mouseClicked and mouseReleased events not be fired even when I don't move the mouse. Notice that commenting out that line causes all listeners to be fired (but obviously the drag isn't started).
How can I get all mouse events to happen the way I want, specifically mouseClicked/mouseReleased when the user doesn't do any dragging, while still being able to exportAsDragged if the user does drag? Any hacks/cracks/reflection solutions are welcome.
Here is some sample code I am working with that illustrates my actual problem:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;
public class DragTest extends JFrame implements MouseMotionListener,
MouseListener {
private JPanel leftPanel = new JPanel(null);
private JPanel rightPanel = new JPanel(null);
JLabel dropLabel;
public DragTest() {
this.setLayout(new GridLayout(1, 2));
leftPanel.setBorder(BorderFactory.createLineBorder(Color.black));
rightPanel.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(leftPanel);
this.add(rightPanel);
leftPanel.addMouseListener(this);
leftPanel.addMouseMotionListener(this);
JTextArea area = new JTextArea();
rightPanel.setLayout(new GridLayout(1, 1));
rightPanel.add(area);
dropLabel = new JLabel("drop");
dropLabel.setTransferHandler(new TransferHandler("text"));
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
Dimension labelSize = dropLabel.getPreferredSize();
dropLabel.setSize(labelSize);
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
dropLabel.setLocation(x, y);
leftPanel.add(dropLabel);
dropLabel.getTransferHandler().exportAsDrag(dropLabel, e,
TransferHandler.COPY);
repaint();
}
@Override
public void mouseDragged(MouseEvent me) {
System.out.println("mouseDragged");
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased");
}
@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);
}
}
Upvotes: 4
Views: 19210
Reputation: 1
@Override
public void mouseDragged(MouseEvent e) {
System.out.println(String.format("[mouseDragged] (%d, %d)", e.getX(),e.getY()));
Dimension labelSize = dropLabel.getPreferredSize();
dropLabel.setSize(labelSize);
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
dropLabel.setLocation(x, y);
leftPanel.add(dropLabel);
repaint();
}
Mouse Event..??
Upvotes: -2
Reputation: 7326
Do you really need the mouseReleased to fire or what? I think this should work well:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;
public class DragTest extends JFrame implements MouseMotionListener,
MouseListener {
private JPanel leftPanel = new JPanel(null);
private JPanel rightPanel = new JPanel(null);
JLabel dropLabel;
public DragTest() {
this.setLayout(new GridLayout(1, 2));
leftPanel.setBorder(BorderFactory.createLineBorder(Color.black));
rightPanel.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(leftPanel);
this.add(rightPanel);
leftPanel.addMouseListener(this);
leftPanel.addMouseMotionListener(this);
JTextArea area = new JTextArea();
rightPanel.setLayout(new GridLayout(1, 1));
rightPanel.add(area);
dropLabel = new JLabel("drop");
dropLabel.setTransferHandler(new TransferHandler("text"));
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
Dimension labelSize = dropLabel.getPreferredSize();
dropLabel.setSize(labelSize);
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
dropLabel.setLocation(x, y);
leftPanel.add(dropLabel);
repaint();
}
@Override
public void mouseDragged(MouseEvent me) {
System.out.println("mouseDragged");
dropLabel.getTransferHandler().exportAsDrag(dropLabel, me,
TransferHandler.COPY);
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased");
}
@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);
}
}
I just moved the call to start the drag event into the mouseDragged call, this way if you just click your mouse then everything calls normally. However, if you drag the mouse, it will fire the drag and drop call, which still does block other calls, but again only if you drag. If you just click, it all fires normally.
Upvotes: 8