Drag and Drop: New Data Transfer Capabilities in the JavaTM 2 Platform, Standard Edition (J2SETM), version 1.4

基于 Qt 6 / C++17 的多算法加解密工具(学习研究用途) 涵盖编码、古典密码、对称/非对称加密、哈希摘要共 24 种算法,全部纯 C++ 自实现,不依赖 OpenSSL/GmSSL 基于 Qt 6 / C++17 的多算法加解密工具(学习研究用途)。涵盖编码、古典密码、对称/非对称加密、哈希摘要共 24 种算法,全部纯 C++ 自实现,不依赖 OpenSSL/GmSSL。含图形界面、批量文件加解密、密钥管理、性能测试与操作日志。提供标准测试向量自测。 立即下载

New Data Transfer Capabilities

John Zukowski
November 2001

Sun is currently undergoing their third beta release of the JavaTM 2 Platform, Standard Edition (J2SETM), version 1.4. This latest release incorporates many new and interesting features into the standard library set, some of which have been available as standard extensions for some time. These would include capabilities like the Java Cryptography Extension (JCE), Java Secure Socket Extension (JSSE), Java Authentication and Authorization Service (JAAS), the Java API for XML Processing (JAXP), and JDBC extensions. All of these libraries have been available as optional libraries and work with prior versions of the Java 2 Platform. Now, they just come standard.

In addition to adding previously optional packages to the standard library set, the 1.4 release also incorporates many new features. These totally new elements include new Swing components, new I/O management, and a new assert keyword in the language. Features like these are not backward compatible and are not available as optional libraries for earlier releases of the Java 2 Platform.

One of the new capabilities now available is improved data transfer support within and between applications. Data transfer includes two tasks: cut, copy, and paste access to the user or system clipboard and drag-and-drop support. Neither of these features is totally new to the standard library set. However, what you can do with them now in the 1.4 release and how you interact with the features has totally changed. Older programs, designed for the earlier data transfer mechanism, will continue to work fine, but in many cases the source code for the task can be simplified considerably.

Before looking into how to use the drag-and-drop capabilities of the J2SE, version 1.4 release, there is some background information you need to understand.

Clipboards

First off is a look at clipboards. If you aren't familiar with what a clipboard is, it is a memory area for storing information in support of cut, copy, and paste operations. For instance, when you are using a word processor and cut a piece of text to place the text elsewhere in the document, the text that was cut is saved within the clipboard. When it becomes time to paste the text, the paste operation reads what is on the clipboard and pastes it into the document.

There are actually multiple clipboards available. There is one global clipboard that all applications have access to, and private clipboards that can be limited in scope to within a single application. By utilizing a private clipboard in an application, you don't copy into system memory what goes onto the system clipboard. Instead, it stays within the application's memory space.

Transferable Objects

While you now know what a clipboard is, you haven't learned anything about the objects that can go into the clipboard. With the Java platform, objects that can be placed within a clipboard must implement the Transferable interface, found in the java.awt.datatransfer package.

public interface Transferable {
  public Object getTransferData(DataFlavor flavor) 
    throws UnsupportedFlavorException, IOException;
  public DataFlavor[] getTransferDataFlavors();
  public boolean isDataFlavorSupported(DataFlavor
         flavor);
}

The interface talks about an object called DataFlavor, but what's a flavor? Quite simply, data flavors are ways of representing data. In the Web world, you might have heard the term MIME types, where MIME stands for Multipurpose Internet Mail Extensions. MIME types allow you to say that an email attachment is an image or the Web document to deliver through your web server is a text file. Data flavors are just the way of representing MIME types within your programs.

MIME types have textual representations like text/html or text/plain. Data flavors on the other hand are classes. Flavors get created by textual representations, but they are classes in the system. They are used by the data transfer mechanism so that when you place something on the clipboard, you can state what type of object it is. Then, when someone gets something off the clipboard, that someone can ask what flavors of data are available. If all the flavors are ones they don't support, they can't get the object off the clipboard.

What's this about multiple flavors? You provide data through the data transfer mechanism with multiple flavors so that you can support the widest possible audience. For instance, if you were to copy text within a word processor, you would want to retain the formatting information. However, if you were to paste the text into something that didn't support the formatting, wouldn't you at least want to be able to get the actual text content? That's how flavors work. You specify that the transferable data can be represented by one or more flavors. You provide the means to check if a particular flavor is supported, and then you provide the mechanism to get the data for a specific flavor. And that is exactly what the Transferable interface does for you.

