Changed how to fully load images. Moved ActionHandler classes to their respective projects (common util project is nice, but unnecessary for a single file)

This commit is contained in:
Robinson 2021-02-09 23:06:28 +01:00
parent d4cc8f01d7
commit d6e4f01496
3 changed files with 35 additions and 53 deletions

View File

@ -1,21 +0,0 @@
/*
* Copyright 2015 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.util;
public
interface ActionHandler<T> {
void handle(T value);
}

View File

@ -1,21 +0,0 @@
/*
* Copyright 2015 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.util;
public
interface ActionHandlerLong {
void handle(long value);
}

View File

@ -17,9 +17,11 @@ package dorkbox.util;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Color; import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -29,6 +31,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.imageio.ImageReader; import javax.imageio.ImageReader;
@ -36,6 +39,8 @@ import javax.imageio.stream.ImageInputStream;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import org.slf4j.LoggerFactory;
import dorkbox.os.OS; import dorkbox.os.OS;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -161,7 +166,7 @@ class ImageUtil {
image = new ImageIcon(systemResource).getImage(); image = new ImageIcon(systemResource).getImage();
} }
image = ImageUtil.getImageImmediate(image); ImageUtil.waitForImageLoad(image);
// make whatever dirs we need to. // make whatever dirs we need to.
boolean mkdirs = newFile.getParentFile() boolean mkdirs = newFile.getParentFile()
@ -379,22 +384,41 @@ class ImageUtil {
throw new IOException("Unable to read file inputStream for image size data."); throw new IOException("Unable to read file inputStream for image size data.");
} }
private static final Object mediaTrackerLock = new Object();
private static final AtomicInteger imageTrackerIndex = new AtomicInteger(0);
private static MediaTracker tracker = null;
/** /**
* Because of the way image loading works in Java, if one wants to IMMEDIATELY get a fully loaded image, one must resort to "hacks" * Wait until the image is fully loaded and then init the graphics.
* by loading the image twice.
* *
* @param image the image you want load immediately * @param image the image you want load immediately
*
* @return a fully loaded image
*/ */
public static public static
Image getImageImmediate(final Image image) { void waitForImageLoad(final Image image) {
// have to do this twice, so that it will finish loading the image (weird callback stuff is required if we don't do this) int imageId = imageTrackerIndex.getAndIncrement();
image.flush();
final Image loadedImage = new ImageIcon(image).getImage(); // make sure the image if fully loaded
loadedImage.flush(); synchronized (mediaTrackerLock) {
if (tracker == null) {
tracker = new MediaTracker(new Component() {});
}
return loadedImage; tracker.addImage(image, imageId);
}
try {
tracker.waitForID(imageId);
if (tracker.isErrorID(imageId)) {
LoggerFactory.getLogger(ImageUtil.class).error("Error loading image!");
}
}
catch (InterruptedException ignored) {
} finally {
synchronized (mediaTrackerLock) {
tracker.removeImage(image);
}
}
} }
} }