Abwerfen der Bild -URL von Webbrowser in der Java -App funktioniert nicht für macOSJava

Java-Forum
Anonymous
 Abwerfen der Bild -URL von Webbrowser in der Java -App funktioniert nicht für macOS

Post by Anonymous »

meine Java (Java 21) -Anwendung hat einen Teil der GUI, mit dem Sie ein Bild in Google im Webbrowser in die Anwendung ziehen können. Nachricht ist auch protokolliert. Nichts ist sogar protokolliert. Basierend auf Vorschlag VGR I Logge jetzt, wenn es eine Ausnahme gibt, und auch log EM> Methode so scheint es, dass MacOS den Drag -Tropfen verhindert, bevor er überhaupt zu meinem Code kommt . Vom Finder stattdessen
Was verursacht den Unterschied? em> < /p>

Code: Select all

    package com.jthink.songkong.ui.startdialog.editsongs;

import com.jthink.songkong.analyse.general.ArtworkHelper;
import com.jthink.songkong.analyse.musicbrainz.RemoteArtworkLookup;
import com.jthink.songkong.db.ImageCache;
import com.jthink.songkong.db.SongCache;
import com.jthink.songkong.preferences.UserOption;
import com.jthink.songkong.preferences.UserPreferences;
import com.jthink.songkong.ui.MainWindow;
import com.jthink.songkong.ui.startdialog.imagefilters.ImageFileFilter;
import com.jthink.songkong.ui.startdialog.imagefilters.ImageFilterFactory;
import com.jthink.songlayer.CoverImage;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.util.logging.Level;

import static com.jthink.songkong.ui.startdialog.editsongs.ArtworkTab.ARTWORK_SIZE;
import static com.jthink.songkong.ui.startdialog.editsongs.ImageSizeDefaults.MAX_IMAGE_SIZE;
import static com.jthink.songkong.ui.startdialog.editsongs.ImageSizeDefaults.MIN_IMAGE_SIZE;

public class ArtworkDropTarget extends DropTarget
{
private static CoverImage   coverImage;
private JLabel              displayArtwork;

public static DataFlavor uriListFlavor;         //This is used by Linux for loading files
public static DataFlavor imageFlavor;           //This is used by Firefox, when drag single image file
public static DataFlavor urlFlavour;            //This is used by Firefox, when drag single image file
public static DataFlavor pictImageFlavor;       //This is used by OSX for iTunes
public static DataFlavor imageIconDataFlavor;   //When dragging from existingArtwork
static
{
try
{
uriListFlavor   = new DataFlavor("text/uri-list;class=java.lang.String");
urlFlavour = new DataFlavor("application/x-java-url;class=java.net.URL");
imageFlavor = new DataFlavor("image/x-java-image;class=java.awt.Image");
pictImageFlavor = new DataFlavor("image/x-pict;class=java.io.InputStream");
imageIconDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType +
";class=\""+javax.swing.Icon.class.getName() + "\"");
}
catch (ClassNotFoundException cne)
{
throw new RuntimeException("unable to create uri-list flavor in drop target:"  + cne.getMessage());
}
}

public ArtworkDropTarget(Component c, JLabel displayArtwork)
throws HeadlessException
{
super(c, DnDConstants.ACTION_COPY, null, true, null);
this.displayArtwork= displayArtwork;
}

public static void setCoverImage(CoverImage coverImage)
{
ArtworkDropTarget.coverImage = coverImage;
}

