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