Jlabel Mouse Events for Drag and Drop

JLabel mouse events for Drag and Drop

Well, if I remember correctly, the drag and drop machinery catches all mouse events and processes them itself. Thus, the normal MouseEvents are not thrown anymore. You'd need to register a DropTargetListener on the JLabel's DropTarget.

Dragging a JLabel in a JPanel using Mouse Events

Add the MouseMotionListener to each of the labels instead of adding it to the panel. Then you don't need to determine whether you clicked on a label or not.

See the Component Mover for a general implementation. You would need to customize it to support the coloring requirement.

Edit:

If you add the listener to the panel then the coordinates will always be relative to the panel, not the label, so I'm not sure what the problem is. If you want to find if you clicked on a component then use the Container.getComponentAt(Point) method.

If you need more help then post your SSCCE that demonstrates the problem.

Java jLabel drag and drop from netbeans events context menu

As MadProgrammer pointed out, that was the issue. This is my mouse drag method:

private void jLabel2MouseDragged(java.awt.event.MouseEvent evt)  {                                     

Point p = SwingUtilities.convertPoint(evt.getComponent(), evt.getPoint(), getContentPane());
int x=p.x;
int y=p.y;

jLabel2.setLocation(x-120, y-120);
jLabel2.repaint();

}

The jLabel now moves smoothly.

My label is roughly 240x240 pixels, so I corrected the coordinates to have the center of the label placed where the mouse pointer is.

Thanks!

JLabel mouse events

See the Drag and Drop and Data Transfer lesson of the Java Tutorial.

How to drag and drop a JLabel into a JPanel

After looking at a few examples posted by @MadProgrammer I came up with a solution that extends both the JPanel and JLabel. Here is the JLabel class:

public class LayerItem extends JLabel {

public LayerItem(String text) {

this.setText(text);

this.setTransferHandler(new ValueExportTransferHandler(text));

this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
JLabel lbl = (JLabel) e.getSource();
TransferHandler handle = lbl.getTransferHandler();
handle.exportAsDrag(lbl, e, TransferHandler.COPY);
}
});

}

protected static class ValueExportTransferHandler extends TransferHandler {

public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;
private String value;

public ValueExportTransferHandler(String value) {
this.value = value;
}

public String getValue() {
return value;
}

@Override
public int getSourceActions(JComponent c) {
return DnDConstants.ACTION_COPY_OR_MOVE;
}

@Override
protected Transferable createTransferable(JComponent c) {
Transferable t = new StringSelection(getValue());
return t;
}

@Override
protected void exportDone(JComponent source, Transferable data, int action) {
super.exportDone(source, data, action);
// Clean up and remove the LayerItem that was moved
((LayerItem) source).setVisible(false);
((LayerItem) source).getParent().remove((LayerItem) source);
}

}
}

Here is the class for the JPanel:

public class LayerContainer extends JPanel {

public LayerContainer() {
this.setTransferHandler(new ValueImportTransferHandler());
this.setLayout(new GridBagLayout()); // Optional layout
this.setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY), new EmptyBorder(20, 20, 20, 20))); // Optional border
}

protected static class ValueImportTransferHandler extends TransferHandler {

public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;

public ValueImportTransferHandler() {
}

@Override
public boolean canImport(TransferHandler.TransferSupport support) {
return support.isDataFlavorSupported(SUPPORTED_DATE_FLAVOR);
}

@Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Object value = t.getTransferData(SUPPORTED_DATE_FLAVOR);
if (value instanceof String) { // Ensure no errors
// TODO: here you can create your own handler
// ie: ((LayerContainer) component).getHandler()....
Component component = support.getComponent();
LayerItem j = new LayerItem((String) value);
((LayerContainer) component).add(j); // Add a new drag JLabel
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}

}

Here is an example of how you could use this (drag from one JPanel to another and back again):

    JPanel left_panel = new LayerContainer();
panel_1.setBounds(28, 47, 129, 97);
add(panel_1);

LayerContainer right_panel = new LayerContainer();
layerContainer.setBounds(203, 47, 129, 97);
add(layerContainer);

JLabel lblToDrag = new LayerItem("Drag Me");
GridBagConstraints gbc_lblToDrag = new GridBagConstraints();
gbc_lblDragMe.gridx = 0;
gbc_lblDragMe.gridy = 0;
panel_right.add(lblToDrag, gbc_lblToDrag);

For future use, I'll create a onTransfer() method and create my own LayerContainerHandler() which overrites a run() method so each time a Label is moved to different Containers, it execute seperate actions.

Java Drag and Drop and Mouse Listeners

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.

How can i drag and adjust icon of jLabel according to mouse movements without scrollbars?

Your first port of call should be How to Write a Mouse Listener, as MouseInfo really isn't the right tool for this job.

One solution might be to use a JScrollPane, but remove the scroll bars, the benefit of this is, it takes care of the bounds checking and component resizing for you automatically...

Scroll Me

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private JLabel label;

public TestPane() {
setLayout(new BorderLayout());
try {
label = new JLabel(new ImageIcon(ImageIO.read(...)));
label.setAutoscrolls(true);
JScrollPane scrollPane = new JScrollPane(label, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBorder(null);
add(scrollPane);

MouseAdapter ma = new MouseAdapter() {

private Point origin;

@Override
public void mousePressed(MouseEvent e) {
origin = new Point(e.getPoint());
}

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseDragged(MouseEvent e) {
if (origin != null) {
JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, label);
if (viewPort != null) {
int deltaX = origin.x - e.getX();
int deltaY = origin.y - e.getY();

Rectangle view = viewPort.getViewRect();
view.x += deltaX;
view.y += deltaY;

label.scrollRectToVisible(view);
}
}
}

};

label.addMouseListener(ma);
label.addMouseMotionListener(ma);
} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

}

}

In fact, this solution is so simple, any other is just asking for trouble



Related Topics



Leave a reply



Submit