/**
* When used as Drop target
*
* @param dtde
*/
public synchronized void drop(DropTargetDropEvent dtde)
{
MainWindow.logger.severe("Starting Drop");
dtde.acceptDrop(DnDConstants.ACTION_COPY);
Transferable trans = dtde.getTransferable();
try
{
if (trans.isDataFlavorSupported(imageIconDataFlavor))
{
MainWindow.logger.severe("Received ImageIcon:"+trans.getTransferData(imageIconDataFlavor));
ImageIconWithOriginalImage icon = (ImageIconWithOriginalImage)trans.getTransferData(imageIconDataFlavor);
setExistingArtwork((BufferedImage)icon.getOriginalImage());
}
else if (trans.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && ImageFilterFactory.getImageFilter().accept(((java.util.List) trans.getTransferData(DataFlavor.javaFileListFlavor)).get(0)))
{
MainWindow.logger.severe("Received Files:"+trans.getTransferData(DataFlavor.javaFileListFlavor));
File file = ((java.util.List) trans.getTransferData(DataFlavor.javaFileListFlavor)).get(0);
setExistingArtwork(file);
}
else if (trans.isDataFlavorSupported(imageFlavor) && trans.getTransferData(ArtworkDropTarget.imageFlavor) instanceof BufferedImage)
{
MainWindow.logger.severe("Received Image:"+trans.getTransferData(ArtworkDropTarget.imageFlavor));
setExistingArtwork((BufferedImage)trans.getTransferData(ArtworkDropTarget.imageFlavor));
}
else if (trans.isDataFlavorSupported(urlFlavour))
{
URI imageUri = ((URL) trans.getTransferData(ArtworkDropTarget.urlFlavour)).toURI();

MainWindow.logger.severe("Received ImageUrl:" + imageUri);
URI subUri = GoogleImageSearch.getImageUrlFromImageSearchUrl(imageUri);
if (GoogleImageSearch.isGoogleImageSearch(imageUri) && subUri!=null)
{
MainWindow.logger.severe("Received ImageSubUrl:" + subUri);
setExistingArtwork(subUri);
}
else
{
MainWindow.logger.severe("Received ImageUrl:"  + imageUri);
setExistingArtwork(imageUri);
}
}
else
{
MainWindow.logger.severe("Unknown DataFlavor for ImageUrl");
for(DataFlavor next:trans.getTransferDataFlavors())
{
MainWindow.logger.severe(next.toString());
}
}
dtde.dropComplete(true);
}
catch(Exception ex)
{
MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
dtde.dropComplete(false);
}
}

/**
* TODO do we have to convert to JPG, cant we keep as PNG
* @param image
*/
private void setExistingArtwork(BufferedImage image)
{
try
{
byte[] imageData = writeCompressedJpegImageToByteArray(image, 1.0f);
coverImage = ImageCache.saveNewCoverImage(image, imageData, "internet", com.jthink.songlayer.CoverImage.createKeyFromData(imageData),
MIN_IMAGE_SIZE,
UserOption.ARTWORK_MAX_SIZE.getIntValue()
);
SongCache.saveImagesForReport(coverImage, null);
createNewArtworkImage(image);
}
catch (IOException ex)
{
MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
}
}

/**
* Write Compressed Jpeg, use minimum compression of 1f for best quality
*
* @param bi
* @param compressionLevel
* @return
* @throws IOException
*/
private static byte[] writeCompressedJpegImageToByteArray(BufferedImage bi, float compressionLevel) throws IOException
{
ImageWriter imageWriter = ImageIO.getImageWritersByFormatName( "jpg").next();
ImageWriteParam writeParams = imageWriter.getDefaultWriteParam();
writeParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParams.setCompressionQuality(compressionLevel);

final ByteArrayOutputStream output = new ByteArrayOutputStream();
imageWriter.setOutput( new MemoryCacheImageOutputStream(output));
IIOImage outputImage = new IIOImage(bi, null, null);
imageWriter.write(null, outputImage, writeParams);
imageWriter.dispose();

output.flush();
final byte[] imageData = output.toByteArray();
return imageData;
}

/**
*
* @param imageUri
*/
private void setExistingArtwork(URI imageUri)
{
byte[] imageData = RemoteArtworkLookup.getDirectImage(imageUri.toString());
if (imageData != null)
{
BufferedImage image = ArtworkHelper.createBufferedImageFromRawData(imageData, imageUri.toString());
coverImage = ImageCache.saveNewCoverImage(image, imageData, "internet", com.jthink.songlayer.CoverImage.createKeyFromData(imageData),
UserPreferences.getInstance().getMinImageSize(),
(Integer) UserOption.ARTWORK_MAX_SIZE.getUserPref().getValue());
SongCache.saveImagesForReport(coverImage, null);
createNewArtworkImage(image);
}
else
{
MainWindow.logger.severe("Unable To Decode Image:"+imageUri.toString());
}
}

