ScribblePane allows individual PolyLine lines to be selected, cut, copied, pasted, dragged, and dropped : 拖曳 « Swing « Java 教程

En
Java 教程
1. 语言基础
2. 数据类型
3. 操作符
4. 流程控制
5. 类定义
6. 开发相关
7. 反射
8. 正则表达式
9. 集合
10. 线
11. 文件
12. 泛型
13. 本土化
14. Swing
15. Swing事件
16. 二维图形
17. SWT
18. SWT 二维图形
19. 网络
20. 数据库
21. Hibernate
22. JPA
23. JSP
24. JSTL
25. Servlet
26. Web服务SOA
27. EJB3
28. Spring
29. PDF
30. 电子邮件
31. 基于J2ME
32. J2EE应用
33. XML
34. 设计模式
35. 日志
36. 安全
37. Apache工具
38. 蚂蚁编译
39. JUnit单元测试
Java
Java 教程 » Swing » 拖曳 
14. 112. 28. ScribblePane allows individual PolyLine lines to be selected, cut, copied, pasted, dragged, and dropped
/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.com/javaexamples3.
 */

import java.awt.AWTEvent;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Externalizable;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

/**
 * This rewrite of ScribblePane allows individual PolyLine lines to be selected,
 * cut, copied, pasted, dragged, and dropped.
 */
public class TransferableScribblePane extends JComponent {
  List lines; // The PolyLines that comprise this scribble

  PolyLine currentLine; // The line currently being drawn

  PolyLine selectedLine; // The line that is current selected

  boolean canDragImage; // Can we drag an image of the line?

  // Lines are 3 pixels wide, and the selected line is drawn dashed
  static Stroke stroke = new BasicStroke(3.0f);

