Jetzt bin ich mal auf ein fuer mich wirklich interessantes Problem gestoszen. Ich wollte meinen color-palette-viewer um die Funktion erweitern dass man die Farben auch in andere Applikationen ziehen kann. In einen Text-Editor ist das einfach, klatscht man ein
Jetzt gibt es aber auch Farbwahlknoepfe, zum Beispiel den
Der
Fuer Qt gilt im uebrigen das gleiche, gleiches Bild. Passiert sowohl auf JDK 8 als auch 21. Und es gibt keinen anderen Wert den man holen kann, also dort kommt nur
Das klingt halt schon recht schlecht. Bevor ich jetzt irgendwo noch tiefer im JDK-Code verschwinde wollte ich mal fragen ob jemand mehr Erfahrung im Umgang mit Swing, Drag'n Drop, und arbitraeren Daten hat? Habe ich eine Moeglichkeit diesen Drop entgegen zu nehmen ohne die JDK zu patchen?
Falls es jemand probieren will, hier ist ein ganz einfaches
Transferable mit DataFlavor.stringFlavor dran und es funktioniert.Jetzt gibt es aber auch Farbwahlknoepfe, zum Beispiel den
ColorButton von GTK, und ich haette gerne dass ich Farben aus meinem Farbwaehler direkt auf diese ziehen kann (der Grund ist dass der Farbwahldialog von GTK sowas von schlecht ist dass es mich graust ihn zu verwenden). Text akzeptiert dieser dummerweise keinen, und um herauszufinden was akzeptiert wird habe ich dann einfach die Farbe vom Knopf in meine Applikation gezogen um zu sehen welches Format dies hat.Der
DataFlavor beim Drop besagt dass es sich um application/x-color; class=java.io.InputStream handelt, was ja an und fuer sich ganz nett ist, aber das holen der Daten versagt mit einer Ausnahme.
Code:
java.io.IOException: Unsupported data format: 16
at sun.awt.X11.XSelection.getData(XSelection.java:415)
at sun.awt.X11.XDnDDropTargetProtocol.getData(XDnDDropTargetProtocol.java:853)
at sun.awt.X11.XDropTargetContextPeer.getNativeData(XDropTargetContextPeer.java:151)
at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:264)
at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
at java.awt.datatransfer.DataFlavor.getReaderForText(DataFlavor.java:845)
at org.bonsaimind.colorpaletteviewer.gui.ColorPanel$1.drop(ColorPanel.java:114)
at java.awt.dnd.DropTarget.drop(DropTarget.java:455)
at sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:538)
at sun.awt.X11.XDropTargetContextPeer.processDropMessage(XDropTargetContextPeer.java:184)
at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:852)
at sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:776)
at sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
at java.awt.Component.dispatchEventImpl(Component.java:4746)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4599)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4461)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Fuer Qt gilt im uebrigen das gleiche, gleiches Bild. Passiert sowohl auf JDK 8 als auch 21. Und es gibt keinen anderen Wert den man holen kann, also dort kommt nur
application/x-color an.Das klingt halt schon recht schlecht. Bevor ich jetzt irgendwo noch tiefer im JDK-Code verschwinde wollte ich mal fragen ob jemand mehr Erfahrung im Umgang mit Swing, Drag'n Drop, und arbitraeren Daten hat? Habe ich eine Moeglichkeit diesen Drop entgegen zu nehmen ohne die JDK zu patchen?
Falls es jemand probieren will, hier ist ein ganz einfaches
JPanel welches jeglichen Drop annimmt und die Informationen nach stdout schreibt:
Java:
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
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 javax.swing.JFrame;
import javax.swing.SwingUtilities;
public final class ColorDropTestMain {
public static final void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame dropFrame = new JFrame("Drop colors here");
dropFrame.setSize(800, 600);
dropFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new DropTarget(dropFrame, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetListener() {
@Override
public void dragEnter(DropTargetDragEvent dtde) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
}
@Override
public void dragExit(DropTargetEvent dte) {
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
}
@Override
public void drop(DropTargetDropEvent dtde) {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
for (DataFlavor dataFlavor : dtde.getCurrentDataFlavors()) {
System.out.println(dataFlavor.getMimeType());
try {
System.out.println(dtde.getTransferable().getTransferData(dataFlavor))
} catch (Throwable th) {
th.printStackTrace();
}
}
dtde.dropComplete(true);
}
@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
});
dropFrame.setVisible(true);
});
}
}