how to drag my component and place it anywhere on the panel
i make a dragable component :
//class: DragAbleComponent.the father of my component
import java.awt.Graphics;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.accessibility.Accessible;
import javax.swing.JComponent;
publicabstractclass DragAbleComponentextends JComponentimplements MouseListener,
FocusListener, Accessible ,MouseMotionListener{
privateint X;
privateint Y;
/**
*
*/
privatestaticfinallong serialVersionUID = 1;
publicvoid mouseClicked(MouseEvent e){
this.requestFocusInWindow();
}
publicvoid mouseEntered(MouseEvent e){}
publicvoid mouseExited(MouseEvent e){}
publicvoid mousePressed(MouseEvent e){}
publicvoid mouseReleased(MouseEvent e){}
publicvoid focusGained(FocusEvent e){
this.repaint();}
publicvoid focusLost(FocusEvent e){
this.repaint();}
protectedabstractvoid paintComponent(Graphics graphics);
publicint getX(){
return X;
}
publicvoid setX(int x){
X = x;
}
publicint getY(){
return Y;
}
publicvoid setY(int y){
Y = y;
}
}
//class:DragableIcon the component
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.TransferHandler;
publicclass DragableIconextends DragAbleComponent{
private Image image;
private MouseEvent firstMouseEvent =null;
privatestaticboolean installKeyBordMapings =true;
/**
*
*/
privatestaticfinallong serialVersionUID = 1;
public DragableIcon(Image image){
super();
this.image = image;
this.setFocusable(true);
this.addMouseListener(this);
this.addFocusListener(this);
this.addMouseMotionListener(this);
this.initKeyBordMaping();
}
privatevoid initKeyBordMaping(){
if (installKeyBordMapings){
InputMap imap = this.getInputMap();
// imap.put(KeyStroke.getKeyStroke("ctrl X"),
// TransferHandler.getCutAction().getValue(Action.NAME));
imap.put(KeyStroke.getKeyStroke("ctrl C"),
TransferHandler.getCopyAction().getValue(Action.NAME));
imap.put(KeyStroke.getKeyStroke("ctrl V"),
TransferHandler.getPasteAction().getValue(Action.NAME));
}
ActionMap map = this.getActionMap();
// map.put(TransferHandler.getCutAction().getValue(Action.NAME),
// TransferHandler.getCutAction());
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
}
@Override
protectedvoid paintComponent(Graphics graphics){
Graphics g = graphics.create();
//Draw in our entire space, even if isOpaque is false.
g.setColor(Color.WHITE);
g.fillRect(0, 0, image ==null ? 125 : image.getWidth(this),
image ==null ? 125 : image.getHeight(this));
if (image !=null){
//Draw image at its natural size of 125x125.
g.drawImage(image, 0, 0,this);
}
//Add a border, red if picture currently has focus
if (isFocusOwner()){
g.setColor(Color.RED);
}else{
g.setColor(Color.BLACK);
}
g.drawRect(0, 0, image ==null ? 125 : image.getWidth(this),
image ==null ? 125 : image.getHeight(this));
// g.drawImage(image, 0, 0, this);
g.dispose();
}
publicvoid mouseDragged(MouseEvent e){
//Don't bother to drag if the component displays no image.
if (image ==null)return;
if (firstMouseEvent !=null){
e.consume();
//If they are holding down the control key, COPY rather than MOVE
int ctrlMask = InputEvent.CTRL_DOWN_MASK;
int action = ((e.getModifiersEx() & ctrlMask) == ctrlMask) ?
TransferHandler.COPY : TransferHandler.MOVE;
int dx = Math.abs(e.getX() - firstMouseEvent.getX());
int dy = Math.abs(e.getY() - firstMouseEvent.getY());
//Arbitrarily define a 5-pixel shift as the
//official beginning of a drag.
if (dx > 5 || dy > 5){
//This is a drag, not a click.
JComponent c = (JComponent)e.getSource();
TransferHandler handler = c.getTransferHandler();
//Tell the transfer handler to initiate the drag.
handler.exportAsDrag(c, firstMouseEvent, action);
firstMouseEvent =null;
}
}
}
publicvoid mouseMoved(MouseEvent e){}
publicvoid mousePressed(MouseEvent e){
//Don't bother to drag if there is no image.
if (image ==null)return;
firstMouseEvent = e;
e.consume();
}
publicvoid mouseReleased(MouseEvent e){
firstMouseEvent =null;
}
publicstaticboolean isInstallKeyBordMapings(){
return installKeyBordMapings;
}
publicstaticvoid setInstallKeyBordMapings(boolean installKeyBordMapings){
DragableIcon.installKeyBordMapings = installKeyBordMapings;
}
public Image getImage(){
return image;
}
publicvoid setImage(Image image){
this.image = image;
}
}
//here is my handler
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
import cn.com.ynld.bms.applet.gui.component.DragableIcon;
;
publicclass IconTransferHandlerextends TransferHandler{
/**
*
*/
privatestaticfinallong serialVersionUID = 1;
DataFlavor pictureFlavor = DataFlavor.imageFlavor;
DragableIcon sourceIcon;
boolean shouldRemove;
publicboolean importData(JComponent c, Transferable t){
System.out.println("begin to import image-->");
Image image;
if (canImport(c, t.getTransferDataFlavors())){
DragableIcon icon = (DragableIcon)c;
//Don't drop on myself.
if (sourceIcon == icon){
shouldRemove =false;
returntrue;
}
try{
image = (Image)t.getTransferData(pictureFlavor);
//Set the component to the new picture.
icon.setImage(image);
returntrue;
}catch (UnsupportedFlavorException ufe){
System.out.println("importData: unsupported data flavor");
}catch (IOException ioe){
System.out.println("importData: I/O exception");
}
}
returnfalse;
}
protected Transferable createTransferable(JComponent c){
sourceIcon = (DragableIcon)c;
shouldRemove =true;
returnnew IconTransferable(sourceIcon);
}
publicint getSourceActions(JComponent c){
return COPY;
}
protectedvoid exportDone(JComponent c, Transferable data,int action){
//if (shouldRemove && (action == MOVE)) {
//sourceIcon.setImage(null);
//}
//sourceIcon = null;
}
publicboolean canImport(JComponent c, DataFlavor[] flavors){
//for (int i = 0; i < flavors.length; i++) {
//if (pictureFlavor.equals(flavors[i])) {
//return true;
//}
//}
returntrue;
}
class IconTransferableimplements Transferable{
private Image image;
IconTransferable(DragableIcon icon){
image = icon.getImage();
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException{
if (!isDataFlavorSupported(flavor)){
thrownew UnsupportedFlavorException(flavor);
}
return image;
}
public DataFlavor[] getTransferDataFlavors(){
returnnew DataFlavor[]{ pictureFlavor};
}
publicboolean isDataFlavorSupported(DataFlavor flavor){
return pictureFlavor.equals(flavor);
}
}
}
i add a handler to my DragableIcon and pane both(copy DragableIcon to my pane);
the draging seem worked(drag icon) but place dose't (he even did't invoke the method importData) )
what' can i do?
thanks for any help!
[18656 byte] By [
dxuranua] at [2007-10-3 2:45:59]