/**
*
* @param file
*/
private void setExistingArtwork(File file)
{
try
{
ImageFileFilter iff = ImageFilterFactory.getImageFilter();
if(iff.accept(file))
{
byte[] imageData = Files.readAllBytes(file.toPath());
BufferedImage image = ArtworkHelper.createBufferedImageFromRawData(imageData, file.getName());
coverImage = ImageCache.saveNewCoverImage(image, imageData,  file.getName(),
com.jthink.songlayer.CoverImage.createKeyFromData(imageData),
UserPreferences.getInstance().getMinImageSize(),
(Integer) UserOption.ARTWORK_MAX_SIZE.getUserPref().getValue());
SongCache.saveImagesForReport(coverImage, null);
createNewArtworkImage(image);
}
}
catch(Exception ex)
{
MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
}
}

/**
* Update new artwork label with version of this image
*
* @param image
*/
private void createNewArtworkImage(BufferedImage image)
{
BufferedImage ret = new BufferedImage(ARTWORK_SIZE, ARTWORK_SIZE, BufferedImage.TYPE_INT_RGB);
ret.getGraphics().drawImage(image, 0, 0, ARTWORK_SIZE, ARTWORK_SIZE, null);
ImageIcon ii = new ImageIcon(ret);
displayArtwork.setIcon(ii);
displayArtwork.setText(image.getWidth() + " x " + image.getHeight());
ArtworkFont.formatArtworkLabel(displayArtwork);
}

public static CoverImage getCoverImage()
{
return coverImage;
}
}
update
Das synchronisierte Schlüsselwort entfernt, wie von VGR vorgeschlagen, wird nun in Drop, wirft aber eine Ausnahme aus

Code: Select all

    01/2025 12.52.09:GMT:ArtworkDropTarget:drop:SEVERE: Cannot invoke "String.length()" because "spec" is null
java.awt.dnd.InvalidDnDOperationException: Cannot invoke "String.length()" because "spec"  is null
at java.desktop/sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:274)
at java.desktop/sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
at java.desktop/java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:387)
at com.jthink.songkong.ui.startdialog.editsongs.ArtworkDropTarget.drop(ArtworkDropTarget.java:109)
at java.desktop/sun.awt.dnd.SunDropTargetContextPeer.processDropMessage(SunDropTargetContextPeer.java:548)
at java.desktop/sun.lwawt.macosx.CDropTargetContextPeer.processDropMessage(CDropTargetContextPeer.java:129)
at java.desktop/sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchDropEvent(SunDropTargetContextPeer.java:864)
at java.desktop/sun.awt.dnd.SunDropTargetContextPeer$EventDispatcher.dispatchEvent(SunDropTargetContextPeer.java:788)
at java.desktop/sun.awt.dnd.SunDropTargetEvent.dispatch(SunDropTargetEvent.java:48)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop/java.awt.LightweightDispatcher.processDropTargetEvent(Container.java:4649)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4511)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Mögliches zugehöriges Problem - https://bugs.openjdk.org/browse/jdk-4358053
Update 2 < /p>
, wie auch durch VGR vorgeschlagen wurde, hat mehrere Anrufe nach GetTransferData () entfernt. Daher kann er nur einmal pro Aufruf der Methode aufgerufen werden, machte keinen Unterschied. < /p>
Update 3
Sehen Sie sich die verfügbaren Datenaromen an und tauschten die Anweisung iF aus, sodass es nach
sucht

Code: Select all

 uriListFlavor   = new DataFlavor("text/uri-list;class=java.lang.String");
< /code>
vor < /p>
urlFlavour = new DataFlavor("application/x-java-url;class=java.net.URL");
Und dann funktioniert es.

Code: Select all

java.awt.dnd.InvalidDnDOperationException: Cannot invoke "String.length()" because "spec" is null
at java.desktop/sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:274)
at java.desktop/sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
at java.desktop/java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:387)
Für einen Geschmack, den er berichtet hatte, und bevor ich eine andere Verarbeitung durchführte, dass dies tatsächlich ein Fehler in dem Code ist, der Java für macOS

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post