【发布时间】:2019-01-08 22:49:00
【问题描述】:
我正在开发一个应该通过拖放与现有 Swing 应用程序交互的 JavaFX 应用程序。通过拖放进行的数据交换实际上是有效的,但我们希望重新设计这部分功能,以实际交换自定义 Java 对象,而不是简单的字符串和序列化为 JSON 的对象。问题是,如果使用自定义 MIME 类型而不是例如,Swing UI 不会接收拖动的数据。 text/plain。您可以在下面找到拖动应用程序 (JavaFX) 和放置应用程序 (Swing) 的最小示例。
FxDrag
public class FxDrag extends Application {
private static final DataFormat format = new DataFormat("application/x-my-mime-type");
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
root.setOnDragDetected(event -> {
Dragboard dragboard = root.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString("Test");
// content.put(format, "Test");
dragboard.setContent(content);
event.consume();
});
stage.setScene(new Scene(root, 300, 300));
stage.setTitle("Drag");
stage.show();
}
}
SwingDrop
public class SwingDrop {
public static void main(String[] args) {
new SwingDrop().run();
}
private void run() {
JPanel panel = new JPanel();
panel.setTransferHandler(new TransferHandler() {
@Override
public boolean canImport(TransferSupport support) {
return true;
}
@Override
public boolean importData(TransferSupport support) {
Stream.of(support.getDataFlavors()).forEach(flavor -> {
System.out.println(flavor.getMimeType());
});
return super.importData(support);
}
});
JFrame frame = new JFrame();
frame.setTitle("Drop");
frame.add(panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
当在 JavaFX 应用程序中通过 putString 将 String 放入 content 时,Swing 应用程序接收拖动并提供以下风格:
application/x-java-serialized-object; class=java.lang.String
text/plain; class=java.io.Reader; charset=Unicode
text/plain; class=java.lang.String; charset=Unicode
text/plain; class=java.nio.CharBuffer; charset=Unicode
text/plain; class="[C"; charset=Unicode
text/plain; class=java.io.InputStream; charset=unicode
text/plain; class=java.nio.ByteBuffer; charset=UTF-16
text/plain; class="[B"; charset=UTF-16
text/plain; class=java.io.InputStream; charset=UTF-8
text/plain; class=java.nio.ByteBuffer; charset=UTF-8
text/plain; class="[B"; charset=UTF-8
text/plain; class=java.io.InputStream; charset=UTF-16BE
text/plain; class=java.nio.ByteBuffer; charset=UTF-16BE
text/plain; class="[B"; charset=UTF-16BE
text/plain; class=java.io.InputStream; charset=UTF-16LE
text/plain; class=java.nio.ByteBuffer; charset=UTF-16LE
text/plain; class="[B"; charset=UTF-16LE
text/plain; class=java.io.InputStream; charset=ISO-8859-1
text/plain; class=java.nio.ByteBuffer; charset=ISO-8859-1
text/plain; class="[B"; charset=ISO-8859-1
text/plain; class=java.io.InputStream; charset=windows-1252
text/plain; class=java.io.InputStream
text/plain; class=java.nio.ByteBuffer; charset=windows-1252
text/plain; class="[B"; charset=windows-1252
text/plain; class=java.io.InputStream; charset=US-ASCII
text/plain; class=java.nio.ByteBuffer; charset=US-ASCII
text/plain; class="[B"; charset=US-ASCII
我什至可以从各种应用程序(如浏览器等)中删除不同的数据,Swing 应用程序提供了相应的数据风格(文本、图像等)。
但是,如果我使用自定义格式,则根本不会列出任何口味。 Swing 是否过滤通过拖放应用程序传输的数据类型?
【问题讨论】:
-
我可以通过使用最少的信息来传输 Java 对象(例如 Product 类),例如键(例如 Product Id),它是一个字符串或分隔符分隔的字符串的组合。拖放以字符串形式发生,在放置位置,Java 对象是使用键字符串值构建的;实际对象在集合中可用。这在两个窗口之间的 Swing 应用程序中有效。
-
当然,我总是可以以某种方式将必要的信息放入一个字符串中,然后将该字符串作为
text/plain传输,但在我看来这很丑,因为传输的数据不仅仅是一个普通的字符串。此外,通过这种方式,我可以将数据放到几乎任何地方,而不仅仅是放到目标应用程序中。 -
这是一个想法。但是,我可以将数据放到几乎任何地方,而不仅仅是放到目标应用程序中...。我觉得不行;至少我所尝试的不允许在应用程序内或目标以外的任何地方放置(可以限制)。
-
使用
text/plain将允许丢弃任何接受text/plain的东西,例如编辑器、浏览器、大多数应用程序的文本输入。即使内容只是一个字符串,我也想使用自定义 MIME 类型来防止数据传输到这些应用程序中,当然不是出于安全原因,而是出于可用性考虑。
标签: java swing javafx drag-and-drop