DataFlavor itself is a class. It makes several default flavor and MIME types available through class constants and a method. Going from simplest to most complex, you get predefined flavors for plain text, strings, a file list, and images. There are also three MIME types defined for local, serialized, and remote objects. From the MIME types, you can create the flavors.

  • getTextPlainUnicodeFlavor
  • stringFlavor
  • javaFileListFlavor
  • imageFlavor
  • javaJVMLocalObjectMimeType
  • javaSerializedObjectMimeType
  • javaRemoteObjectMimeType

Using the word processor example, imagine if that word processor was your program and you wanted to support cut and paste of the content of your document. You might present the content in four different flavors. The first flavor would be the local object type. If cut-and-paste is happening within the same application, using the javaJVMLocalObjectMimeType allows you to just use a local memory reference for the copy operation. Going between different Java applications would allow you to create a flavor from javaSerializedObjectMimeType. Here, the content is serialized, and you would be able to preserve any formatting information. The last two are stringFlavor and getTextPlainUnicodeFlavor. Both lose all formatting information, but still permit you to copy the contents.

Transferring string objects is a common task so you'll find a StringSelection class in the java.awt.datatransfer package to help you. As it only works with strings, the class doesn't support the local/serialized types just mentioned.

Now that you have some background information, let's move on to some real code.

Buffers

The clipboard acts as an indirect buffer. When you make something available to the clipboard, you don't actually copy the data there. Instead, you copy a reference and that reference is accessed when you want to take something off the buffer. Because you may need to keep track of that external reference, the clipboard will actually notify you when something else replaces an item on the clipboard. That notification is handled by the ClipboardOwner interface:

public interface ClipboardOwner {
  public void lostOwnership(Clipboard clip, 
    Transferable t);
}

This means that there is no built-in support for having multiple items on the clipboard. When something new is added to the clipboard, the old reference is thrown away.

To demonstrate the use of the system clipboard, take a look at the StringSelection class. It implements both the Transferable and ClipboardOwner interfaces. You use it to transfer strings to the clipboard. Adding a string to the clipboard involves creating a StringSelection item and setting the clipboard contents, through its setContents method. Here's what the code for that task looks like.

// Get String
String selection = ...;
// Convert to StringSelection
StringSelection data = new StringSelection(selection);
// Get system clipboard
Clipboard clipboard =
  Toolkit.getDefaultToolkit().getSystemClipboard();
// Set contents
clipboard.setContents(data, data);

Getting the clipboard data is a little more involved, but not too difficult. There are basically three steps involved:

  • Get the reference to the data from the clipboard, the Transferable object.
  • Find a flavor you can handle that it supports, where DataFlavor.stringFlavor is for text strings.
  • Get the data for that flavor.

And, here's what that code looks like. There's also a bit of exception handling necessary as a UnsupportedFlavorException or IOException could be thrown.

// Get data from clipboard
Transferable clipData = 
  clipboard.getContents(clipboard);
// Make sure not empty
if (clipData != null) {
// Check if it supports the desired flavor
  if (clipData.isDataFlavorSupported
       (DataFlavor.stringFlavor)) {
// Get data
    String s = (String)(clipData.getTransferData(
      DataFlavor.stringFlavor));
// Use data
    ...
  }
}

Clipboard Text Example

As shown in the following figure, the sample program that puts all these pieces together involves a text area and two buttons, Copy and Paste. When the Copy button is selected, the current selection within the text area is copied to the system clipboard. When the Paste button is selected, the current selection will be replaced with the contents of the system clipboard. If the flavor of data on the clipboard is not supported, the system beeps. Most of the code involves just the screen setup. There should be no new code as far as the clipboard access.

Clipboard Sample Screen

And, here's the complete source.

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.*;