  static Stroke selectedStroke = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND,
      0fnew float[] { 3f3f}0f);

  // Different borders indicate receptivity to drops
  static Border normalBorder = new LineBorder(Color.black, 3);

  static Border canDropBorder = new BevelBorder(BevelBorder.LOWERED);
  public static void main(String args[]) {
    JFrame f = new JFrame("ColorDrag");
    f.getContentPane().setLayout(new FlowLayout());
    f.getContentPane().add(new TransferableScribblePane());
    f.getContentPane().add(new TransferableScribblePane());
    f.pack();
    f.setVisible(true);
  }
  // The constructor method
  public TransferableScribblePane() {
    setPreferredSize(new Dimension(450200))// We need a default size
    setBorder(normalBorder)// and a border.
    lines = new ArrayList()// Start with an empty list of lines

    // Register interest in mouse button and mouse motion events.
    enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);

    // Enable drag-and-drop by specifying a listener that will be
    // notified when a drag begins. dragGestureListener is defined later.
    DragSource dragSource = DragSource.getDefaultDragSource();
    dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE,
        dragGestureListener);

    // Enable drops on this component by registering a listener to
    // be notified when something is dragged or dropped over us.
    this.setDropTarget(new DropTarget(this, dropTargetListener));

    // Check whether the system allows us to drag an image of the line
    canDragImage = dragSource.isDragImageSupported();
  }

  /** We override this method to draw ourselves. */
  public void paintComponent(Graphics g) {
    // Let the superclass do its painting first
    super.paintComponent(g);

    // Make a copy of the Graphics context so we can modify it
    Graphics2D g2 = (Graphics2D) (g.create());

    // Our superclass doesn't paint the background, so do this ourselves.
    g2.setColor(getBackground());
    g2.fillRect(00, getWidth(), getHeight());

    // Set the line width and color to use for the foreground
    g2.setStroke(stroke);
    g2.setColor(this.getForeground());

    // Now loop through the PolyLine shapes and draw them all
    int numlines = lines.size();
    for (int i = 0; i < numlines; i++) {
      PolyLine line = (PolyLinelines.get(i);
      if (line == selectedLine) { // If it is the selected line
        g2.setStroke(selectedStroke)// Set dash pattern
        g2.draw(line)// Draw the line
        g2.setStroke(stroke)// Revert to solid lines
      else
        g2.draw(line)// Otherwise just draw the line
    }
  }

  /**
   * This method is called on mouse button events. It begins a new line or tries
   * to select an existing line.
   */
  public void processMouseEvent(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) { // Left mouse button
      if (e.getID() == MouseEvent.MOUSE_PRESSED) { // Pressed down
        if (e.isShiftDown()) { // with Shift key
          // If the shift key is down, try to select a line
          int x = e.getX();
          int y = e.getY();

          // Loop through the lines checking to see if we hit one
          PolyLine selection = null;
          int numlines = lines.size();
          for (int i = 0; i < numlines; i++) {
            PolyLine line = (PolyLinelines.get(i);
            if (line.intersects(x - 2, y - 244)) {
              selection = line;
              e.consume();
              break;
            }
          }
          // If we found an intersecting line, save it and repaint
          if (selection != selectedLine) { // If selection changed
            selectedLine = selection; // remember which is selected
            repaint()// will make selection dashed
          }
        else if (!e.isControlDown()) { // no shift key or ctrl key
          // Start a new line on mouse down without shift or ctrl
          currentLine = new PolyLine(e.getX(), e.getY());
          lines.add(currentLine);
          e.consume();
        }
      else if (e.getID() == MouseEvent.MOUSE_RELEASED) {// Left Button Up
        // End the line on mouse up
        if (currentLine != null) {
          currentLine = null;
          e.consume();
        }
      }
    }

    // The superclass method dispatches to registered event listeners
    super.processMouseEvent(e);
  }

  /**
   * This method is called for mouse motion events. We don't have to detect
   * gestures that initiate a drag in this method. That is the job of the
   * DragGestureRecognizer we created in the constructor: it will notify the
   * DragGestureListener defined below.
   */
  public void processMouseMotionEvent(MouseEvent e) {
    if (e.getID() == MouseEvent.MOUSE_DRAGGED && // If we're dragging
        currentLine != null) { // and a line exists
      currentLine.addSegment(e.getX(), e.getY())// Add a line segment
      e.consume()// Eat the event
      repaint()// Redisplay all lines
    }
    super.processMouseMotionEvent(e)// Invoke any listeners
  }

  /** Copy the selected line to the clipboard, then delete it */
  public void cut() {
    if (selectedLine == null)
      return// Only works if a line is selected
    copy()// Do a Copy operation...
    lines.remove(selectedLine)// and then erase the selected line
    selectedLine = null;
    repaint()// Repaint because a line was removed
  }

  /** Copy the selected line to the clipboard */
  public void copy() {
    if (selectedLine == null)
      return// Only works if a line is selected
    // Get the system Clipboard object.
    Clipboard c = this.getToolkit().getSystemClipboard();

    // Wrap the selected line in a TransferablePolyLine object
    // and pass it to the clipboard, with an object to receive notification
    // when some other application takes ownership of the clipboard
    c.setContents(new TransferablePolyLine((PolyLineselectedLine.clone())new ClipboardOwner() {
      public void lostOwnership(Clipboard c, Transferable t) {
        // This method is called when something else
        // is copied to the clipboard. We could use it
        // to deselect the selected line, if we wanted.
      }
    });
  }

  /** Get a PolyLine from the clipboard, if one exists, and display it */
  public void paste() {
    // Get the system Clipboard and ask for its Transferable contents
    Clipboard c = this.getToolkit().getSystemClipboard();
    Transferable t = c.getContents(this);

    // See if we can extract a PolyLine from the Transferable object
    PolyLine line;
    try {
      line = (PolyLinet.getTransferData(TransferablePolyLine.FLAVOR);
    catch (Exception e) { // UnsupportedFlavorException or IOException
      // If we get here, the clipboard doesn't hold a PolyLine we can use
      getToolkit().beep()// So beep to indicate the error
      return;
    }

    lines.add(line)// We got a line from the clipboard, so add it to list
    repaint()// And repaint to make the line appear
  }

  /** Erase all lines and repaint. */
  public void clear() {
    lines.clear();
    repaint();
  }

  /**
   * This DragGestureListener is notified when the user initiates a drag. We
   * passed it to the DragGestureRecognizer we created in the constructor.
   */
  public DragGestureListener dragGestureListener = new DragGestureListener() {
    public void dragGestureRecognized(DragGestureEvent e) {
      // Don't start a drag if there isn't a selected line
      if (selectedLine == null)
        return;

      // Find out where the drag began
      MouseEvent trigger = (MouseEvente.getTriggerEvent();
      int x = trigger.getX();
      int y = trigger.getY();

      // Don't do anything if the drag was not near the selected line
      if (!selectedLine.intersects(x - 4, y - 488))
        return;

      // Make a copy of the selected line, adjust the copy so that
      // the point under the mouse is (0,0), and wrap the copy in a
      // Tranferable wrapper.
      PolyLine copy = (PolyLineselectedLine.clone();
      copy.translate(-x, -y);
      Transferable t = new TransferablePolyLine(copy);

      // If the system allows custom images to be dragged, make
      // an image of the line on a transparent background
      Image dragImage = null;
      Point hotspot = null;
      if (canDragImage) {
        Rectangle box = copy.getBounds();
        dragImage = createImage(box.width, box.height);
        Graphics2D g = (Graphics2DdragImage.getGraphics();
        g.setColor(new Color(0000))// transparent bg
        g.fillRect(00, box.width, box.height);
        g.setColor(getForeground());
        g.setStroke(selectedStroke);
        g.translate(-box.x, -box.y);
        g.draw(copy);
        hotspot = new Point(-box.x, -box.y);

      }

      // Now begin dragging the line, specifying the listener
      // object to receive notifications about the progress of
      // the operation. Note: the startDrag() method is defined by
      // the event object, which is unusual.
      e.startDrag(null, // Use default drag-and-drop cursors
          dragImage, // Use the image, if supported
          hotspot, // Ditto for the image hotspot
          t, // Drag this object
          dragSourceListener)// Send notifications here
    }
  };

  /**
   * If this component is the source of a drag, then this DragSourceListener
   * will receive notifications about the progress of the drag. The only one we
   * use here is dragDropEnd() which is called after a drop occurs. We could use
   * the other methods to change cursors or perform other "drag over effects"
   */
  public DragSourceListener dragSourceListener = new DragSourceListener() {
    // Invoked when dragging stops
    public void dragDropEnd(DragSourceDropEvent e) {
      if (!e.getDropSuccess())
        return// Ignore failed drops
      // If the drop was a move, then delete the selected line
      if (e.getDropAction() == DnDConstants.ACTION_MOVE) {
        lines.remove(selectedLine);
        selectedLine = null;
        repaint();
      }
    }

    // The following methods are unused here. We could implement them
    // to change custom cursors or perform other "drag over effects".
    public void dragEnter(DragSourceDragEvent e) {
    }

    public void dragExit(DragSourceEvent e) {
    }

    public void dragOver(DragSourceDragEvent e) {
    }

    public void dropActionChanged(DragSourceDragEvent e) {
    }
  };

  /**
   * This DropTargetListener is notified when something is dragged over this
   * component.
   */
  public DropTargetListener dropTargetListener = new DropTargetListener() {
    // This method is called when something is dragged over us.
    // If we understand what is being dragged, then tell the system
    // we can accept it, and change our border to provide extra
    // "drag under" visual feedback to the user to indicate our
    // receptivity to a drop.
    public void dragEnter(DropTargetDragEvent e) {
      if (e.isDataFlavorSupported(TransferablePolyLine.FLAVOR)) {
        e.acceptDrag(e.getDropAction());
        setBorder(canDropBorder);
      }
    }

    // Revert to our normal border if the drag moves off us.
    public void dragExit(DropTargetEvent e) {
      setBorder(normalBorder);
    }

    // This method is called when something is dropped on us.
    public void drop(DropTargetDropEvent e) {
      // If a PolyLine is dropped, accept either a COPY or a MOVE
      if (e.isDataFlavorSupported(TransferablePolyLine.FLAVOR))
        e.acceptDrop(e.getDropAction());
      else // Otherwise, reject the drop and return
        e.rejectDrop();
        return;
      }

      // Get the dropped object and extract a PolyLine from it
      Transferable t = e.getTransferable();
      PolyLine line;
      try {
        line = (PolyLinet.getTransferData(TransferablePolyLine.FLAVOR);
      catch (Exception ex) { // UnsupportedFlavor or IOException
        getToolkit().beep()// Something went wrong, so beep
        e.dropComplete(false)// Tell the system we failed
        return;
      }

      // Figure out where the drop occurred, and translate so the
      // point that was formerly (0,0) is now at that point.
      Point p = e.getLocation();
      line.translate((floatp.getX()(floatp.getY());

      // Add the line to our list, and repaint
      lines.add(line);
      repaint();

      // Tell the system that we successfully completed the transfer.
      // This means it is safe for the initiating component to delete
      // its copy of the line
      e.dropComplete(true);
    }

    // We could provide additional drag under effects with this method.
    public void dragOver(DropTargetDragEvent e) {
    }

    // If we used custom cursors, we would update them here.
    public void dropActionChanged(DropTargetDragEvent e) {
    }
  };
}

/**
 * This Shape implementation represents a series of connected line segments. It
 * is like a Polygon, but is not closed. This class is used by the ScribblePane
 * class of the GUI chapter. It implements the Cloneable and Externalizable
 * interfaces so it can be used in the Drag-and-Drop examples in the Data
 * Transfer chapter.
 */
class PolyLine implements Shape, Cloneable, Externalizable {
  float x0, y0; // The starting point of the polyline.

  float[] coords; // The x and y coordinates of the end point of each line

  // segment packed into a single array for simplicity:
  // [x1,y1,x2,y2,...] Note that these are relative to x0,y0
  int numsegs; // How many line segments in this PolyLine

  // Coordinates of our bounding box, relative to (x0, y0);
  float xmin = 0f, xmax = 0f, ymin = 0f, ymax = 0f;

  // No arg constructor assumes an origin of (0,0)
  // A no-arg constructor is required for the Externalizable interface
  public PolyLine() {
    this(0f0f);
  }

  // The constructor.
  public PolyLine(float x0, float y0) {
    setOrigin(x0, y0)// Record the starting point.
    numsegs = 0// Note that we have no line segments, so far
  }

  /** Set the origin of the PolyLine. Useful when moving it */
  public void setOrigin(float x0, float y0) {
    this.x0 = x0;
    this.y0 = y0;
  }

  /** Add dx and dy to the origin */
  public void translate(float dx, float dy) {
    this.x0 += dx;
    this.y0 += dy;
  }

  /**
   * Add a line segment to the PolyLine. Note that x and y are absolute
   * coordinates, even though the implementation stores them relative to x0, y0;
   */
  public void addSegment(float x, float y) {
    // Allocate or reallocate the coords[] array when necessary
    if (coords == null)
      coords = new float[32];
    if (numsegs * >= coords.length) {
      float[] newcoords = new float[coords.length * 2];
      System.arraycopy(coords, 0, newcoords, 0, coords.length);
      coords = newcoords;
    }

    // Convert from absolute to relative coordinates
    x = x - x0;
    y = y - y0;

    // Store the data
    coords[numsegs * 2= x;
    coords[numsegs * 1= y;
    numsegs++;

    // Enlarge the bounding box, if necessary
    if (x > xmax)
      xmax = x;
    else if (x < xmin)
      xmin = x;
    if (y > ymax)
      ymax = y;
    else if (y < ymin)
      ymin = y;
  }

  /*------------------ The Shape Interface --------------------- */

  // Return floating-point bounding box
  public Rectangle2D getBounds2D() {
    return new Rectangle2D.Float(x0 + xmin, y0 + ymin, xmax - xmin, ymax - ymin);
  }

  // Return integer bounding box, rounded to outermost pixels.
  public Rectangle getBounds() {
    return new Rectangle((int) (x0 + xmin - 0.5f)// x0
        (int) (y0 + ymin - 0.5f)// y0
        (int) (xmax - xmin + 0.5f)// width
        (int) (ymax - ymin + 0.5f))// height
  }

  // PolyLine shapes are open curves, with no interior.
  // The Shape interface says that open curves should be implicitly closed
  // for the purposes of insideness testing. For our purposes, however,
  // we define PolyLine shapes to have no interior, and the contains()
  // methods always return false.
  public boolean contains(Point2D p) {
    return false;
  }

  public boolean contains(Rectangle2D r) {
    return false;
  }

  public boolean contains(double x, double y) {
    return false;
  }

  public boolean contains(double x, double y, double w, double h) {
    return false;
  }

  // The intersects methods simply test whether any of the line segments
  // within a polyline intersects the given rectangle. Strictly speaking,
  // the Shape interface requires us to also check whether the rectangle
  // is entirely contained within the shape as well. But the contains()
  // methods for this class alwasy return false.
  // We might improve the efficiency of this method by first checking for
  // intersection with the overall bounding box to rule out cases that
  // aren't even close.
  public boolean intersects(Rectangle2D r) {
    if (numsegs < 1)
      return false;
    float lastx = x0, lasty = y0;
    for (int i = 0; i < numsegs; i++) { // loop through the segments
      float x = coords[i * 2+ x0;
      float y = coords[i * 1+ y0;
      // See if this line segment intersects the rectangle
      if (r.intersectsLine(x, y, lastx, lasty))
        return true;
      // Otherwise move on to the next segment
      lastx = x;
      lasty = y;
    }
    return false// No line segment intersected the rectangle
  }

  // This variant method is just defined in terms of the last.
  public boolean intersects(double x, double y, double w, double h) {
    return intersects(new Rectangle2D.Double(x, y, w, h));
  }

  // This is the key to the Shape interface; it tells Java2D how to draw
  // the shape as a series of lines and curves. We use only lines
  public PathIterator getPathIterator(final AffineTransform transform) {
    return new PathIterator() {
      int curseg = -1// current segment

      // Copy the current segment for thread-safety, so we don't
      // mess up of a segment is added while we're iterating
      int numsegs = PolyLine.this.numsegs;

      public boolean isDone() {
        return curseg >= numsegs;
      }

      public void next() {
        curseg++;
      }

      // Get coordinates and type of current segment as floats
      public int currentSegment(float[] data) {
        int segtype;
        if (curseg == -1) { // First time we're called
          data[0= x0; // Data is the origin point
          data[1= y0;
          segtype = SEG_MOVETO; // Returned as a moveto segment
        else // Otherwise, the data is a segment endpoint
          data[0= x0 + coords[curseg * 2];
          data[1= y0 + coords[curseg * 1];
          segtype = SEG_LINETO; // Returned as a lineto segment
        }
        // If a tranform was specified, transform point in place
        if (transform != null)
          transform.transform(data, 0, data, 01);
        return segtype;
      }

      // Same as last method, but use doubles
      public int currentSegment(double[] data) {
        int segtype;
        if (curseg == -1) {
          data[0= x0;
          data[1= y0;
          segtype = SEG_MOVETO;
        else {
          data[0= x0 + coords[curseg * 2];
          data[1= y0 + coords[curseg * 1];
          segtype = SEG_LINETO;
        }
        if (transform != null)
          transform.transform(data, 0, data, 01);
        return segtype;
      }

      // This only matters for closed shapes
      public int getWindingRule() {
        return WIND_NON_ZERO;
      }
    };
  }

  // PolyLines never contain curves, so we can ignore the flatness limit
  // and implement this method in terms of the one above.
  public PathIterator getPathIterator(AffineTransform at, double flatness) {
    return getPathIterator(at);
  }

  /*------------------ Externalizable --------------------- */

  /**
   * The following two methods implement the Externalizable interface. We use
   * Externalizable instead of Seralizable so we have full control over the data
   * format, and only write out the defined coordinates
   */
  public void writeExternal(java.io.ObjectOutput outthrows java.io.IOException {
    out.writeFloat(x0);
    out.writeFloat(y0);
    out.writeInt(numsegs);
    for (int i = 0; i < numsegs * 2; i++)
      out.writeFloat(coords[i]);
  }

  public void readExternal(java.io.ObjectInput inthrows java.io.IOException,
      ClassNotFoundException {
    this.x0 = in.readFloat();
    this.y0 = in.readFloat();
    this.numsegs = in.readInt();
    this.coords = new float[numsegs * 2];
    for (int i = 0; i < numsegs * 2; i++)
      coords[i= in.readFloat();
  }

  /*------------------ Cloneable --------------------- */

  /**
   * Override the Object.clone() method so that the array gets cloned, too.
   */
  public Object clone() {
    try {
      PolyLine copy = (PolyLinesuper.clone();
      if (coords != null)
        copy.coords = (float[]) this.coords.clone();
      return copy;
    catch (CloneNotSupportedException e) {
      throw new AssertionError()// This should never happen
    }
  }
}

/*
 * Copyright (c) 2004 David Flanagan. All rights reserved. This code is from the
 * book Java Examples in a Nutshell, 3nd Edition. It is provided AS-IS, WITHOUT
 * ANY WARRANTY either expressed or implied. You may study, use, and modify it
 * for any non-commercial purpose, including teaching and use in open-source
 * projects. You may distribute it non-commercially as long as you retain this
 * notice. For a commercial use license, or to purchase the book, please visit
 * http://www.davidflanagan.com/javaexamples3.
 */

/**
 * This class implements the Transferable interface for PolyLine objects. It
 * also defines a DataFlavor used to describe this data type.
 */
class TransferablePolyLine implements Transferable {
  public static DataFlavor FLAVOR = new DataFlavor(PolyLine.class, "PolyLine");

  static DataFlavor[] FLAVORS = new DataFlavor[] { FLAVOR };

  PolyLine line; // This is the PolyLine we wrap.

  public TransferablePolyLine(PolyLine line) {
    this.line = line;
  }

  /** Return the supported flavor */
  public DataFlavor[] getTransferDataFlavors() {
    return FLAVORS;
  }

  /** Check for the one flavor we support */
  public boolean isDataFlavorSupported(DataFlavor f) {
    return f.equals(FLAVOR);
  }

  /** Return the wrapped PolyLine, if the flavor is right */
  public Object getTransferData(DataFlavor fthrows UnsupportedFlavorException {
    if (!f.equals(FLAVOR))
      throw new UnsupportedFlavorException(f);
    return line;
  }
}
14. 112. 拖曳
14. 112. 1. 基本拖放
14. 112. 2. 从JLabel拖动文字从JLabel拖动文字
14. 112. 3. 拖放图片拖放图片
14. 112. 4. 拖放图标
14. 112. 5. 实施DragGestureListener
14. 112. 6. Dragging and dropping text between a text area, a list, and a tableDragging and dropping text between a text area, a list, and a table
14. 112. 7. 拖放JTextArea和JTextField
14. 112. 8. Transfer both Text and Color between JTextField and JTextArea
14. 112. 9. 拖放JList和JTextField
14. 112. 10. DropMode.ON
14. 112. 11. DropMode.INSERT
14. 112. 12. DropMode.ON_OR_INSERT
14. 112. 13. 树DropMode以DropMode.USE_SELECTION
14. 112. 14. 树拖动模式DropMode.ON
14. 112. 15. 树拖动模式DropMode.INSERT
14. 112. 16. 树拖动模式DropMode.ON_OR_INSERT
14. 112. 17. 选择下拉事件
14. 112. 18. 各种下拉事件
14. 112. 19. 表格拖放
14. 112. 20. Create a drag source a drop target and a transferable object.
14. 112. 21. 组件拖动
14. 112. 22. 拖动发起的动作
14. 112. 23. Illustrates cut, copy, paste and drag and drop using three instances of JList
14. 112. 24. 位置敏感拖放
14. 112. 25. Demonstration of the top-level TransferHandler support on JFrame
14. 112. 26. Drag-and-Drop customization: drag the foreground color from the first label and drop it as the background color into the second one
14. 112. 27. Demonstrates how to add copy and drag support to a Swing component with TransferHandler
14. 112. 28. ScribblePane allows individual PolyLine lines to be selected, cut, copied, pasted, dragged, and dropped
14. 112. 29. Built-in drag and drop support: utilize a TransferHandler class
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.