mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-22 10:43:57 -04:00
Fixed handshake failed connecting with minecraft asset site
This commit is contained in:
parent
574532f10c
commit
627e632120
@ -25,7 +25,7 @@ install: echo "skip 'gradle assemble' step"
|
|||||||
script: gradle build --continue
|
script: gradle build --continue
|
||||||
before_cache:
|
before_cache:
|
||||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||||
cache:
|
#cache:
|
||||||
directories:
|
# directories:
|
||||||
- "$HOME/.gradle/caches/"
|
# - "$HOME/.gradle/caches/"
|
||||||
- "$HOME/.gradle/wrapper/"
|
# - "$HOME/.gradle/wrapper/"
|
||||||
|
@ -64,7 +64,7 @@ public class MojangDownloadProvider extends IDownloadProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAssetsDownloadURL() {
|
public String getAssetsDownloadURL() {
|
||||||
return "https://resources.download.minecraft.net/";
|
return "http://resources.download.minecraft.net/";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,17 +94,23 @@ public class MinecraftModService extends IMinecraftModService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeMod(String id, Object[] rows) {
|
public boolean removeMod(String id, Object[] rows) {
|
||||||
if (rows.length == 0)
|
if (rows.length == 0)
|
||||||
return;
|
return true;
|
||||||
|
boolean flag = true;
|
||||||
for (Object r : rows)
|
for (Object r : rows)
|
||||||
if (r instanceof ModInfo) {
|
if (r instanceof ModInfo) {
|
||||||
if (!((ModInfo) r).location.delete())
|
if (!((ModInfo) r).location.delete()) {
|
||||||
HMCLog.warn("Failed to delete mod" + r);
|
HMCLog.warn("Failed to delete mod" + r);
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
} else if (r instanceof Number)
|
} else if (r instanceof Number)
|
||||||
if (!getMods(id).get(((Number) r).intValue()).location.delete())
|
if (!getMods(id).get(((Number) r).intValue()).location.delete()) {
|
||||||
HMCLog.warn("Failed to delete mod " + r + ", maybe not a file?");
|
HMCLog.warn("Failed to delete mod " + r + ", maybe not a file?");
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
recacheMods(id);
|
recacheMods(id);
|
||||||
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] checkMd5s(String id) throws IOException {
|
public String[] checkMd5s(String id) throws IOException {
|
||||||
|
@ -37,5 +37,5 @@ public abstract class IMinecraftModService extends IMinecraftBasicService {
|
|||||||
|
|
||||||
public abstract boolean addMod(String id, File f);
|
public abstract boolean addMod(String id, File f);
|
||||||
|
|
||||||
public abstract void removeMod(String id, Object[] mods);
|
public abstract boolean removeMod(String id, Object[] mods);
|
||||||
}
|
}
|
||||||
|
@ -113,16 +113,16 @@ public class MinecraftVersionManager extends IMinecraftProvider {
|
|||||||
try {
|
try {
|
||||||
mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class);
|
mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class);
|
||||||
if (mcVersion == null)
|
if (mcVersion == null)
|
||||||
throw new GameException("Wrong json format, got null.");
|
throw new JsonSyntaxException("Wrong json format, got null.");
|
||||||
} catch (JsonSyntaxException | IOException | GameException e) {
|
} catch (JsonSyntaxException | IOException e) {
|
||||||
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
||||||
if (MessageBox.show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
if (MessageBox.show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||||
service.download().downloadMinecraftVersionJson(id);
|
service.download().downloadMinecraftVersionJson(id);
|
||||||
try {
|
try {
|
||||||
mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class);
|
mcVersion = C.GSON.fromJson(FileUtils.read(jsonFile), MinecraftVersion.class);
|
||||||
if (mcVersion == null)
|
if (mcVersion == null)
|
||||||
throw new GameException("Wrong json format, got null.");
|
throw new JsonSyntaxException("Wrong json format, got null.");
|
||||||
} catch (IOException | GameException | JsonSyntaxException ex) {
|
} catch (IOException | JsonSyntaxException ex) {
|
||||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ public final class Main implements Runnable {
|
|||||||
try {
|
try {
|
||||||
File file = new File("hmcl.log");
|
File file = new File("hmcl.log");
|
||||||
if (!file.exists() && !file.createNewFile())
|
if (!file.exists() && !file.createNewFile())
|
||||||
HMCLog.warn("Failed to create log file " + file);
|
LOGGER.log(Level.WARNING, "Failed to create log file {0}", file);
|
||||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
LOGGER.log(Level.SEVERE, "Failed to add log appender File because an error occurred while creating or opening hmcl.log", ex);
|
||||||
@ -144,9 +144,6 @@ public final class Main implements Runnable {
|
|||||||
Locale.setDefault(sl.self);
|
Locale.setDefault(sl.self);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogWindow.INSTANCE.clean();
|
|
||||||
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
||||||
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
||||||
@ -154,6 +151,9 @@ public final class Main implements Runnable {
|
|||||||
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
||||||
HMCLog.warn("Failed to set look and feel...", ex);
|
HMCLog.warn("Failed to set look and feel...", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogWindow.INSTANCE.clean();
|
||||||
|
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||||
|
|
||||||
Settings.UPDATE_CHECKER.outOfDateEvent.register(IUpgrader.NOW_UPGRADER);
|
Settings.UPDATE_CHECKER.outOfDateEvent.register(IUpgrader.NOW_UPGRADER);
|
||||||
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
||||||
|
@ -132,7 +132,7 @@ public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
|||||||
private static final HashSet<String> THROWABLE_SET = new HashSet<>();
|
private static final HashSet<String> THROWABLE_SET = new HashSet<>();
|
||||||
|
|
||||||
void reportToServer(final String text, String stacktrace) {
|
void reportToServer(final String text, String stacktrace) {
|
||||||
if (THROWABLE_SET.contains(stacktrace) || stacktrace.contains("Font"))
|
if (THROWABLE_SET.contains(stacktrace) || stacktrace.contains("Font") || stacktrace.contains("InternalError"))
|
||||||
return;
|
return;
|
||||||
THROWABLE_SET.add(stacktrace);
|
THROWABLE_SET.add(stacktrace);
|
||||||
Thread t = new Thread(() -> {
|
Thread t = new Thread(() -> {
|
||||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.lookandfeel;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import org.jackhuang.hellominecraft.util.C;
|
import org.jackhuang.hellominecraft.util.C;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,9 +86,7 @@ public enum Theme {
|
|||||||
public final Map<String, String> settings;
|
public final Map<String, String> settings;
|
||||||
|
|
||||||
private Theme(String localizedName, Map<String, String> settings) {
|
private Theme(String localizedName, Map<String, String> settings) {
|
||||||
if (settings == null)
|
|
||||||
throw new NullPointerException("Theme settings map should not be null.");
|
|
||||||
this.localizedName = localizedName;
|
this.localizedName = localizedName;
|
||||||
this.settings = settings;
|
this.settings = Objects.requireNonNull(settings, "Theme settings map may not be null.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,12 @@ public abstract class AbstractSwingWorker<T> extends SwingWorker<Void, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AbstractSwingWorker reg(Consumer<T> c) {
|
public AbstractSwingWorker reg(Consumer<T> c) {
|
||||||
Objects.requireNonNull(c);
|
processListeners.add(Objects.requireNonNull(c));
|
||||||
processListeners.add(c);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractSwingWorker regDone(Runnable c) {
|
public AbstractSwingWorker regDone(Runnable c) {
|
||||||
Objects.requireNonNull(c);
|
doneListeners.add(Objects.requireNonNull(c));
|
||||||
doneListeners.add(c);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
import org.jackhuang.hellominecraft.util.logging.HMCLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,8 +122,7 @@ public final class FileUtils {
|
|||||||
|
|
||||||
public static boolean isSymlink(File file)
|
public static boolean isSymlink(File file)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (file == null)
|
Objects.requireNonNull(file, "File must not be null");
|
||||||
throw new NullPointerException("File must not be null");
|
|
||||||
if (File.separatorChar == '\\')
|
if (File.separatorChar == '\\')
|
||||||
return false;
|
return false;
|
||||||
File fileInCanonicalDir;
|
File fileInCanonicalDir;
|
||||||
@ -143,10 +143,8 @@ public final class FileUtils {
|
|||||||
|
|
||||||
public static void copyDirectory(File srcDir, File destDir, FileFilter filter)
|
public static void copyDirectory(File srcDir, File destDir, FileFilter filter)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (srcDir == null)
|
Objects.requireNonNull(srcDir, "Source must not be null");
|
||||||
throw new NullPointerException("Source must not be null");
|
Objects.requireNonNull(destDir, "Destination must not be null");
|
||||||
if (destDir == null)
|
|
||||||
throw new NullPointerException("Destination must not be null");
|
|
||||||
if (!srcDir.exists())
|
if (!srcDir.exists())
|
||||||
throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
|
throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
|
||||||
if (!srcDir.isDirectory())
|
if (!srcDir.isDirectory())
|
||||||
@ -230,10 +228,8 @@ public final class FileUtils {
|
|||||||
|
|
||||||
public static void copyFile(File srcFile, File destFile)
|
public static void copyFile(File srcFile, File destFile)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (srcFile == null)
|
Objects.requireNonNull(srcFile, "Source must not be null");
|
||||||
throw new NullPointerException("Source must not be null");
|
Objects.requireNonNull(destFile, "Destination must not be null");
|
||||||
if (destFile == null)
|
|
||||||
throw new NullPointerException("Destination must not be null");
|
|
||||||
if (!srcFile.exists())
|
if (!srcFile.exists())
|
||||||
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
|
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
|
||||||
if (srcFile.isDirectory())
|
if (srcFile.isDirectory())
|
||||||
|
@ -36,10 +36,8 @@ public class LogWindowOutputStream extends OutputStream {
|
|||||||
private final Level sas;
|
private final Level sas;
|
||||||
|
|
||||||
public LogWindowOutputStream(LogWindow logWindow, Level l) {
|
public LogWindowOutputStream(LogWindow logWindow, Level l) {
|
||||||
Objects.requireNonNull(logWindow);
|
txt = Objects.requireNonNull(logWindow);
|
||||||
Objects.requireNonNull(l);
|
sas = Objects.requireNonNull(l);
|
||||||
txt = logWindow;
|
|
||||||
sas = l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Wizard with indeterminate branches. The actual branch decision-making is
|
* A Wizard with indeterminate branches. The actual branch decision-making is
|
||||||
@ -105,8 +106,7 @@ final class BranchingWizard extends AbstractWizard {
|
|||||||
if (activeWizard == wizard)
|
if (activeWizard == wizard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (wizard == null)
|
Objects.requireNonNull(wizard, "Can't set current wizard to null");
|
||||||
throw new NullPointerException("Can't set current wizard to null");
|
|
||||||
|
|
||||||
if ((activeWizard != null) && (wl != null))
|
if ((activeWizard != null) && (wl != null))
|
||||||
activeWizard.removeWizardObserver(wl);
|
activeWizard.removeWizardObserver(wl);
|
||||||
@ -260,15 +260,10 @@ final class BranchingWizard extends AbstractWizard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final JComponent navigatingTo(String id, Map settings) {
|
public final JComponent navigatingTo(String id, Map settings) {
|
||||||
if (id == null)
|
currStep = Objects.requireNonNull(id);
|
||||||
throw new NullPointerException();
|
|
||||||
currStep = id;
|
|
||||||
wizardData = settings;
|
wizardData = settings;
|
||||||
|
|
||||||
WizardImplementation impl = ownerOf(id);
|
WizardImplementation impl = Objects.requireNonNull(ownerOf(id), "No owning WizardImplementation for id " + id);
|
||||||
if (impl == null)
|
|
||||||
throw new NullPointerException("No owning WizardImplementation for"
|
|
||||||
+ " id " + id);
|
|
||||||
setCurrent(impl);
|
setCurrent(impl);
|
||||||
|
|
||||||
return activeWizard.navigatingTo(id, settings);
|
return activeWizard.navigatingTo(id, settings);
|
||||||
|
@ -25,6 +25,7 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
@ -59,12 +60,8 @@ public final class SimpleWizardInfo implements WizardControllerImplementation {
|
|||||||
* and descriptions.
|
* and descriptions.
|
||||||
*/
|
*/
|
||||||
protected SimpleWizardInfo(String title, String[] steps, String[] descriptions, WizardPanelProvider provider) {
|
protected SimpleWizardInfo(String title, String[] steps, String[] descriptions, WizardPanelProvider provider) {
|
||||||
if (steps == null)
|
this.steps = Objects.requireNonNull(steps, "Null steps");
|
||||||
throw new NullPointerException("Null steps");
|
this.descriptions = Objects.requireNonNull(descriptions, "Null descriptions");
|
||||||
if (descriptions == null)
|
|
||||||
throw new NullPointerException("Null descriptions");
|
|
||||||
this.steps = steps;
|
|
||||||
this.descriptions = descriptions;
|
|
||||||
if (new HashSet(Arrays.asList(steps)).size() < steps.length)
|
if (new HashSet(Arrays.asList(steps)).size() < steps.length)
|
||||||
throw new IllegalArgumentException("Duplicate ID: " + Arrays.asList(steps));
|
throw new IllegalArgumentException("Duplicate ID: " + Arrays.asList(steps));
|
||||||
if (descriptions.length != steps.length)
|
if (descriptions.length != steps.length)
|
||||||
@ -132,16 +129,6 @@ public final class SimpleWizardInfo implements WizardControllerImplementation {
|
|||||||
* gathered data.
|
* gathered data.
|
||||||
*/
|
*/
|
||||||
protected Object finish(Map settings) throws WizardException {
|
protected Object finish(Map settings) throws WizardException {
|
||||||
//XXX fixme
|
|
||||||
// assert canFinish();
|
|
||||||
|
|
||||||
// SKNUTSON: the "canFinish" behavior is not working
|
|
||||||
// instead, panels must implement the WizardPanel interface
|
|
||||||
// and have allowFinish return false
|
|
||||||
// if ( ! canFinish())
|
|
||||||
// {
|
|
||||||
// throw new RuntimeException ("Can't finish right now");
|
|
||||||
// }
|
|
||||||
return provider.finish(settings);
|
return provider.finish(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,10 +20,13 @@ package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import org.jackhuang.hellominecraft.util.ArrayUtils;
|
||||||
|
import org.jackhuang.hellominecraft.util.StrUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object which may be returned from
|
* Object which may be returned from
|
||||||
@ -56,9 +59,7 @@ public class Summary {
|
|||||||
public Summary(String text, Object result) {
|
public Summary(String text, Object result) {
|
||||||
//XXX this is creating components off the AWT thread - needs to change
|
//XXX this is creating components off the AWT thread - needs to change
|
||||||
//to use invokeAndWait where appropriate
|
//to use invokeAndWait where appropriate
|
||||||
if (text == null)
|
if (StrUtils.isBlank(text))
|
||||||
throw new NullPointerException("Text is null");
|
|
||||||
if (text.trim().length() == 0)
|
|
||||||
throw new IllegalArgumentException("Text is empty or all whitespace");
|
throw new IllegalArgumentException("Text is empty or all whitespace");
|
||||||
this.result = result;
|
this.result = result;
|
||||||
JTextArea jta = new JTextArea();
|
JTextArea jta = new JTextArea();
|
||||||
@ -85,9 +86,7 @@ public class Summary {
|
|||||||
* @return the requested <code>Summary</code> object
|
* @return the requested <code>Summary</code> object
|
||||||
*/
|
*/
|
||||||
public Summary(String[] items, Object result) {
|
public Summary(String[] items, Object result) {
|
||||||
if (items == null)
|
if (ArrayUtils.isEmpty(items))
|
||||||
throw new NullPointerException("Items array null");
|
|
||||||
if (items.length == 0)
|
|
||||||
throw new IllegalArgumentException("Items array empty");
|
throw new IllegalArgumentException("Items array empty");
|
||||||
this.result = result;
|
this.result = result;
|
||||||
JList list = new JList(items);
|
JList list = new JList(items);
|
||||||
@ -108,9 +107,7 @@ public class Summary {
|
|||||||
*/
|
*/
|
||||||
public Summary(Component comp, Object result) {
|
public Summary(Component comp, Object result) {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.comp = comp;
|
this.comp = Objects.requireNonNull(comp, "Null component");
|
||||||
if (comp == null)
|
|
||||||
throw new NullPointerException("Null component");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,7 @@ import java.lang.reflect.Modifier;
|
|||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,10 +72,8 @@ final class Util {
|
|||||||
try {
|
try {
|
||||||
Method m = clazz.getDeclaredMethod("getStep", new Class[]{});
|
Method m = clazz.getDeclaredMethod("getStep", new Class[]{});
|
||||||
// assert m.getReturnType() == String.class;
|
// assert m.getReturnType() == String.class;
|
||||||
result = (String) m.invoke(clazz, (Object[]) null);
|
result = Objects.requireNonNull((String) m.invoke(clazz, (Object[]) null), "getStep may not return null");
|
||||||
if (result == null)
|
} catch (Exception ex) {
|
||||||
throw new NullPointerException("getStep may not return null");
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | NullPointerException | SecurityException | InvocationTargetException ex) {
|
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
return result == null ? clazz.getName() : result;
|
return result == null ? clazz.getName() : result;
|
||||||
@ -85,16 +84,13 @@ final class Util {
|
|||||||
* class object passed
|
* class object passed
|
||||||
*/
|
*/
|
||||||
static String[] getSteps(Class[] pages) {
|
static String[] getSteps(Class[] pages) {
|
||||||
if (pages == null)
|
Objects.requireNonNull(pages, "Null array of classes");
|
||||||
throw new NullPointerException("Null array of classes");
|
|
||||||
|
|
||||||
String[] result = new String[pages.length];
|
String[] result = new String[pages.length];
|
||||||
|
|
||||||
Set used = new HashSet(pages.length);
|
Set used = new HashSet(pages.length);
|
||||||
for (int i = 0; i < pages.length; i++) {
|
for (int i = 0; i < pages.length; i++) {
|
||||||
if (pages[i] == null)
|
Objects.requireNonNull(pages[i], "Null at " + i + " in array of panel classes");
|
||||||
throw new NullPointerException("Null at " + i + " in array "
|
|
||||||
+ "of panel classes");
|
|
||||||
|
|
||||||
if (!WizardPage.class.isAssignableFrom(pages[i]))
|
if (!WizardPage.class.isAssignableFrom(pages[i]))
|
||||||
throw new IllegalArgumentException(pages[i]
|
throw new IllegalArgumentException(pages[i]
|
||||||
|
@ -15,6 +15,7 @@ import java.util.Collections;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer;
|
import org.jackhuang.hellominecraft.util.ui.wizard.api.WizardDisplayer;
|
||||||
@ -121,9 +122,7 @@ public final class Wizard {
|
|||||||
* Creates a new instance of Wizard
|
* Creates a new instance of Wizard
|
||||||
*/
|
*/
|
||||||
Wizard(WizardImplementation impl) {
|
Wizard(WizardImplementation impl) {
|
||||||
this.impl = impl;
|
this.impl = Objects.requireNonNull(impl);
|
||||||
if (impl == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -321,6 +320,7 @@ public final class Wizard {
|
|||||||
|
|
||||||
private class ImplL implements WizardObserver {
|
private class ImplL implements WizardObserver {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void stepsChanged(Wizard wizard) {
|
public void stepsChanged(Wizard wizard) {
|
||||||
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
||||||
new WizardObserver[listeners.size()]);
|
new WizardObserver[listeners.size()]);
|
||||||
@ -328,6 +328,7 @@ public final class Wizard {
|
|||||||
l1.stepsChanged(Wizard.this);
|
l1.stepsChanged(Wizard.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void navigabilityChanged(Wizard wizard) {
|
public void navigabilityChanged(Wizard wizard) {
|
||||||
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
||||||
new WizardObserver[listeners.size()]);
|
new WizardObserver[listeners.size()]);
|
||||||
@ -335,6 +336,7 @@ public final class Wizard {
|
|||||||
l1.navigabilityChanged(Wizard.this);
|
l1.navigabilityChanged(Wizard.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void selectionChanged(Wizard wizard) {
|
public void selectionChanged(Wizard wizard) {
|
||||||
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
WizardObserver[] l = (WizardObserver[]) listeners.toArray(
|
||||||
new WizardObserver[listeners.size()]);
|
new WizardObserver[listeners.size()]);
|
||||||
@ -343,10 +345,12 @@ public final class Wizard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return impl.hashCode() * 17;
|
return impl.hashCode() * 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o == this)
|
if (o == this)
|
||||||
return true;
|
return true;
|
||||||
|
@ -16,6 +16,7 @@ enclosed by brackets [] replaced by your own identifying information:
|
|||||||
package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend this class to create wizards which have branch points in them -
|
* Extend this class to create wizards which have branch points in them -
|
||||||
@ -93,9 +94,7 @@ public abstract class WizardBranchController {
|
|||||||
* for the initial panes of the wizard.
|
* for the initial panes of the wizard.
|
||||||
*/
|
*/
|
||||||
WizardBranchController(SimpleWizardInfo base) {
|
WizardBranchController(SimpleWizardInfo base) {
|
||||||
if (base == null)
|
this.base = Objects.requireNonNull(base, "No base");
|
||||||
throw new NullPointerException("No base");
|
|
||||||
this.base = base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,10 +165,6 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
throw new IllegalStateException("CustomComponentListener "
|
throw new IllegalStateException("CustomComponentListener "
|
||||||
+ "will never be called if the autoListen parameter is "
|
+ "will never be called if the autoListen parameter is "
|
||||||
+ "false");
|
+ "false");
|
||||||
// if (getClass() == WizardPage.class && stepId == null ||
|
|
||||||
// description == null) {
|
|
||||||
// throw new NullPointerException ("Step or ID is null");
|
|
||||||
// }
|
|
||||||
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); //XXX
|
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); //XXX
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +335,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
this.page = page; //Slightly smaller footprint a nested, not inner class
|
this.page = page; //Slightly smaller footprint a nested, not inner class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void userInputReceived(Component c, Object event) {
|
public void userInputReceived(Component c, Object event) {
|
||||||
if (!page.ccl.accept(c))
|
if (!page.ccl.accept(c))
|
||||||
return;
|
return;
|
||||||
@ -362,6 +359,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addNotify() {
|
public void addNotify() {
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
if (!listening)
|
if (!listening)
|
||||||
@ -376,14 +374,17 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public WizardPanelNavResult allowBack(String stepName, Map settings, Wizard wizard) {
|
public WizardPanelNavResult allowBack(String stepName, Map settings, Wizard wizard) {
|
||||||
return WizardPanelNavResult.PROCEED;
|
return WizardPanelNavResult.PROCEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public WizardPanelNavResult allowFinish(String stepName, Map settings, Wizard wizard) {
|
public WizardPanelNavResult allowFinish(String stepName, Map settings, Wizard wizard) {
|
||||||
return WizardPanelNavResult.PROCEED;
|
return WizardPanelNavResult.PROCEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public WizardPanelNavResult allowNext(String stepName, Map settings, Wizard wizard) {
|
public WizardPanelNavResult allowNext(String stepName, Map settings, Wizard wizard) {
|
||||||
return WizardPanelNavResult.PROCEED;
|
return WizardPanelNavResult.PROCEED;
|
||||||
}
|
}
|
||||||
@ -830,7 +831,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static WizardPanelProvider createWizardPanelProvider(WizardPage page) {
|
static WizardPanelProvider createWizardPanelProvider(WizardPage page) {
|
||||||
return new WPP(new WizardPage[]{page}, WizardResultProducer.NO_OP);
|
return new WPP(new WizardPage[] { page }, WizardResultProducer.NO_OP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WizardPanelProvider createWizardPanelProvider(WizardPage[] page) {
|
static WizardPanelProvider createWizardPanelProvider(WizardPage[] page) {
|
||||||
@ -879,6 +880,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
this.finish = finish;
|
this.finish = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected JComponent createPanel(WizardController controller, String id,
|
protected JComponent createPanel(WizardController controller, String id,
|
||||||
Map wizardData) {
|
Map wizardData) {
|
||||||
int idx = indexOfStep(id);
|
int idx = indexOfStep(id);
|
||||||
@ -907,14 +909,17 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Object finish(Map settings) throws WizardException {
|
protected Object finish(Map settings) throws WizardException {
|
||||||
return finish.finish(settings);
|
return finish.finish(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean cancel(Map settings) {
|
public boolean cancel(Map settings) {
|
||||||
return finish.cancel(settings);
|
return finish.cancel(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getLongDescription(String stepId) {
|
public String getLongDescription(String stepId) {
|
||||||
for (WizardPage wizardPage : pages)
|
for (WizardPage wizardPage : pages)
|
||||||
if (stepId.equals(wizardPage.getID()))
|
if (stepId.equals(wizardPage.getID()))
|
||||||
@ -974,6 +979,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
this.finish = finish;
|
this.finish = finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected JComponent createPanel(WizardController controller, String id, Map wizardData) {
|
protected JComponent createPanel(WizardController controller, String id, Map wizardData) {
|
||||||
int idx = indexOfStep(id);
|
int idx = indexOfStep(id);
|
||||||
|
|
||||||
@ -995,18 +1001,22 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Object finish(Map settings) throws WizardException {
|
protected Object finish(Map settings) throws WizardException {
|
||||||
return finish.finish(settings);
|
return finish.finish(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean cancel(Map settings) {
|
public boolean cancel(Map settings) {
|
||||||
return finish.cancel(settings);
|
return finish.cancel(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " for " + finish;
|
return super.toString() + " for " + finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getLongDescription(String stepId) {
|
public String getLongDescription(String stepId) {
|
||||||
int idx = indexOfStep(stepId);
|
int idx = indexOfStep(stepId);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
@ -1027,10 +1037,12 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
private int canFinish = -1;
|
private int canFinish = -1;
|
||||||
private Boolean busy = null;
|
private Boolean busy = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setProblem(String value) {
|
public void setProblem(String value) {
|
||||||
this.problem = value;
|
this.problem = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setForwardNavigationMode(int value) {
|
public void setForwardNavigationMode(int value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case WizardController.MODE_CAN_CONTINUE:
|
case WizardController.MODE_CAN_CONTINUE:
|
||||||
@ -1044,6 +1056,7 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
canFinish = value;
|
canFinish = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setBusy(boolean busy) {
|
public void setBusy(boolean busy) {
|
||||||
this.busy = busy ? Boolean.TRUE : Boolean.FALSE;
|
this.busy = busy ? Boolean.TRUE : Boolean.FALSE;
|
||||||
}
|
}
|
||||||
@ -1106,14 +1119,17 @@ public class WizardPage extends JPanel implements WizardPanel {
|
|||||||
* A no-op WizardResultProducer that returns null.
|
* A no-op WizardResultProducer that returns null.
|
||||||
*/
|
*/
|
||||||
WizardResultProducer NO_OP = new WizardResultProducer() {
|
WizardResultProducer NO_OP = new WizardResultProducer() {
|
||||||
|
@Override
|
||||||
public Object finish(Map wizardData) {
|
public Object finish(Map wizardData) {
|
||||||
return wizardData;
|
return wizardData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean cancel(Map settings) {
|
public boolean cancel(Map settings) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "NO_OP WizardResultProducer";
|
return "NO_OP WizardResultProducer";
|
||||||
}
|
}
|
||||||
|
@ -8,44 +8,44 @@ and include the License file at http://www.netbeans.org/cddl.txt.
|
|||||||
If applicable, add the following below the CDDL Header, with the fields
|
If applicable, add the following below the CDDL Header, with the fields
|
||||||
enclosed by brackets [] replaced by your own identifying information:
|
enclosed by brackets [] replaced by your own identifying information:
|
||||||
"Portions Copyrighted [year] [name of copyright owner]" */
|
"Portions Copyrighted [year] [name of copyright owner]" */
|
||||||
/*
|
/*
|
||||||
* PanelProvider.java
|
* PanelProvider.java
|
||||||
*
|
*
|
||||||
* Created on March 5, 2005, 7:25 PM
|
* Created on March 5, 2005, 7:25 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
package org.jackhuang.hellominecraft.util.ui.wizard.spi;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Note: <code>WizardPage</code> offers somewhat simpler functionality for
|
* (Note: <code>WizardPage</code> offers somewhat simpler functionality for
|
||||||
* creating a wizard than does WizardPanelProvider; the only advantage of
|
* creating a wizard than does WizardPanelProvider; the only advantage of
|
||||||
* <code>WizardPanelProvider</code> is that it does not require one to
|
* <code>WizardPanelProvider</code> is that it does not require one to subclass
|
||||||
* subclass a panel component).
|
* a panel component).
|
||||||
* <p>
|
* <p>
|
||||||
* A simple interface for providing a fixed set of panels for a wizard.
|
* A simple interface for providing a fixed set of panels for a wizard. To use,
|
||||||
* To use, simply implement <code>createPanel()</code> to create the
|
* simply implement <code>createPanel()</code> to create the appropriate UI
|
||||||
* appropriate UI component for a given step (a unique String ID - one of the ones passed
|
* component for a given step (a unique String ID - one of the ones passed in
|
||||||
* in the constructor in the <code>steps</code> array), and implement
|
* the constructor in the <code>steps</code> array), and implement
|
||||||
* <code>finish()</code> to do whatever should be done when the wizard is
|
* <code>finish()</code> to do whatever should be done when the wizard is
|
||||||
* finished.
|
* finished.
|
||||||
* <p>
|
* <p>
|
||||||
* To control whether the Next/Finish buttons are enabled, components
|
* To control whether the Next/Finish buttons are enabled, components created in
|
||||||
* created in <code>createPanel()</code> should call methods on the <code>
|
* <code>createPanel()</code> should call methods on the <code>
|
||||||
* WizardController</code> passed. The created panels should listen on the
|
* WizardController</code> passed. The created panels should listen on the UI
|
||||||
* UI components they create, updating the settings Map when the user changes
|
* components they create, updating the settings Map when the user changes their
|
||||||
* their input.
|
* input.
|
||||||
* <p>
|
* <p>
|
||||||
* Super-simple one-pane wizard example - if the checkbox is checked, the user
|
* Super-simple one-pane wizard example - if the checkbox is checked, the user
|
||||||
* can continue:
|
* can continue:
|
||||||
* <pre>
|
* <pre>
|
||||||
* public class MyProvider extends WizardPanelProvider {
|
* public class MyProvider extends WizardPanelProvider {
|
||||||
* public MyProvider() {
|
* public MyProvider() {
|
||||||
* <font color="gray">//here we pass a localized title for the wizard,
|
* <font color="gray">//here we pass a localized title for the wizard,
|
||||||
* //the ID of the one step it will have, and a localized description
|
* //the ID of the one step it will have, and a localized description
|
||||||
* //the wizard can show for that one step</font>
|
* //the wizard can show for that one step</font>
|
||||||
* super ("Click the box", "click", "Click the checkbox");
|
* super ("Click the box", "click", "Click the checkbox");
|
||||||
@ -57,7 +57,7 @@ import javax.swing.JComponent;
|
|||||||
* final JCheckBox result = new JCheckBox();
|
* final JCheckBox result = new JCheckBox();
|
||||||
* result.addActionListener (new ActionListener() {
|
* result.addActionListener (new ActionListener() {
|
||||||
* public void actionPerformed (ActionEvent ae) {
|
* public void actionPerformed (ActionEvent ae) {
|
||||||
* <font color="gray">//Typically you want to write the result of some user
|
* <font color="gray">//Typically you want to write the result of some user
|
||||||
* //action into the settings map as soon as they do it </font>
|
* //action into the settings map as soon as they do it </font>
|
||||||
* settings.put ("boxSelected", result.isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
* settings.put ("boxSelected", result.isSelected() ? Boolean.TRUE : Boolean.FALSE);
|
||||||
* if (result.isSelected()) {
|
* if (result.isSelected()) {
|
||||||
@ -72,7 +72,7 @@ import javax.swing.JComponent;
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* protected Object finish (Map settings) throws WizardException {
|
* protected Object finish (Map settings) throws WizardException {
|
||||||
* <font color="gray">//if we had some interesting information (Strings a user put in a
|
* <font color="gray">//if we had some interesting information (Strings a user put in a
|
||||||
* //text field or something, we'd generate some interesting object or
|
* //text field or something, we'd generate some interesting object or
|
||||||
* //create some files or something here</font>
|
* //create some files or something here</font>
|
||||||
* return null;
|
* return null;
|
||||||
@ -83,240 +83,229 @@ import javax.swing.JComponent;
|
|||||||
* @author Tim Boudreau
|
* @author Tim Boudreau
|
||||||
*/
|
*/
|
||||||
public abstract class WizardPanelProvider {
|
public abstract class WizardPanelProvider {
|
||||||
|
|
||||||
final String title;
|
final String title;
|
||||||
final String[] descriptions;
|
final String[] descriptions;
|
||||||
final String[] steps;
|
final String[] steps;
|
||||||
final String[] knownProblems;
|
final String[] knownProblems;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a WizardPanelProvider. The passed array of steps and descriptions
|
* Create a WizardPanelProvider. The passed array of steps and descriptions
|
||||||
* will be used as IDs and localized descriptions of the various steps in
|
* will be used as IDs and localized descriptions of the various steps in
|
||||||
* the wizard. Use this constructor (which passes not title) for sub-wizards
|
* the wizard. Use this constructor (which passes not title) for sub-wizards
|
||||||
* used in a <code>WizardBranchController</code>, where the first pane
|
* used in a <code>WizardBranchController</code>, where the first pane will
|
||||||
* will determine the title, and the titles of the sub-wizards will never be
|
* determine the title, and the titles of the sub-wizards will never be
|
||||||
* shown.
|
* shown.
|
||||||
* @param steps A set of unique IDs identifying each step of this wizard. Each
|
*
|
||||||
* ID must occur only once in the array of steps.
|
* @param steps A set of unique IDs identifying each step of this wizard.
|
||||||
*
|
* Each ID must occur only once in the array of steps.
|
||||||
|
*
|
||||||
* @param descriptions A set of human-readable descriptions corresponding
|
* @param descriptions A set of human-readable descriptions corresponding
|
||||||
* 1:1 with the unique IDs passed as the <code>steps</code> parameter
|
* 1:1 with the unique IDs passed as the <code>steps</code> parameter
|
||||||
*/
|
*/
|
||||||
protected WizardPanelProvider (String[] steps, String[] descriptions) {
|
protected WizardPanelProvider(String[] steps, String[] descriptions) {
|
||||||
this (null, steps, descriptions);
|
this(null, steps, descriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a WizardPanelProvider with the provided title, steps and
|
* Create a WizardPanelProvider with the provided title, steps and
|
||||||
* descriptions. The <code>steps</code> parameter are unique IDs of
|
* descriptions. The <code>steps</code> parameter are unique IDs of panels,
|
||||||
* panels, which will be passed to <code>createPanel</code> to create
|
* which will be passed to <code>createPanel</code> to create panels for
|
||||||
* panels for various steps in the wizard, as the user navigates it.
|
* various steps in the wizard, as the user navigates it. The
|
||||||
* The <code>descriptions</code> parameter is a set of localized descriptions
|
* <code>descriptions</code> parameter is a set of localized descriptions
|
||||||
* that can appear in the Wizard to describe each step.
|
* that can appear in the Wizard to describe each step.
|
||||||
|
*
|
||||||
* @param title A human readable title for the wizard dialog
|
* @param title A human readable title for the wizard dialog
|
||||||
* @param steps An array of unique IDs for the various panels of this
|
* @param steps An array of unique IDs for the various panels of this wizard
|
||||||
* wizard
|
|
||||||
* @param descriptions An array of descriptions corresponding 1:1 with the
|
* @param descriptions An array of descriptions corresponding 1:1 with the
|
||||||
* unique IDs. These must be human readable, localized strings.
|
* unique IDs. These must be human readable, localized strings.
|
||||||
*/
|
*/
|
||||||
protected WizardPanelProvider (String title, String[] steps, String[] descriptions) {
|
protected WizardPanelProvider(String title, String[] steps, String[] descriptions) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.steps = steps;
|
this.steps = steps;
|
||||||
this.descriptions = descriptions;
|
this.descriptions = descriptions;
|
||||||
knownProblems = new String[steps.length];
|
knownProblems = new String[steps.length];
|
||||||
if (steps.length != descriptions.length) {
|
if (steps.length != descriptions.length)
|
||||||
throw new IllegalArgumentException ("Length of steps and" +
|
throw new IllegalArgumentException("Length of steps and"
|
||||||
" descriptions arrays do not match");
|
+ " descriptions arrays do not match");
|
||||||
}
|
|
||||||
// assert validData (steps, descriptions) == null : validData (steps, descriptions);
|
// assert validData (steps, descriptions) == null : validData (steps, descriptions);
|
||||||
String v = validData (steps, descriptions);
|
String v = validData(steps, descriptions);
|
||||||
if (v != null)
|
if (v != null)
|
||||||
{
|
throw new RuntimeException(v);
|
||||||
throw new RuntimeException (v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String validData(String[] steps, String[] descriptions) {
|
||||||
private String validData (String[] steps, String[] descriptions) {
|
if (steps.length != descriptions.length)
|
||||||
if (steps.length != descriptions.length) {
|
return steps.length + " steps but " + descriptions.length
|
||||||
return steps.length + " steps but " + descriptions.length +
|
+ " descriptions";
|
||||||
" descriptions";
|
for (int i = 0; i < steps.length; i++) {
|
||||||
|
Objects.requireNonNull(steps[i], "Step id " + i + " is null");
|
||||||
|
Objects.requireNonNull(descriptions[i], "Description " + i + " is null");
|
||||||
}
|
}
|
||||||
for (int i=0; i < steps.length; i++) {
|
if (new HashSet(Arrays.asList(steps)).size() != steps.length)
|
||||||
if (steps[i] == null) {
|
|
||||||
throw new NullPointerException ("Step id " + i + " is null");
|
|
||||||
}
|
|
||||||
if (descriptions[i] == null) {
|
|
||||||
throw new NullPointerException ("Description " + i + " is null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (new HashSet(Arrays.asList(steps)).size() != steps.length) {
|
|
||||||
return "Duplicate step ids: " + Arrays.asList(steps);
|
return "Duplicate step ids: " + Arrays.asList(steps);
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience constructor to create a WizardPanelProvider which has only
|
* Convenience constructor to create a WizardPanelProvider which has only
|
||||||
* one step to it. Mainly useful for initial steps in a <code>WizardBranchController</code>.
|
* one step to it. Mainly useful for initial steps in a
|
||||||
|
* <code>WizardBranchController</code>.
|
||||||
|
*
|
||||||
* @param title A human readable title for the wizard dialog
|
* @param title A human readable title for the wizard dialog
|
||||||
* @param singleStep The unique ID of the only step this wizard has
|
* @param singleStep The unique ID of the only step this wizard has
|
||||||
* @param singleDescription The human-readable description of what the user
|
* @param singleDescription The human-readable description of what the user
|
||||||
* should do in the one step of this one-step wizard or sub-wizard
|
* should do in the one step of this one-step wizard or sub-wizard
|
||||||
*/
|
*/
|
||||||
protected WizardPanelProvider (String title, String singleStep, String singleDescription) {
|
protected WizardPanelProvider(String title, String singleStep, String singleDescription) {
|
||||||
this (title, new String[] {singleStep}, new String[] {singleDescription});
|
this(title, new String[] { singleStep }, new String[] { singleDescription });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a panel that represents a named step in the wizard.
|
* Create a panel that represents a named step in the wizard. This method
|
||||||
* This method will be called exactly <i>once</i> in the life of
|
* will be called exactly <i>once</i> in the life of a wizard. The panel
|
||||||
* a wizard. The panel should retain the passed settings Map, and
|
* should retain the passed settings Map, and add/remove values from it as
|
||||||
* add/remove values from it as the user enters information, calling
|
* the user enters information, calling <code>setProblem()</code> and
|
||||||
* <code>setProblem()</code> and <code>setCanFinish()</code> as
|
* <code>setCanFinish()</code> as appropriate in response to user input.
|
||||||
* appropriate in response to user input.
|
*
|
||||||
*
|
* @param controller - the object which controls whether the Next/Finish
|
||||||
* @param controller - the object which controls whether the
|
* buttons in the wizard are enabled, and what instructions are displayed to
|
||||||
* Next/Finish buttons in the wizard are enabled, and what instructions
|
* the user if they are not
|
||||||
* are displayed to the user if they are not
|
* @param id The name of the step, one of the array of steps passed in the
|
||||||
* @param id The name of the step, one of the array of steps passed in
|
* constructor
|
||||||
* the constructor
|
* @param settings A Map containing settings from earlier steps in the
|
||||||
* @param settings A Map containing settings from earlier steps in
|
* wizard. It is safe to retain a reference to this map and put values in it
|
||||||
* the wizard. It is safe to retain a reference to this map and put
|
* as the user manipulates the UI; the reference should be refreshed
|
||||||
* values in it as the user manipulates the UI; the reference should
|
* whenever this method is called again.
|
||||||
* be refreshed whenever this method is called again.
|
* @return A JComponent that should be displayed in the center of the wizard
|
||||||
* @return A JComponent that should be displayed in the center of the
|
|
||||||
* wizard
|
|
||||||
*/
|
*/
|
||||||
protected abstract JComponent createPanel (WizardController controller, String id, Map settings);
|
protected abstract JComponent createPanel(WizardController controller, String id, Map settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate whatever object (if any) the wizard creates from its
|
* Instantiate whatever object (if any) the wizard creates from its gathered
|
||||||
* gathered data. The default implementation is a no-op that returns
|
* data. The default implementation is a no-op that returns null.
|
||||||
* null.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If an instance of <code>Summary</code> is returned from this method, the
|
* If an instance of <code>Summary</code> is returned from this method, the
|
||||||
* UI shall display it on a final page and disable all navigation buttons
|
* UI shall display it on a final page and disable all navigation buttons
|
||||||
* except the Close/Cancel button.
|
* except the Close/Cancel button.
|
||||||
* <p>
|
* <p>
|
||||||
* If an instance of <code>DeferredWizardResult</code> is returned from this
|
* If an instance of <code>DeferredWizardResult</code> is returned from this
|
||||||
* method, the UI shall display some sort of progress bar while the result
|
* method, the UI shall display some sort of progress bar while the result
|
||||||
* is computed in the background. If that <code>DeferredWizardResult</code>
|
* is computed in the background. If that <code>DeferredWizardResult</code>
|
||||||
* produces a <code>Summary</code> object, that summary shall be displayed
|
* produces a <code>Summary</code> object, that summary shall be displayed
|
||||||
* as described above.
|
* as described above.
|
||||||
* <p>
|
* <p>
|
||||||
* The default implementation returns the settings map it is passed.
|
* The default implementation returns the settings map it is passed.
|
||||||
*
|
*
|
||||||
* @param settings The settings map, now fully populated with all settings needed
|
* @param settings The settings map, now fully populated with all settings
|
||||||
* to complete the wizard (this method will only be called if
|
* needed to complete the wizard (this method will only be called if
|
||||||
* <code>setProblem(null)</code> and <code>setCanFinish(true)</code> have
|
* <code>setProblem(null)</code> and <code>setCanFinish(true)</code> have
|
||||||
* been called on the <code>WizardController</code> passed to
|
* been called on the <code>WizardController</code> passed to
|
||||||
* <code>createPanel()</code>.
|
* <code>createPanel()</code>.
|
||||||
* @return an object composed based on what the user entered in the wizard -
|
* @return an object composed based on what the user entered in the wizard -
|
||||||
* somethingmeaningful to whatever code invoked the wizard, or null. Note
|
* somethingmeaningful to whatever code invoked the wizard, or null. Note
|
||||||
* special handling if an instance of <code>DeferredWizardResult</code>
|
* special handling if an instance of <code>DeferredWizardResult</code> or
|
||||||
* or <code>Summary</code> is returned from this method.
|
* <code>Summary</code> is returned from this method.
|
||||||
*/
|
*/
|
||||||
protected Object finish (Map settings) throws WizardException {
|
protected Object finish(Map settings) throws WizardException {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The method provides a chance to call setProblem() or setCanFinish() when
|
* The method provides a chance to call setProblem() or setCanFinish() when
|
||||||
* the user re-navigates to a panel they've already seen - in the case
|
* the user re-navigates to a panel they've already seen - in the case that
|
||||||
* that the user pressed the Previous button and then the Next button.
|
* the user pressed the Previous button and then the Next button.
|
||||||
* <p>
|
* <p>
|
||||||
* The default implementation does nothing, which is sufficient for most
|
* The default implementation does nothing, which is sufficient for most
|
||||||
* cases.
|
* cases. If whether this panel is valid or not could have changed because
|
||||||
* If whether this panel is valid or not could
|
* of changed data from a previous panel, or it displays data entered on
|
||||||
* have changed because of changed data from a previous panel, or it
|
* previous panes which may have changed, you may want to override this
|
||||||
* displays data entered on previous panes which may have changed,
|
* method to ensure validity and canFinish are set correctly, and that the
|
||||||
* you may want to override this method to ensure validity and canFinish
|
* components have the correct text.
|
||||||
* are set correctly, and that the components have the correct text.
|
|
||||||
* <p>
|
* <p>
|
||||||
* This method will <i>not</i> be called when a panel is first instantiated -
|
* This method will <i>not</i> be called when a panel is first instantiated
|
||||||
* <code>createPanel()</code> is expected to set validity and canFinish
|
* - <code>createPanel()</code> is expected to set validity and canFinish
|
||||||
* appropriately.
|
* appropriately.
|
||||||
* <p>
|
* <p>
|
||||||
* The settings Map passed to this method will always be the same
|
* The settings Map passed to this method will always be the same Settings
|
||||||
* Settings map instance that was passed to <code>createPanel()</code>
|
* map instance that was passed to <code>createPanel()</code> when the panel
|
||||||
* when the panel was created.
|
* was created.
|
||||||
* <p>
|
* <p>
|
||||||
* If you are implementing WizardPanelProvider and some of the pages are
|
* If you are implementing WizardPanelProvider and some of the pages are
|
||||||
* <code>WizardPage</code>s, you should call the super implementation if
|
* <code>WizardPage</code>s, you should call the super implementation if you
|
||||||
* you override this method.
|
* override this method.
|
||||||
*/
|
*/
|
||||||
protected void recycleExistingPanel (String id, WizardController controller, Map wizardData, JComponent panel) {
|
protected void recycleExistingPanel(String id, WizardController controller, Map wizardData, JComponent panel) {
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
void recycle (String id, WizardController controller, Map wizardData, JComponent panel) {
|
void recycle(String id, WizardController controller, Map wizardData, JComponent panel) {
|
||||||
if (panel instanceof WizardPage) {
|
if (panel instanceof WizardPage) {
|
||||||
WizardPage page = (WizardPage) panel;
|
WizardPage page = (WizardPage) panel;
|
||||||
page.setController(controller);
|
page.setController(controller);
|
||||||
page.setWizardDataMap(wizardData);
|
page.setWizardDataMap(wizardData);
|
||||||
page.recycle();
|
page.recycle();
|
||||||
}
|
}
|
||||||
recycleExistingPanel (id, controller, wizardData, panel);
|
recycleExistingPanel(id, controller, wizardData, panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Wizard wizard;
|
private Wizard wizard;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Wizard for this PanelProvider. The instance created by this
|
* Create a Wizard for this PanelProvider. The instance created by this
|
||||||
* method is cached and the same instance will be returned on subsequent
|
* method is cached and the same instance will be returned on subsequent
|
||||||
* calls.
|
* calls.
|
||||||
*/
|
*/
|
||||||
public final Wizard createWizard() {
|
public final Wizard createWizard() {
|
||||||
if (wizard == null) {
|
if (wizard == null)
|
||||||
wizard = new Wizard (new SimpleWizard (this));
|
wizard = new Wizard(new SimpleWizard(this));
|
||||||
}
|
|
||||||
return wizard;
|
return wizard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method can optionally be overridden to provide a longer
|
* This method can optionally be overridden to provide a longer description
|
||||||
* description of a step to be shown in the top of its panel.
|
* of a step to be shown in the top of its panel. The default implementation
|
||||||
* The default implementation returns null, indicating that the
|
* returns null, indicating that the short description should be used.
|
||||||
* short description should be used.
|
*
|
||||||
*
|
|
||||||
* @param stepId a unique id for one step of the wizard
|
* @param stepId a unique id for one step of the wizard
|
||||||
* @return An alternate description for use in the top of the wizard
|
* @return An alternate description for use in the top of the wizard page
|
||||||
* page when this page is the current one, or null
|
* when this page is the current one, or null
|
||||||
*/
|
*/
|
||||||
public String getLongDescription (String stepId) {
|
public String getLongDescription(String stepId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to get the index into the array of steps passed to
|
* Convenience method to get the index into the array of steps passed to the
|
||||||
* the constructor of a specific step id.
|
* constructor of a specific step id.
|
||||||
*/
|
*/
|
||||||
protected final int indexOfStep (String id) {
|
protected final int indexOfStep(String id) {
|
||||||
return Arrays.asList(steps).indexOf(id);
|
return Arrays.asList(steps).indexOf(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setKnownProblem (String problem, int idx) {
|
void setKnownProblem(String problem, int idx) {
|
||||||
//Record a problem message so we can put it back if the user does
|
//Record a problem message so we can put it back if the user does
|
||||||
//prev and then next
|
//prev and then next
|
||||||
if (idx >= 0) { //setProblem() can be called during initialization
|
if (idx >= 0) //setProblem() can be called during initialization
|
||||||
knownProblems[idx] = problem;
|
knownProblems[idx] = problem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String getKnownProblem(int idx) {
|
String getKnownProblem(int idx) {
|
||||||
return knownProblems[idx];
|
return knownProblems[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called if the user invokes cancel. The default impl returns
|
* Called if the user invokes cancel. The default impl returns true.
|
||||||
* true.
|
*
|
||||||
* @return false to abort cancellation (almost all implementations will
|
* @return false to abort cancellation (almost all implementations will want
|
||||||
* want to return true - this is really only applicable in cases such
|
* to return true - this is really only applicable in cases such as an OS
|
||||||
* as an OS installer or such).
|
* installer or such).
|
||||||
*/
|
*/
|
||||||
public boolean cancel(Map settings) {
|
public boolean cancel(Map settings) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " with wizard " + wizard;
|
return super.toString() + " with wizard " + wizard;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user