public class ClipboardExample {
  public static void main(String args[]) {

    JFrame frame = new JFrame("Copy/Paste");
    Container contentPane = frame.getContentPane();

    final Toolkit kit = Toolkit.getDefaultToolkit();
    final Clipboard clipboard =
      kit.getSystemClipboard();

    final JTextArea jt = new JTextArea();

    JScrollPane pane = new JScrollPane(jt);
    contentPane.add(pane, BorderLayout.CENTER); 

    JPanel bottom = new JPanel();

    JButton copy = new JButton("Copy");
    bottom.add(copy);

    ActionListener copyListener = new 
      ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String selection = jt.getSelectedText();
        StringSelection data = new 
          StringSelection(selection);
        clipboard.setContents(data, data);
      }
    };

    copy.addActionListener(copyListener);

    JButton paste = new JButton("Paste");
    bottom.add(paste);

    ActionListener pasteListener = new 
      ActionListener() {
      public void actionPerformed(ActionEvent 
        actionEvent) {
        Transferable clipData = 
          clipboard.getContents(clipboard);
        if (clipData != null) {
          try {
            if (clipData.isDataFlavorSupported(
                DataFlavor.stringFlavor)) {
              String s = 
                (String)(clipData.getTransferData(
                DataFlavor.stringFlavor));
              jt.replaceSelection(s);
            } else {
              kit.beep();
            }
          } catch (Exception e) {
            System.err.println("Problems getting data:
              " + e);
          }
        }
      }
    };

    paste.addActionListener(pasteListener);

    contentPane.add(bottom, BorderLayout.SOUTH);

    frame.setDefaultCloseOperation
      (JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 300);
    frame.show();
  }
}

When trying out the program, be sure to try to copy and paste between native applications like your word processor. Because you are using the system clipboard, the program will transfer whatever the contents of the clipboard are.

Text Actions

While this article is about explaining the data transfer mechanisms with the J2SE libraries, the code for copy and paste doesn't have to be that complicated when using the Swing text controls. They already know how to do cut, copy, and paste operations, among many other tasks. All you have to do is lookup the appropriate listener and add that instead.

The actions associated with the text controls are retrieved through the getActions method. This returns an array of Action objects, which implement the ActionListener interface. You just need to find the specific listener and attach that instead. The following code will do just that. It replaces the creation of the two ActionListener objects and their attachment in the prior example.

// get command table
Action actions[] = jt.getActions();

// Find the two wanted
int count = 

   0; for
(int i = 
 0, n = actions.length; (i< 
    n)  && (count <  2); 
    i++) {
  Action a = actions[i];
  String name = (String)a.getValue(Action.NAME);
  if (name.equals(DefaultEditorKit.copyAction)) {
    copy.addActionListener(a);
    count++;
  } else if (name.equals
      (DefaultEditorKit.pasteAction)) {
    paste.addActionListener(a);
    count++;
  }
}

Transferring Images

Now that the basic process of transferring text has been explained, let's move on to something new to the 1.4 release of J2SE, images transfers. Prior versions of the J2SE didn't provide integrated support for transferring images between Java programs and native applications. While you could go through the manual process of providing the data in an understandable format, that task is no longer necessary. All you now have to do is specify that the flavor is of type DataFlavor.imageFlavor, provide the data to the clipboard as an AWT Image object, and you're all set.

While the process of transferring a String is done through the StringSelection class, there is no such class available for transferring images. You must create your own Transferable object that implements ClipboardOwner, too. If StringSelection is for transferring String objects, the logical name for transferring images is ImageSelection.

If you plan on creating transferable objects that will interact with Swing components, you don't have to implement the two interfaces yourself. Instead, there is a helper TransferHandler class that does most of the work for you. The handler does the interaction with the clipboard, and you just have to override four of its methods:

  • public int getSourceActions(JComponent c) -- Returns the supported operations. There are four constants in the TransferHandler class for the operations: COPY, COPY_OR_MOVE, MOVE, and NONE.
  • public boolean canImport(JComponent comp, DataFlavor flavor[]) -- Returns true if the component can support one of the data flavors, false otherwise.
  • public Transferable createTransferable(JComponent comp) -- Here, you need to save a reference to the data to be transferred, and return the TransferHandler (this). The component represents where the data is coming from. This is your copy operation. The handler does the actual copy to the clipboard at the appropriate time.
  • public boolean importData(JComponent comp, Transferable t) -- Returns true if the component supports getting one of the data flavors from the Transferable object, and successfully gets it, false otherwise. This is your paste operation. Again, the handler gets the data from the clipboard, you just have to get it from the Transferable.

Here's just such a class definition that works with all AbstractButton subclasses and the JLabel component.

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;
import javax.swing.*;