This approach to drag-and-drop is generally used for copying and/or moving images from
one component to another or to other applications. If you just want to move an image
around in its parent component consider this
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class DI extends JPanel {
private BufferedImage image;
Rectangle r;
public DI(BufferedImage image) {
super();
this.image = image;
r = new Rectangle(10, 10, image.getWidth(), image.getHeight());
this.setFocusable(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(image, r.x, r.y, this);
//Add a border, red if picture currently has focus
if (isFocusOwner()) {
g.setColor(Color.RED);
} else {
g.setColor(Color.BLACK);
}
g2.draw(r);
}
public void setRect(int x, int y) {
r.x = x;
r.y = y;
repaint();
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
r.setSize(image.getWidth(), image.getHeight());
}
public static void main(String[] args) throws IOException {
File file = new File("images/cougar.jpg");
BufferedImage image = ImageIO.read(file);
DI test = new DI(image);
DragHandler handler = new DragHandler(test);
test.addMouseListener(handler);
test.addMouseMotionListener(handler);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(test);
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
class DragHandler extends MouseInputAdapter {
DI di;
Point offset;
boolean dragging;
public DragHandler(DI di) {
this.di = di;
offset = new Point();
dragging = false;
}
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
if(di.r.contains(p)) {
offset.x = p.x - di.r.x;
offset.y = p.y - di.r.y;
dragging = true;
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
}
public void mouseDragged(MouseEvent e) {
if(dragging) {
int x = e.getX() - offset.x;
int y = e.getY() - offset.y;
di.setRect(x, y);
}
}
}
thanks for your reply!
the method you given worked prttey well.but i still can't implement what i want.
i am a newby to swing and i have some complicated (at least for me)thing to implement. after three day searching it got me more confusing.
what i want is: an applet which has a big map(draw) on center contentpane and a toolbar (or panel or popupmenu)which i lay some components(i make.just draw a little image )on .for these components i can
drag (copy) them from toolbar (or panel or popupmenu) and drop temp on map.
The problems i encounter are.
1,i can't place my components on toolbar.
2,when i add these components on panel and try to place panel on contentpane(applet)'s west (i use BordLayout)i can't saw them .
so how to make this component(just show a image,can be placed on toolbar or JPopupMenu,can be draged anywhere)
my email is dxuranus@gmail.com
waiting for your replay.
thanks
I made this by modeling and copying code from the DragPictureDemo2 in the tutorial.
It works okay with the other classes used as-is, ie, no changes made to them.
Image files from [url=http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/index.html]Examples 1.4[/url] down low on page.
// <applet code="DropApplet" width="560" height="480"></applet>
// use: >appletviewer DropApplet.java
import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class DropApplet extends JApplet
{
DTPicture pic1, pic2, pic3, pic4, pic5, pic6,
pic7, pic8, pic9, pic10, pic11, pic12;
static String cString= "Chin";
static String cgString = "Chin & Glasses";
static String chString = "Chin & Hat";
static String ctString = "Chin & Teeth";
static String gString= "Glasses";
static String hString= "Hat";
static String tString= "Teeth";
static String cghString = "Chin, Glasses & Hat";
PictureTransferHandler picHandler;
public void init()
{
getContentPane().setLayout(new BorderLayout());
picHandler = new PictureTransferHandler();
DTPicture.setInstallInputMapBindings(false);
createPictures();
getContentPane().add(createMenuBar(), "North");
getContentPane().add(getCenterPanel());
getContentPane().add(getWestPanel(), "West");
}
private JPanel getCenterPanel()
{
JPanel panel = new JPanel(new GridLayout(0,3));
panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
panel.add(pic1);
panel.add(pic2);
panel.add(pic3);
panel.add(pic4);
panel.add(pic9);
panel.add(pic10);
panel.add(pic11);
panel.add(pic12);
return panel;
}
private JPanel getWestPanel()
{
JPanel panel = new JPanel(new GridLayout(0,1));
panel.setBackground(Color.pink);
panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
panel.add(pic5);
panel.add(pic6);
panel.add(pic7);
panel.add(pic8);
return panel;
}
private void createPictures()
{
String prefix = "images/geek";
String ext = ".gif";
String[] paths =
{
"-c", "-cg--", "-c-h-", "-c--t", "--g--", "h-", "-t", "-cgh-"
};
pic1 = new DTPicture(createImageIcon(prefix + paths[0] + ext,
cString).getImage());
pic1.setTransferHandler(picHandler);
pic2 = new DTPicture(createImageIcon(prefix + paths[1] + ext,
cgString).getImage());
pic2.setTransferHandler(picHandler);
pic3 = new DTPicture(createImageIcon(prefix + paths[2] + ext,
chString).getImage());
pic3.setTransferHandler(picHandler);
pic4 = new DTPicture(createImageIcon(prefix + paths[3] + ext,
ctString).getImage());
pic4.setTransferHandler(picHandler);
pic5 = new DTPicture(createImageIcon(prefix + paths[4] + ext,
gString).getImage());
pic5.setTransferHandler(picHandler);
pic6 = new DTPicture(createImageIcon(prefix + paths[5] + ext,
hString).getImage());
pic6.setTransferHandler(picHandler);
pic7 = new DTPicture(createImageIcon(prefix + paths[6] + ext,
tString).getImage());
pic7.setTransferHandler(picHandler);
pic8 = new DTPicture(createImageIcon(prefix + paths[7] + ext,
cghString).getImage());
pic8.setTransferHandler(picHandler);
pic9 = new DTPicture(null);
pic9.setTransferHandler(picHandler);
pic10 = new DTPicture(null);
pic10.setTransferHandler(picHandler);
pic11 = new DTPicture(null);
pic11.setTransferHandler(picHandler);
pic12 = new DTPicture(null);
pic12.setTransferHandler(picHandler);
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path,
String description)
{
java.net.URL imageURL = DropApplet.class.getResource(path);
if (imageURL == null)
{
System.err.println("Resource not found: " + path);
return null;
}
else
{
return new ImageIcon(imageURL, description);
}
}
//Create an Edit menu to support cut/copy/paste.
private JMenuBar createMenuBar()
{
JMenuItem menuItem = null;
JMenuBar menuBar = new JMenuBar();
JMenu mainMenu = new JMenu("Edit");
mainMenu.setMnemonic(KeyEvent.VK_E);
TransferActionListener actionListener = new TransferActionListener();
menuItem = new JMenuItem("Cut");
menuItem.setActionCommand((String)TransferHandler.getCutAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_T);
mainMenu.add(menuItem);
menuItem = new JMenuItem("Copy");
menuItem.setActionCommand((String)TransferHandler.getCopyAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_C);
mainMenu.add(menuItem);
menuItem = new JMenuItem("Paste");
menuItem.setActionCommand((String)TransferHandler.getPasteAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_P);
mainMenu.add(menuItem);
menuBar.add(mainMenu);
return menuBar;
}
public static void main(String[] args)
{
JApplet applet = new DropApplet();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(applet);
f.setSize(560, 480);
f.setLocation(200,200);
applet.init();
f.setVisible(true);
}
}
the example you given was not fit for my needs.
i give my need more preciesly ,in one pane - source pane the images or icons(anything can show a small image) on it can be copy to target pane,and on target pane i need draw images dynamicly at any position(within target pane),and these images can be move around (withing target pane).but most importantly there a big image background on target pane all other images or icons are on it (background image is a static image and can't be covered )
so please help me ,waiting online.................
here is my code.
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import cn.com.ynld.bms.applet.gui.listener.ElectronicPaneLisenter;
import cn.com.ynld.bms.applet.service.GeneralContext;
public class ElectronicMap extends JApplet {
/**
*
*/
private static final long serialVersionUID = -8716508203782373640;
public void init() {
ElectronicPane pane = new ElectronicPane(GeneralContext
.generateContext());
pane.addMouseListener(new ElectronicPaneLisenter(GeneralContext
.generateContext(), pane));
this.setContentPane(pane);
}
/** Returns an ImageIcon, or null if the path was invalid. */
public static ImageIcon createImageIcon(String path) {
// java.net.URL imageURL = DragPictureDemo.class.getResource(path);
if (path == null) {
System.err.println("Resource not found: " + path);
return null;
} else {
return new ImageIcon(path);
}
}
}
import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import cn.com.ynld.bms.applet.service.UpdateAble;
public class ElectronicPane extends JPanel implements ItemListener {
private UpdateAble updateAble = null;
private JToolBar toolBar;
/**
*
*/
private static final long serialVersionUID = 1;
public ElectronicPane(UpdateAble updateAble) {
super(new BorderLayout());
this.updateAble = updateAble;
this.creatToolBar();
this.add(this.toolBar, BorderLayout.NORTH);
//DropTarget dt = new DropTarget(this,new DropIconOnPaneListener());
//this.setDropTarget(dt);
}
public void itemStateChanged(ItemEvent e) {
}
private void creatToolBar() {
this.toolBar = new JToolBar();
this.toolBar.add(new ToolBarDragAction("alarm",
createImageIcon("/root/Desktop/drawing/alarm.png"),
"drag icon", this.updateAble));
this.toolBar.add(new ToolBarDragAction("config",
createImageIcon("/root/Desktop/drawing/device.png"),
"device icon", this.updateAble));
this.toolBar.add(new ToolBarDragAction("ball",
createImageIcon("/root/Desktop/drawing/ball.png"), "ball icon",
this.updateAble));
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
// java.net.URL imageURL = DragPictureDemo.class.getResource(path);
if (path == null) {
System.err.println("Resource not found: " + path);
return null;
} else {
return new ImageIcon(path);
}
}
}
import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import cn.com.ynld.bms.applet.service.UpdateAble;
public class ElectronicPane extends JPanel implements ItemListener {
private UpdateAble updateAble = null;
private JToolBar toolBar;
/**
*
*/
private static final long serialVersionUID = 1;
public ElectronicPane(UpdateAble updateAble) {
super(new BorderLayout());
this.updateAble = updateAble;
this.creatToolBar();
this.add(this.toolBar, BorderLayout.NORTH);
//DropTarget dt = new DropTarget(this,new DropIconOnPaneListener());
//this.setDropTarget(dt);
}
public void itemStateChanged(ItemEvent e) {
}
private void creatToolBar() {
this.toolBar = new JToolBar();
this.toolBar.add(new ToolBarDragAction("alarm",
createImageIcon("/root/Desktop/drawing/alarm.png"),
"drag icon", this.updateAble));
this.toolBar.add(new ToolBarDragAction("config",
createImageIcon("/root/Desktop/drawing/device.png"),
"device icon", this.updateAble));
this.toolBar.add(new ToolBarDragAction("ball",
createImageIcon("/root/Desktop/drawing/ball.png"), "ball icon",
this.updateAble));
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
// java.net.URL imageURL = DragPictureDemo.class.getResource(path);
if (path == null) {
System.err.println("Resource not found: " + path);
return null;
} else {
return new ImageIcon(path);
}
}
}
now i even can't see button when i add it to pane
Comments:
1 — You can remove the toolBar from the frame and still cut/copy/paste and drag
images in or out of it.
2 — You can drag and drop images onto or off of the frame center panel. To paste or
drop images on the center section you must first select the drop point with the mouse, it
will be marked by a red cross. The same applies to dragging images that are located in
the center section: select a drop location first or they will go to the last point selected.
3 — To cut or copy an image from the center section, select it with the mouse
first. There is no visual indication that it is selected.
4 — As before, this is mostly put together from the code found in the Drag_n_Drop
online tutorial.
// <applet code="DropApplet1" width="560" height="480"></applet>
// use: >appletviewer DropApplet.java
import java.awt.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class DropApplet1 extends JApplet
{
BufferedImage[] images;
BufferedImage backgroundImage;
ImageTransferHandler imageHandler;
DragInitiator dragInitiator;
ComponentSelector componentSelector;
JComponent lastSelected;
public void init()
{
images = loadImages();
imageHandler = new ImageTransferHandler();
dragInitiator = new DragInitiator();
componentSelector = new ComponentSelector(this);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(createMenuBar(), "North");
getContentPane().add(getCenterPanel());
getContentPane().add(getToolBar(), "West");
}
private JPanel getCenterPanel()
{
DnDPanel dndPanel = new DnDPanel(backgroundImage);
registerActions(dndPanel);
dndPanel.setTransferHandler(imageHandler);
dndPanel.addMouseListener(dragInitiator);
dndPanel.addMouseMotionListener(dragInitiator);
dndPanel.addMouseListener(componentSelector);
return dndPanel;
}
private JToolBar getToolBar()
{
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2,0,2,0);
gbc.weighty = 1.0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
panel.setBackground(Color.pink);
panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
// use last 4 images
for(int j = 0; j < images.length; j++)
{
JLabel label = new JLabel(new ImageIcon(images[j]));
label.setPreferredSize(label.getPreferredSize());
label.setBorder(BorderFactory.createLineBorder(Color.black));
registerActions(label);
label.setTransferHandler(imageHandler);
label.addMouseListener(componentSelector);
label.addMouseListener(dragInitiator);
label.addMouseMotionListener(dragInitiator);
panel.add(label, gbc);
}
JToolBar toolBar = new JToolBar();
toolBar.add(panel);
return toolBar;
}
private void registerActions(JComponent jc)
{
ActionMap map = jc.getActionMap();
map.put(TransferHandler.getCutAction().getValue(Action.NAME),
TransferHandler.getCutAction());
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
map.put(TransferHandler.getPasteAction().getValue(Action.NAME),
TransferHandler.getPasteAction());
}
private BufferedImage[] loadImages()
{
String prefix = "images/geek";
String ext = ".gif";
String[] ids =
{
"-c", "-cg--", "-c-h-", "-c--t"
};
BufferedImage[] images = new BufferedImage[ids.length];
int j = 0;
try
{
for(j = 0; j < images.length; j++)
{
String path = prefix + ids[j] + ext;
java.net.URL url = DropApplet1.class.getResource(path);
images[j] = ImageIO.read(url);
}
String path = "images/owls.jpg";
java.net.URL url = DropApplet1.class.getResource(path);
backgroundImage = ImageIO.read(url);
}
catch(IOException ioe)
{
System.err.printf("ids[%d] read error: %s%n", j, ioe.getMessage());
}
return images;
}
//Create an Edit menu to support cut/copy/paste.
private JMenuBar createMenuBar()
{
JMenuItem menuItem = null;
JMenuBar menuBar = new JMenuBar();
JMenu mainMenu = new JMenu("Edit");
mainMenu.setMnemonic(KeyEvent.VK_E);
MenuItemListener actionListener = new MenuItemListener(this);
menuItem = new JMenuItem("Cut");
menuItem.setActionCommand((String)TransferHandler.getCutAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_T);
mainMenu.add(menuItem);
menuItem = new JMenuItem("Copy");
menuItem.setActionCommand((String)TransferHandler.getCopyAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_C);
mainMenu.add(menuItem);
menuItem = new JMenuItem("Paste");
menuItem.setActionCommand((String)TransferHandler.getPasteAction().
getValue(Action.NAME));
menuItem.addActionListener(actionListener);
menuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK));
menuItem.setMnemonic(KeyEvent.VK_P);
mainMenu.add(menuItem);
menuBar.add(mainMenu);
return menuBar;
}
public static void main(String[] args)
{
JApplet applet = new DropApplet1();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(applet);
f.setSize(560, 480);
f.setLocation(200,200);
applet.init();
f.setVisible(true);
}
}
/**
* Main panel for center section of JFrame.
*/
class DnDPanel extends JPanel
{
BufferedImage bgImage;
List<Image> images;
List<Rectangle> rects;
int selectedIndex;
Point target;
public DnDPanel(BufferedImage image)
{
bgImage = image;
images = new ArrayList<Image>();
rects = new ArrayList<Rectangle>();
selectedIndex = -1;
target = new Point();
addMouseListener(spotter);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int x = (getWidth() - bgImage.getWidth())/2;
int y = (getHeight() - bgImage.getHeight())/2;
g2.drawImage(bgImage, x, y, this);
g2.setPaint(Color.red);
g2.draw(new Line2D.Double(target.x-30, target.y, target.x+30, target.y));
g2.draw(new Line2D.Double(target.x, target.y-30, target.x, target.y+30));
for(int j = 0; j < images.size(); j++)
{
Rectangle r = rects.get(j);
Image image = images.get(j);
g2.drawImage(image, r.x, r.y, this);
}
}
private MouseListener spotter = new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
Point p = e.getPoint();
boolean overImage = false;
for(int j = 0; j < rects.size(); j++)
{
if(rects.get(j).contains(p))
{
selectedIndex = j;
overImage = true;
break;
}
}
if(!overImage)
{
target = e.getPoint();
repaint();
}
}
};
public Image getSelectedImage()
{
if(selectedIndex != -1)
return images.get(selectedIndex);
return null;
}
public void removeSelectedImage()
{
if(selectedIndex != -1)
{
rects.remove(selectedIndex);
images.remove(selectedIndex);
selectedIndex = -1;
}
repaint();
}
public void addImage(Image image)
{
if(image == null)
return;
int w = image.getWidth(this);
int h = image.getHeight(this);
int x = target.x - w/2;
int y = target.y - h/2;
rects.add(new Rectangle(x, y, w, h));
images.add(image);
repaint();
}
}
/**
* Registered with all components that support drag and drop.
*/
class DragInitiator extends MouseInputAdapter
{
MouseEvent firstMouseEvent;
public void mousePressed(MouseEvent e)
{
firstMouseEvent = e;
e.consume();
}
public void mouseReleased(MouseEvent e)
{
firstMouseEvent = null;
}
public void mouseDragged(MouseEvent e)
{
if(firstMouseEvent != null)
e.consume();
//If they are holding down the control key, COPY rather than MOVE
int ctrlMask = InputEvent.CTRL_DOWN_MASK;
int action = ((e.getModifiersEx() & ctrlMask) == ctrlMask) ?
TransferHandler.COPY : TransferHandler.MOVE;
int dx = Math.abs(e.getX() - firstMouseEvent.getX());
int dy = Math.abs(e.getY() - firstMouseEvent.getY());
//Arbitrarily define a 5-pixel shift as the
//official beginning of a drag.
if (dx > 5 || dy > 5)
{
//This is a drag, not a click.
JComponent c = (JComponent)e.getSource();
TransferHandler handler = c.getTransferHandler();
//Tell the transfer handler to initiate the drag.
handler.exportAsDrag(c, firstMouseEvent, action);
firstMouseEvent = null;
}
}
}
/**
* Listens to all image JComponents and gets
* the last selected JComponent which is saved in
* the DropApplet1 instance variable lastSelected.
* lastSelected is used by the MenuItemListener
* class for menu its cut/copy/paste operations.
*/
class ComponentSelector extends MouseAdapter
{
DropApplet1 dropApplet;
JLabel lastSelection;
public ComponentSelector(DropApplet1 da)
{
dropApplet = da;
}
public void mouseClicked(MouseEvent e)
{
JComponent source = (JComponent)e.getSource();
if(source instanceof JLabel)
{
if(lastSelection != null)
lastSelection.setBorder(BorderFactory.createLineBorder(Color.black));
source.setBorder(BorderFactory.createLineBorder(Color.red));
lastSelection = (JLabel)source;
}
dropApplet.lastSelected = source;
}
}
/**
* JMenuItem listener replaces TransferActionListener and
* uses its ActionListener implementation.
*/
class MenuItemListener implements ActionListener
{
DropApplet1 dropApplet;
public MenuItemListener(DropApplet1 da)
{
dropApplet = da;
}
public void actionPerformed(ActionEvent e)
{
JComponent focusOwner = dropApplet.lastSelected;
if (focusOwner == null)
return;
String action = (String)e.getActionCommand();
Action a = focusOwner.getActionMap().get(action);
if (a != null)
a.actionPerformed(new ActionEvent(focusOwner,
ActionEvent.ACTION_PERFORMED,
null));
}
}
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class ImageTransferHandler extends TransferHandler
{
DataFlavor imageFlavor = DataFlavor.imageFlavor;
boolean shouldRemove;
public boolean importData(JComponent c, Transferable t)
{
Image image;
if (canImport(c, t.getTransferDataFlavors()))
{
try
{
if(c instanceof JLabel)
{
JLabel label = (JLabel)c;
image = (Image)t.getTransferData(imageFlavor);
label.setIcon(new ImageIcon(image));
return true;
}
else if(c instanceof DnDPanel)
{
DnDPanel panel = (DnDPanel)c;
image = (Image)t.getTransferData(imageFlavor);
panel.addImage(image);
return true;
}
}
catch (UnsupportedFlavorException ufe)
{
System.out.println("importData: unsupported data flavor");
}
catch (IOException ioe)
{
System.out.println("importData: I/O exception");
}
}
return false;
}
protected Transferable createTransferable(JComponent c)
{
if(c instanceof JLabel)
{
JLabel label = (JLabel)c;
shouldRemove = true;
return new ImageTransferable(label);
}
else if(c instanceof DnDPanel)
{
DnDPanel dndPanel = (DnDPanel)c;
shouldRemove = true;
return new ImageTransferable(dndPanel);
}
return null;
}
public int getSourceActions(JComponent c) { return COPY_OR_MOVE; }
protected void exportDone(JComponent c, Transferable data, int action)
{
if(shouldRemove && (action == MOVE))
{
if(c instanceof JLabel)
((JLabel)c).setIcon(null);
else if(c instanceof DnDPanel)
((DnDPanel)c).removeSelectedImage();
}
}
public boolean canImport(JComponent c, DataFlavor[] flavors)
{
for(int j = 0; j < flavors.length; j++) {
if(imageFlavor.equals(flavors[j]))
return true;
}
return false;
}
class ImageTransferable implements Transferable
{
private Image image;
ImageTransferable(JComponent c)
{
if(c instanceof JLabel)
image = ((ImageIcon)((JLabel)c).getIcon()).getImage();
else if(c instanceof DnDPanel)
image = ((DnDPanel)c).getSelectedImage();
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException
{
if (!isDataFlavorSupported(flavor))
throw new UnsupportedFlavorException(flavor);
return image;
}
public DataFlavor[] getTransferDataFlavors()
{
return new DataFlavor[] { imageFlavor };
}
public boolean isDataFlavorSupported(DataFlavor flavor)
{
return imageFlavor.equals(flavor);
}
}
}
it seem if i want to creat a new JComponent and draw a image on JComponent an place it on a panel is simple.but the problem is if second time i add a same JComponent in ,it will cover the first one and all event will delegate to the second JComponent.
now i have a way,add all images to single JComponent and draw all of them toghter,but now i can't drag the image.
the example you given told me if i want to add a new JComponent every time,i must set the layout of container,but in this way i can't add them anywhere on Pane,
The example given in reply 6 transfers the image to the DnDPanel where it is drawn as an
image; there is no JComponent associated with the image. What might be confusing is that
if you do not first click on the surface of the DnDPanel before you drop or paste each
image, then every image will end up in a single stack and you must click somewhere else
on the DnDPanel before you drag each one off the stack to the new location. If you do not
see a red cross on the DnDPanel before dropping or pasting any/every image it will be
drawn over the last selected position (red cross).
If you add these extra three lines to the ImageTransferHandler class under the
importData method
else if(c instanceof DnDPanel)
{
DnDPanel panel = (DnDPanel)c;
image = (Image)t.getTransferData(imageFlavor);
>>>>Point p = panel.getMousePosition();<<<< add
>>>>if(p != null)<<<< these
>>>>panel.target = p; <<<< lines
panel.addImage(image);
return true;
}
you can drop the dragged image anywhere and it will stay where you drop it. For pasting
you will still need to click the surface to set a red cross before pasting each/every
image.
For success: make sure you can see a red cross on the surface of the DnDPanel before
trying to drag or paste any image onto it.
thanks !i hava fellow your way and solved my problem.can you give me your email or some other contract methods ,if i encounter problem agin i can ask you more convenience .thanks agin.
by the way my email is dxuranus@gmail.com