Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple splash icons #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
Institute of Molecular Cell Biology and Genetics.</license.copyrightOwners>
<license.projectName>ImageJ software for multidimensional image processing and analysis.</license.projectName>

<scijava.jvm.version>1.6</scijava.jvm.version>

<target.architecture />
<debug.option />
<skipTests>true</skipTests>
Expand All @@ -153,7 +151,6 @@ Institute of Molecular Cell Biology and Genetics.</license.copyrightOwners>
<dependency>
<groupId>org.scijava</groupId>
<artifactId>scijava-common</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

Expand Down
38 changes: 26 additions & 12 deletions src/main/java/net/imagej/launcher/ClassLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,6 @@ public class ClassLauncher {
*/
public static void main(final String[] arguments) {
originalArguments = arguments;
// If the imagej.splash system property is not set, the splash screen is not
// shown. The --dry-run option of the launcher will set this property to
// true by default. Starting the launcher with --no-splash does not set the
// property.
if (Boolean.getBoolean("imagej.splash")) {
try {
SplashScreen.show();
}
catch (Throwable t) {
t.printStackTrace();
}
}
run(arguments);
}

Expand Down Expand Up @@ -150,6 +138,32 @@ else if (option.equals("-retrotranslator")) {
}
}

// If the imagej.splash system property is not set, the splash screen is
// not shown. The --dry-run option of the launcher will set this
// property to true by default. Starting the launcher with --no-splash
// does not set the property.
if (Boolean.getBoolean("imagej.splash")) {
try {
// Invoke SplashScreen.show() with the previously
// constructed class loader
Class<?> splashScreen = classLoader.loadClass("net.imagej.launcher.SplashScreen");
Method method = splashScreen.getMethod("show");
method.invoke(null);
} catch (final ClassNotFoundException e) {
if (debug)
e.printStackTrace();
} catch (final NoSuchMethodException e) {
if (debug)
e.printStackTrace();
} catch (final IllegalAccessException e) {
if (debug)
e.printStackTrace();
} catch (final InvocationTargetException e) {
if (debug)
e.getTargetException().printStackTrace();
}
}

if (i >= arguments.length) {
System.err.println("Missing argument: main class");
System.exit(1);
Expand Down
98 changes: 98 additions & 0 deletions src/main/java/net/imagej/launcher/SplashIcon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* #%L
* ImageJ software for multidimensional image processing and analysis.
* %%
* Copyright (C) 2007 - 2018 ImageJ developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/

package net.imagej.launcher;

import java.awt.Component;
import java.awt.Graphics;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.swing.ImageIcon;

/**
* A custom ImageIcon implementation that renders various splash screens onto a
* main icon.
*
* @author Stefan Helfrich
*/
public class SplashIcon extends ImageIcon {

private static final long serialVersionUID = 1L;
private final List<ImageIcon> splashs = new LinkedList<ImageIcon>();
private static final int ICON_HEIGHT = 24;
private static final int ICON_WIDTH = 24;
private static final int GAP_WIDTH = 2;

public SplashIcon(final URL main, final Collection<URL> splashs) {
super(main);

// FIXME Simplify with streams when support for Java 6 was dropped
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use FIXME only to mean "This must be fixed ASAP and the code is broken until then." For a comment like this, use TODO, which means "It would be nice to improve this." See also the relevant section of Coding Style wiki page.

for (URL url : splashs) {
if (url == null) {
continue;
}
this.splashs.add(new ImageIcon(url));
}
}

@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
// Paint the main icon to show in the background
super.paintIcon(c, g, x, y);

// Get size of main icon
int mainWidth = super.getIconWidth();
int mainHeight = super.getIconHeight();

// Compute maximum number of splash icons that fit into one row
final int maxNumberOfIcons = (int) Math.floor(mainWidth / (ICON_WIDTH + GAP_WIDTH));

// Compute number of painted icons
final int numberOfIcons = maxNumberOfIcons < splashs.size() ? maxNumberOfIcons : splashs.size();

// Compute offset for centering icons
final int remainder = mainWidth - numberOfIcons * ICON_WIDTH - (numberOfIcons - 1) * GAP_WIDTH;
final int offset = (int) Math.floor(remainder / 2);

for (int i = 0; i < numberOfIcons; i++) {
final ImageIcon imageIcon = splashs.get(i);
if (imageIcon == null) {
continue;
}

// Use index to determine the position
g.drawImage(imageIcon.getImage(), offset + i * (ICON_WIDTH + GAP_WIDTH), mainHeight - ICON_HEIGHT,
offset + i * (ICON_WIDTH + GAP_WIDTH) + ICON_WIDTH, mainHeight, 0, 0, imageIcon.getIconWidth(),
imageIcon.getIconHeight(), c);
}
}
}
31 changes: 26 additions & 5 deletions src/main/java/net/imagej/launcher/SplashScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@
import java.awt.Color;
import java.awt.Window;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JWindow;

import org.scijava.util.FileUtils;

/**
* Application splash screen.
*
Expand All @@ -50,7 +54,8 @@ public class SplashScreen {

private static final int PROGRESS_MAX = 10000;

private static final String LOGO_PATH = "splash/imagej.png";
private static final String LOGO_FILENAME = "imagej.png";
private static final String LOGO_PATH = "splash/" + LOGO_FILENAME;

private static Object splashWindow;
private static Object progressBar;
Expand All @@ -59,20 +64,32 @@ public static void show() {
if (Boolean.getBoolean("java.awt.headless")) return;
final JWindow window = new JWindow();
splashWindow = window; // Save a non-AWT reference to the window.

// Get splash icon from current class loader
final ClassLoader classLoader = //
Thread.currentThread().getContextClassLoader();
final URL logoURL = classLoader.getResource(LOGO_PATH);
final ImageIcon imageIcon;
URL logoURL = classLoader.getResource(LOGO_PATH);

if (logoURL == null) {
// Look for images/icon.png on disk, as a fallback.
// For backwards compatibility with old Fiji installations.
final String parent = System.getProperty("imagej.dir") != null ? //
System.getProperty("imagej.dir") : ".";
final File logoFile = new File(parent, "images/icon.png");
if (!logoFile.exists()) return;
imageIcon = new ImageIcon(logoFile.getPath());
try {
logoURL = logoFile.toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
return;
}
}
else imageIcon = new ImageIcon(logoURL);

// Find all splash icons on the classpath
Map<String, URL> splashs = FileUtils.findResources(".*", "splash", null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think... we better not depend on scijava-common in this project. I'll give some thought to the best way to avoid it here. I think we can recapitulate a targeted subset of what the FileUtils.findResources method does.

splashs.remove(LOGO_FILENAME); // We are using this as the main logo already

final ImageIcon imageIcon = new SplashIcon(logoURL, splashs.values());
final JLabel logoImage = new JLabel(imageIcon);
final JProgressBar bar = new JProgressBar();
bar.setMaximum(PROGRESS_MAX);
Expand Down Expand Up @@ -129,4 +146,8 @@ public static void hide() {
((Window) splashWindow).dispose();
splashWindow = null;
}

public static void main(String[] args) {
SplashScreen.show();
}
}