public class ImageSelection extends TransferHandler
    implements Transferable {

  private static final DataFlavor flavors[] = 
     {DataFlavor.imageFlavor};

  private Image image;

  public int getSourceActions(JComponent c) {
    return TransferHandler.COPY;
  }

  public boolean canImport(JComponent comp, DataFlavor 
    flavor[]) {
    if (!(comp instanceof JLabel) || 
         (comp instanceof AbstractButton)) {
      return false;
    }
    for (int i=0, n=flavor.length; i<n; i++) {
      if (flavor[i].equals(flavors[0])) {
        return true;
      }
    }
    return false;
  }

  public Transferable createTransferable(JComponent 
    comp) {
    // Clear
    image = null;
    Icon icon = null;

    if (comp instanceof JLabel) {
      JLabel label = (JLabel)comp;
      icon = label.getIcon();
    } else if (comp instanceof AbstractButton) {
      AbstractButton button = (AbstractButton)comp;
      icon = button.getIcon();
    }
    if (icon instanceof ImageIcon) {
      image = ((ImageIcon)icon).getImage();
      return this;
    }
    return null;
  }

  public boolean importData(JComponent comp, 
    Transferable t) {
    ImageIcon icon = null;
    try {
      if (t.isDataFlavorSupported(flavors[0])) {
        image = (Image)t.getTransferData(flavors[0]);
        icon = new ImageIcon(image);
      }
      if (comp instanceof JLabel) {
        JLabel label = (JLabel)comp;
        label.setIcon(icon);
        return true;
      } else if (comp instanceof AbstractButton) {
        AbstractButton button = (AbstractButton)comp;
        button.setIcon(icon);
        return true;
      }
    } catch (UnsupportedFlavorException ignored) {
    } catch (IOException ignored) {
    }
    return false;
  }

  // Transferable
  public Object getTransferData(DataFlavor flavor) {
    if (isDataFlavorSupported(flavor)) {
      return image;
    }
    return null;
  }

  public DataFlavor[] getTransferDataFlavors() {
    return flavors;
  }

  public boolean isDataFlavorSupported(DataFlavor 
    flavor) {
    return flavor.equals(flavors[0]);
  }
}

The following program demonstrates the ImageSelection class. There will be both a JLabel and JButton that uses the ImageSelection as its transfer handler. In the case of the label, three buttons will support different tasks: copying the image on the label to the clipboard, pasting an image on the clipboard to the label, and clearing the label. For the button, selection will act as a paste operation.

Associating an ImageSelection as the transfer handler for a component isn't sufficient for the behavior part of the program to work. You must create an ActionListener to associate to the button and call the necessary TransferHandler method to move the data. As previously mentioned, exportToClipboard will copy the image off the component, and importData will paste it. Like with pasting strings, you still need to get the Transferable off the clipboard though.

TransferHandler handler = label.getTransferHandler();
// Copy
handler.exportToClipboard(label, clipboard, 
  TransferHandler.COPY);
// Paste
Transferable clipData = 
  clipboard.getContents(clipboard);
if (clipData != null) {
  if (clipData.isDataFlavorSupported
    (DataFlavor.imageFlavor)) {
    handler.importData(label, clipData);
  }
}

To support pasting with the button component, you could do the same thing, but it isn't necessary. If the component that is to trigger the transfer is the source of the event, all you have to do is get the ActionListener right from the TransferHandler. There are three static methods for just such an operation: getCopyAction, getCutAction, and getPasteAction. Here's all the code that is necessary to have button selection trigger pasting of the clipboard contents to the button, setting its icon label.

JButton pasteB = new JButton("Paste");
pasteB.setTransferHandler(new ImageSelection());
pasteB.addActionListener
  (TransferHandler.getPasteAction());

Putting all this together becomes a complete test program:

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import java.io.IOException;

public class ImageCopy {

  public static void main(String args[]) {

    JFrame frame = new JFrame("Copy Image");
    frame.setDefaultCloseOperation
      (JFrame.EXIT_ON_CLOSE);

    Container contentPane = frame.getContentPane();

    Toolkit kit = Toolkit.getDefaultToolkit();
    final Clipboard clipboard =
      kit.getSystemClipboard();

    Icon icon = new ImageIcon("scott.jpg");
    final JLabel label = new JLabel(icon);
    label.setTransferHandler(new ImageSelection());

    JScrollPane pane = new JScrollPane(label);
    contentPane.add(pane, BorderLayout.CENTER); 

    JButton copy = new JButton("Label Copy");
    copy.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        TransferHandler handler = 
          label.getTransferHandler();
        handler.exportToClipboard(label, clipboard, 
          TransferHandler.COPY);
      }
    });

    JButton clear = new JButton("Label Clear");
    clear.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent 
        actionEvent) {
        label.setIcon(null);
      }
    });

    JButton paste = new JButton("Label Paste");
    paste.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent 
        actionEvent) {
        Transferable clipData = 
          clipboard.getContents(clipboard);
        if (clipData != null) {
          if (clipData.isDataFlavorSupported
            (DataFlavor.imageFlavor)) {
            TransferHandler handler = 
              label.getTransferHandler();
            handler.importData(label, clipData);
          }
        }
      }
    });

    JPanel p = new JPanel();
    p.add(copy);
    p.add(clear);
    p.add(paste);
    contentPane.add(p, BorderLayout.NORTH);

    JPanel pasteP = new JPanel();
    JButton pasteB = new JButton("Paste");

    pasteB.setTransferHandler(new ImageSelection());

    pasteB.addActionListener
      (TransferHandler.getPasteAction());

    pasteP.add(pasteB);
    contentPane.add(pasteB, BorderLayout.SOUTH);

    frame.setSize(400, 400);
    frame.show();
  }
}

When run, the program will look like the following screen, however, your images will probably differ. Try to copy only small images to the button as it isn't in a JScrollPane. Only the label supports large images.

Image Copy Sample Screen

Drag & Drop

This leads us up to how the 1.4 release of the J2SE supports drag-and-drop operations. The drag-and-drop operation is the transferring of data between objects, triggered by a gesture of the mouse or other pointing device. Prior versions of the platform required intricate work to get drag-and-drop going. For the new release, times have changed considerably. In some cases, all you have to do is call the setDragEnabled method of the component. In other cases, you need to associate a TransferHandler to the component. In all cases, the data to transfer must implement the Transferable interface, but now in many cases that part is already done.

For instance, if you want to support drag-and-drop operations within a JTextField, all you have to do is call the setDragEnabled method of the class, and the contents of the field are draggable.

JTextField tf = new JTextField();
tf.setDragEnabled(true);

This default behavior is available with many of the Swing components:

  • JColorChooser
  • JEditorPane
  • JFileChooser
  • JFormattedTextField
  • JList
  • JPasswordField
  • JTable
  • JTextArea
  • JTextField
  • JTextPane
  • JTree

Here's a simple program to demonstrate how easy drag-and-drop operations are with the new release of J2SE. It provides a JTextField and a JTree, both of which have drag enabled. The JTextField also supports drop operations, so you can drag something from the tree to the text field, but you must do additional work to enable drop on a JTree component.

import java.awt.*;
import java.awt.datatransfer.*;
import javax.swing.*;

public class DragOne {

  public static void main(String args[]) {

    JFrame frame = new JFrame("First Drag");
    frame.setDefaultCloseOperation
      (JFrame.EXIT_ON_CLOSE);

    Container contentPane = frame.getContentPane();

    JTree tree = new JTree();
    JScrollPane pane = new JScrollPane(tree);
    contentPane.add(pane, BorderLayout.CENTER);
    tree.setDragEnabled(true);

    JTextField tf = new JTextField();
    tf.setDragEnabled(true);
    contentPane.add(tf, BorderLayout.NORTH);

    frame.setSize(300, 300);
    frame.show();
  }
}

In order to drag a node from the tree, you must select the icon associated with the specific node. Also, be sure to try to drag multiple selected nodes from the JTree component. This will drag the entries as an ordered HTML list.

While some components have built-in support for drag-and-drop operations, not all do. For instance, if you wanted to support dragging the image on a JLabel, you would have to initiate the drag operation yourself when the mouse was pressed over the component.

MouseListener mouseListener = new MouseAdapter() {
  public void mousePressed(MouseEvent e) {
    JComponent comp = (JComponent)e.getSource();
    TransferHandler handler = 
      comp.getTransferHandler();
    handler.exportAsDrag(comp, e, 
      TransferHandler.COPY);
  }
};
label.addMouseListener(mouseListener);

As long as you associate the earlier ImageSelection handler as the TransferHandler for the component, you can drag off the image to a native application that accepts image input. It is that easy.

The ImageSelection handler is a little special in the sense that it doesn't transfer a property of the button/label. Instead it gets the Image from the Icon property of the component. When the transferable object actually is a property of the component, the creation of the handler can be done much more easily. The TransferHandler class has a constructor that accepts a property name as the constructor argument. Then, when you associate the handler with a Swing component, it knows how to acquire the appropriate content.

For instance, if you wanted to support the dragging of the text label for a JLabel, the following would work to create the TransferHandler for the label and associate it with the component:

TransferHandler handler = new TransferHandler("text");
JLabel label = new JLabel("Welcome");
label.setTransferHandler(handler);

You would still need to add the MouseListener to the component, but you don't have to do anything special to create the handler for the component.

If a Swing component doesn't provide built in drop support, you have to add that in yourself. The code to get the data being transferred via the drag-and-drop operation is identical to getting the data from the clipboard. You only need to associate the behavior with some triggering action, like when the mouse is released over a component:

MouseListener releaseListener = new MouseAdapter() {
  public void mouseReleased(MouseEvent e) {
    Transferable clipData = clipboard.getContents
      (clipboard);
    if (clipData != null) {
      if (clipData.isDataFlavorSupported
        (DataFlavor.imageFlavor)) {
        TransferHandler handler = 
          component.getTransferHandler();
        handler.importData(component, clipData);
      }
    }
  }
};

The following sample program combines all of these operations. There is one draggable text label, one draggable image label, one droppable image label, and a text field for dropping the text.

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.*;

public class DragTwo {

  public static void main(String args[]) {

    JFrame frame = new JFrame("Second Drag");
    frame.setDefaultCloseOperation
      (JFrame.EXIT_ON_CLOSE);

    Container contentPane = frame.getContentPane();

    Toolkit kit = Toolkit.getDefaultToolkit();
    final Clipboard clipboard =
      kit.getSystemClipboard();

    JTextField tf = new JTextField();
    contentPane.add(tf, BorderLayout.NORTH);

    Icon icon = new ImageIcon("scott.jpg");
    JLabel label1 = new JLabel(icon);
    label1.setTransferHandler(new ImageSelection());

    MouseListener pressListener = new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        JComponent comp = (JComponent)e.getSource();
        TransferHandler handler = 
          comp.getTransferHandler();
        handler.exportAsDrag
          (comp, e, TransferHandler.COPY);
      }
    };
    label1.addMouseListener(pressListener);

    TransferHandler handler = new 
      TransferHandler("text");
    JLabel label2 = new JLabel("Drag Me");
    label2.setTransferHandler(handler);
    label2.addMouseListener(pressListener);

    JPanel panel = new JPanel();
    panel.add(label1);
    panel.add(label2);
    contentPane.add(panel, BorderLayout.SOUTH);

    final JLabel dropZone = new JLabel();
    dropZone.setTransferHandler(new ImageSelection());
    MouseListener releaseListener = 
      new MouseAdapter() {
      public void mouseReleased(MouseEvent e) {
        Transferable clipData = clipboard.getContents
          (clipboard);
        if (clipData != null) {
          if (clipData.isDataFlavorSupported
            (DataFlavor.imageFlavor)) {
            TransferHandler handler = 
              dropZone.getTransferHandler();
            handler.importData(dropZone, clipData);
          }
        }
      }
    };
    dropZone.addMouseListener(releaseListener);

    JScrollPane pane = new JScrollPane(dropZone);
    contentPane.add(pane, BorderLayout.CENTER);

    frame.setSize(400, 400);
    frame.show();
  }
}

As shown here, the new J2SE, version 1.4 release makes adding drag-and-drop support to your applications very, very simple. With the added support for transferring images through either the system clipboard or through drag-and-drop operations, what more could you ask for? Throw in all the other new features being added to the 1.4 release and it is sure to be a success.

RESOURCES
考虑一次调频以及二次调频和各机组调频特性的双目标风光水火储动态调度研究(Matlab代码实现) 考虑一次调频以及二次调频和各机组调频特性的双目标风光水火储动态调度研究(Matlab代码实现)内容概要:本文研究了一种考虑一次调频、二次调频以及各机组调频特性的双目标优化模型,用于风光水火储多能互补系统的动态调度问题。该模型以系统运行成本最小化和新能源消纳最大化为双重优化目标,综合考虑了各类电源的出力特性、储能系统的充放电行为及电网频率响应要求。通过Matlab编程实现了完整的求解流程,采用多目标优化算法对复杂约束条件下的调度方案进行求解,并对不同场景下的调度结果进行仿真分析,验证了所提模型在提升系统经济性与稳定性方面的有效性。研究还探讨了储能系统在平抑新能源波动、参与频率调节中的关键作用,为高比例可再生能源接入下的电力系统调度提供了理论支持和技术路径。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事新能源调度、电力系统优化等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决含多种能源形式的复杂电力系统在实际运行中的动态调度问题;②研究储能系统在调频和促进新能源消纳中的协同机制;③掌握多目标优化在电力系统调度中的建模与实现方法; 阅读建议:建议读者结合Matlab代码深入理解模型构建与求解过程,重点关注目标函数设计、约束条件处理及多目标折衷分析方法,同时可通过修改参数进行不同场景的仿真实验,以加深对系统动态行为的理解。 立即下载

相关推荐

tcl脚本语言之file的常见用法

这些命令覆盖了从文件属性获取、修改、复制、删除、路径处理等广泛的文件操作需求。命令用于处理文件系统操作。

hzmscut的博客 5155

[原创]关于jdk多版本的调研

关于jdk多版本的调研。Jws的版本和发布程序没有关系。如果在机器上安装了多个版本的jws,那么默认使用哪个是由系统决定的。注册表中的HKEY_LOCAL_MACHINE/SOFTWARE/Classes/JNLPFile/Shell/Open/Command的值指向某个版本的javaws.exe。从发布的角度来看,只能在jnlp文件中指定你的程序需要的jre,而无法要求客户端用什么版本的jws。

技术专栏 1201

NXP S32K3 Safety软件生态全解析:RTD、SPD、SAF、SCST到底怎么选?

本文深入解析NXP S32K3系列MCU的安全软件生态,详细对比RTD、SPD、SAF和SCST四大组件的功能定位与选型策略。针对不同ASIL等级需求,提供从架构设计到工程实践的完整解决方案,帮助开发者高效实现功能安全认证,优化汽车电子系统的安全性与可靠性。

weixin_42524226的博客 324

Drag and Drop: New Data Transfer Capabilities in the JavaTM 2 Platform, Standard Edition (J2SETM), v

Drag and Drop: New Data Transfer Capabilities in the JavaTM 2 Platform, Standard Edition (J2SETM), version 1.4 (转)...

cuiji1279的博客 158

RADIOML 2018.01A调制信号数据集介绍及处理

RadioML 2018.01A 由 DeepSig 发布,是专门针对自动调制识别(Automatic Modulation Recognition, AMR)和无线信号分类研究设计的基准数据集。它在原有 RadioML 2016.10a 的基础上,扩展并精细化了信道仿真模型,使得信号更接近真实无线环境下的表现。该数据集广泛用于机器学习模型的训练与评估,为各类深度学习算法提供了统一、可重复的实验条件。

weixin_56527269的博客 1901

别再死磕NFP了!用Python+遗传算法搞定异形件自动排版(附完整代码)

本文介绍了如何利用Python和遗传算法实现异形件智能排版,解决传统NFP方法计算复杂的问题。通过Shapely库处理几何运算和DEAP库搭建遗传算法框架,结合模拟退火策略避免局部最优,显著提升材料利用率。附完整代码和优化技巧,适用于服装裁剪、金属加工等行业。

weixin_26965807的博客 236

The Science of JavaTM Sound Technology

  The Science of JavaTM Sound TechnologyBy Michael D. Meloan(June 1999) Sound creates mood, triggers memories, and in conjunction with visual imagery weaves whole worlds of fantasy. Sound is t

CanFly的专栏 2653

Tessent --- PDL

当关联的ICL模块是当前ICL顶部模块时,即当它与当前设计匹配时,只能iCall一个iTopProc。但是,可以在iTopProc内调用iCall iProc或iTopProc。为指定后续iProc命令引用的ICL模块,发出这个命令之后,随后定义的iProc都会对应的ICL模块进行定义。为后续iCall调用,当使用iCall命令调用该过程时,参数列表中的变量将被替换为iCall命令中指定的值。在调用iProc时,运行iProc内的命令。PDL是面向工程师的,工程师利用PDL语言,对ICL中的单元进行控制。

qiantianyiqian的博客 2791

jar-The Java Archive Tool

jar-The Java Archive ToolCombines multiple files into a single JAR archive file. SYNOPSISjar [ options ] [manifest] destination input-file [input-files]DESCRIPTIONThe jar tool is a java

CanFly的专栏 1785

UE5实现建筑剖切效果

UE5实现建筑剖切效果

专注GIS开发 8464

【深度学习|学习笔记】广义线性模型Generalized linear model(GLM)模型详解,附代码。

【深度学习|学习笔记】广义线性模型Generalized linear model(GLM)模型详解,附代码。

2401_89898861的博客 1879

Compressing and Decompressing Data using JavaTM APIs

Compressing and Decompressing Data using JavaTM APIsby Qusay H. Mahmoud with contributions from Konstantin KladkoFebruary 2002 Many sources of information contain redundant data or data that adds

CanFly的专栏 1732

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

What's New in the JMF 2.0 Reference Implementations

   Whats New in the JMF 2.0 Reference Implementations New Features in JMF 2.1.1 FCS Improved RTP API Added support for H.263/1998 (RFC 2429) - now can interoperate with Darwin based RTSP

CanFly的专栏 1639

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Distributed Java Programming with RMI and CORBA

Distributed Java Programming with RMI and CORBAQusay H. MahmoudJanuary 2002 The Java Remote Method Invocation (RMI) mechanism and the Common Object Request Broker Architecture (CORBA) are the two

CanFly的专栏 1464

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

New I/0 Functionality for JavaTM 2 Standard Edition 1.4

New I/0 Functionality for JavaTM 2 Standard Edition 1.4 John ZukowskiOctober, 2001Back in January 2000, while many people were arguing about whether the year 2000 was the last or first year of the

CanFly的专栏 1434

JINI NETWORK TECHNOLOGY DEFENDS THE ENVIRONMENT

JINITM NETWORK TECHNOLOGY DEFENDS THE ENVIRONMENT by Jon Byous November 8, 2001 -- Scientists at the U.S. Department of Energys Pacific Northwest National Laboratory (PNNL), in Richland,

CanFly的专栏 1335

NLEASHING J2EETM TECHNOLOGY'S POWER WITH EJBTM COMPONENTS

NLEASHING J2EETM TECHNOLOGYS POWER WITH EJBTM COMPONENTS by Michael Meloan March 20, 2001 -- The benefits of building ecommerce software applications from pretested, server-side JavaTM c

CanFly的专栏 1303

Understanding the Manifest

Understanding the Manifest JAR files can support a wide range of functionality, including electronic signing, version control, package sealing, extensions, and others. What gives JAR files the abi

CanFly的专栏 1271

Lightweight UI Framework(有產生圓形Button的源碼)

Java AWT: Lightweight UI FrameworkThe ProblemOne of the issues with the 1.0 AWT is that creating new components requires creating subclasses of java.awt.Canvas or java.awt.Panel, which means that

CanFly的专栏 1251

GENERATING INTEGER RANDOM NUMBERS(幾種產生隨機數方法的效率分析)

GENERATING INTEGER RANDOM NUMBERSThere are many ways to generate random numbers with the base libraries found in the Java 2 SDK, Standard Edition. If you havent kept up to date with changes to the

CanFly的专栏 1246

CREATING ROUND SWING BUTTONS 2

CREATING ROUND SWING BUTTONSThis tip is about round Swing buttons. Actually, the information inthis tip applies to a button of any arbitrary shape but to keep thediscussion simple, were just going to

CanFly的专栏 1192

Adding Undo and Redo to a Text Component

 These code examples and other materials are subject to Sun Microsystems, Inc. Legal Terms Adding Undo and Redo to a Text Component JTextArea textarea = new JTextArea(); final UndoManager

CanFly的专栏 1167

Getting Listeners from JavaBeansTM

Getting Listeners from JavaBeansTM An Amendment to the JavaBeans Specification Hans Muller and Mark DavidsonPresently all of the state in an AWT component that can be written can also be read, e.g

CanFly的专栏 1155
上一篇: What's New in the JMF 2.0 Reference Implementations
下一篇: jar-The Java Archive Tool
CanFly
博客等级 码龄25年 0粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值