102
src/main/java/eva2/EvAInfo.java
Normal file
102
src/main/java/eva2/EvAInfo.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package eva2;
|
||||
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author mkron
|
||||
*/
|
||||
public class EvAInfo {
|
||||
/**
|
||||
* Product Name.
|
||||
*/
|
||||
public static final String productName = "EvA2";
|
||||
|
||||
/**
|
||||
* Long product name.
|
||||
*/
|
||||
public static final String productLongName = "Evolutionary Algorithms Workbench 2";
|
||||
|
||||
/**
|
||||
* Website URL of EvA2.
|
||||
*/
|
||||
public static final String url = "http://www.cogsys.cs.uni-tuebingen.de/software/EvA2";
|
||||
|
||||
/**
|
||||
* Relative path to default properties.
|
||||
*/
|
||||
public static final String propertyFile = "META-INF/EvA2.props";
|
||||
|
||||
public static final String LGPLFile = "lgpl-3.0.txt";
|
||||
public static final String GPLFile = "gpl-3.0.txt";
|
||||
|
||||
/**
|
||||
* Relative path to application icon.
|
||||
*/
|
||||
public static final String iconLocation = "images/icon.png";
|
||||
|
||||
/**
|
||||
* Relative path to splash screen image.
|
||||
*/
|
||||
public static final String splashLocation = "images/EvASplashScreen.png";
|
||||
|
||||
public static final String infoTitle = productName + " Information";
|
||||
public static final String copyrightYear = "2010-2014";
|
||||
|
||||
private static Properties evaProperties;
|
||||
|
||||
static {
|
||||
try {
|
||||
evaProperties = BasicResourceLoader.readProperties(EvAInfo.propertyFile);
|
||||
} catch (Exception ex) {
|
||||
System.err.println(resourceNotFoundErrorMessage(EvAInfo.propertyFile));
|
||||
System.err.println(ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
InputStream istr = BasicResourceLoader.getInstance().getStreamFromResourceLocation(EvAInfo.iconLocation);
|
||||
if (istr == null) {
|
||||
throw new RuntimeException(resourceNotFoundErrorMessage(EvAInfo.iconLocation) + " (EvAInfo.static)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An eloquent error message in case a resource was not found - which was
|
||||
* expected in the EvA2 resource directory.
|
||||
*
|
||||
* @param resourceName
|
||||
* @return
|
||||
*/
|
||||
public static String resourceNotFoundErrorMessage(String resourceName) {
|
||||
String cp = System.getProperty("java.class.path");
|
||||
return "Could not find " + resourceName +
|
||||
"\nPlease make resources folder available on the class path! " +
|
||||
"Current class path is: " + cp +
|
||||
"\nYou may copy it there or add the parent folder of resources/ to the class path.";
|
||||
}
|
||||
|
||||
public static String getProperty(String key) {
|
||||
return evaProperties.getProperty(key);
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return evaProperties;
|
||||
}
|
||||
|
||||
private static void setProperty(String key, String value) {
|
||||
evaProperties.setProperty(key, value);
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
String version = getProperty("EvA2Version");
|
||||
if (version == null) {
|
||||
System.err.println("ERROR, missing property EvA2Version!");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public static String propDefaultModule() {
|
||||
return getProperty("DefaultModule");
|
||||
}
|
||||
}
|
||||
1628
src/main/java/eva2/OptimizerFactory.java
Normal file
1628
src/main/java/eva2/OptimizerFactory.java
Normal file
File diff suppressed because it is too large
Load Diff
287
src/main/java/eva2/OptimizerRunnable.java
Normal file
287
src/main/java/eva2/OptimizerRunnable.java
Normal file
@@ -0,0 +1,287 @@
|
||||
package eva2;
|
||||
|
||||
import eva2.optimization.InterfaceOptimizationParameters;
|
||||
import eva2.optimization.OptimizationStateListener;
|
||||
import eva2.optimization.Processor;
|
||||
import eva2.optimization.individuals.IndividualInterface;
|
||||
import eva2.optimization.individuals.InterfaceDataTypeBinary;
|
||||
import eva2.optimization.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.optimization.individuals.InterfaceDataTypeInteger;
|
||||
import eva2.optimization.operator.postprocess.InterfacePostProcessParams;
|
||||
import eva2.optimization.operator.postprocess.PostProcessParams;
|
||||
import eva2.optimization.operator.terminators.InterfaceTerminator;
|
||||
import eva2.optimization.population.Population;
|
||||
import eva2.optimization.population.SolutionSet;
|
||||
import eva2.optimization.statistics.*;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.BitSet;
|
||||
|
||||
|
||||
/**
|
||||
* This Runnable class just encapsulates the Processor class with some simple ways to access a solution.
|
||||
*
|
||||
* @author mkron
|
||||
*/
|
||||
public class OptimizerRunnable implements Runnable {
|
||||
private Processor proc;
|
||||
private boolean isFinished = false;
|
||||
private boolean doRestart = false; // indicate whether start or restart should be done --> whether pop will be reinitialized.
|
||||
private boolean postProcessOnly = false;
|
||||
private InterfaceTextListener listener = null;
|
||||
private String ident = "OptimizerRunnable";
|
||||
private static int cntID = 0;
|
||||
private int rnblID = -1;
|
||||
|
||||
/**
|
||||
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance without restart,
|
||||
* meaning that the population will be initialized randomly.
|
||||
*
|
||||
* @param params
|
||||
* @param outputFilePrefix
|
||||
*/
|
||||
public OptimizerRunnable(InterfaceOptimizationParameters params, String outputFilePrefix) {
|
||||
this(params, outputFilePrefix, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor assumes that DummyStatistics are enough. This saves time e.g. for small populations.
|
||||
* If restart is true, the processor will not reinitialize the population allowing search on predefined populations.
|
||||
*
|
||||
* @param params
|
||||
* @param restart
|
||||
*/
|
||||
public OptimizerRunnable(InterfaceOptimizationParameters params, boolean restart) {
|
||||
this(params, new StatisticsDummy(), restart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an OptimizerRunnable with given parameters and a StatisticsStandalone instance with optional restart.
|
||||
* If restart is true, the processor will not reinitialize the population allowing search on predefined populations.
|
||||
* The outputFilePrefix may be null.
|
||||
*
|
||||
* @param params
|
||||
* @param outputFilePrefix
|
||||
* @param restart
|
||||
*/
|
||||
public OptimizerRunnable(InterfaceOptimizationParameters params, String outputFilePrefix, boolean restart) {
|
||||
this(params, new StatisticsStandalone(outputFilePrefix), restart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an OptimizerRunnable with given parameters and statistics instance with optional restart.
|
||||
* If restart is true, the processor will not reinitialize the population allowing search on predefined populations.
|
||||
*
|
||||
* @param params
|
||||
* @param stats
|
||||
* @param restart
|
||||
*/
|
||||
public OptimizerRunnable(InterfaceOptimizationParameters params, InterfaceStatistics stats, boolean restart) {
|
||||
rnblID = cntID;
|
||||
cntID++;
|
||||
|
||||
proc = new Processor(stats, params);
|
||||
if (proc.getStatistics() instanceof AbstractStatistics) {
|
||||
((AbstractStatistics) proc.getStatistics()).setSaveParams(false);
|
||||
}
|
||||
doRestart = restart;
|
||||
}
|
||||
|
||||
public void setIdentifier(String id) {
|
||||
ident = id;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return ident;
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique ID for the runnable.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getID() {
|
||||
return rnblID;
|
||||
}
|
||||
|
||||
public InterfaceOptimizationParameters getOptimizationParameters() {
|
||||
return proc.getOptimizationParameters();
|
||||
}
|
||||
|
||||
public InterfaceStatistics getStats() {
|
||||
return proc.getStatistics();
|
||||
}
|
||||
|
||||
public void setStatistics(InterfaceStatistics stats) {
|
||||
if (proc.isOptimizationRunning()) {
|
||||
throw new RuntimeException("Error - cannot change statistics instance during optimization.");
|
||||
}
|
||||
InterfaceOptimizationParameters params = proc.getOptimizationParameters();
|
||||
proc = new Processor(stats, params);
|
||||
if (proc.getStatistics() instanceof AbstractStatistics) {
|
||||
((AbstractStatistics) proc.getStatistics()).setSaveParams(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextListener(InterfaceTextListener lsnr) {
|
||||
proc.getStatistics().removeTextListener(listener);
|
||||
this.listener = lsnr;
|
||||
if (listener != null) {
|
||||
proc.getStatistics().addTextListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addOptimizationStateListener(OptimizationStateListener rsl) {
|
||||
if (proc != null) {
|
||||
proc.addListener(rsl);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDoRestart(boolean restart) {
|
||||
doRestart = restart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
isFinished = false;
|
||||
try {
|
||||
proc.setSaveParams(false);
|
||||
if (postProcessOnly) {
|
||||
proc.performPostProcessing((PostProcessParams) proc.getOptimizationParameters().getPostProcessParams(), listener);
|
||||
} else {
|
||||
if (doRestart) {
|
||||
proc.restartOptimization();
|
||||
} else {
|
||||
proc.startOptimization();
|
||||
}
|
||||
proc.runOptimizationOnce();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
proc.getStatistics().printToTextListener("Exception in OptimizeThread::run: " + e.getMessage() + "\n");
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
proc.getStatistics().printToTextListener(sw.toString());
|
||||
}
|
||||
isFinished = true;
|
||||
synchronized (this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDoPostProcessOnly(boolean poPO) {
|
||||
postProcessOnly = poPO;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
public boolean wasAborted() {
|
||||
return (proc != null && (proc.wasAborted()));
|
||||
}
|
||||
|
||||
public void restartOpt() {
|
||||
proc.restartOptimization();
|
||||
}
|
||||
|
||||
public void stopOpt() {
|
||||
proc.stopOptimization();
|
||||
}
|
||||
|
||||
public IndividualInterface getResult() {
|
||||
return proc.getStatistics().getBestSolution();
|
||||
}
|
||||
|
||||
public Population getResultPopulation() {
|
||||
return proc.getResultPopulation();
|
||||
}
|
||||
|
||||
public SolutionSet getSolutionSet() {
|
||||
return (SolutionSet) proc.getOptimizationParameters().getOptimizer().getAllSolutions();
|
||||
}
|
||||
|
||||
public void setPostProcessingParams(InterfacePostProcessParams ppp) {
|
||||
proc.getOptimizationParameters().setPostProcessParams(ppp);
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return proc.getOptimizationParameters().getOptimizer().getPopulation().getFunctionCalls();
|
||||
}
|
||||
|
||||
public String terminatedBecause() {
|
||||
if (isFinished) {
|
||||
if (postProcessOnly) {
|
||||
return "Post processing finished";
|
||||
} else {
|
||||
InterfaceTerminator term = proc.getOptimizationParameters().getTerminator();
|
||||
return term.lastTerminationMessage();
|
||||
}
|
||||
} else {
|
||||
return "Not yet terminated";
|
||||
}
|
||||
}
|
||||
|
||||
public double[] getDoubleSolution() {
|
||||
IndividualInterface indy = getResult();
|
||||
if (indy instanceof InterfaceDataTypeDouble) {
|
||||
return ((InterfaceDataTypeDouble) indy).getDoubleData();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public BitSet getBinarySolution() {
|
||||
IndividualInterface indy = getResult();
|
||||
if (indy instanceof InterfaceDataTypeBinary) {
|
||||
return ((InterfaceDataTypeBinary) indy).getBinaryData();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getIntegerSolution() {
|
||||
IndividualInterface indy = getResult();
|
||||
if (indy instanceof InterfaceDataTypeInteger) {
|
||||
return ((InterfaceDataTypeInteger) indy).getIntegerData();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the verbosity level in the statistics module to the given value.
|
||||
*
|
||||
* @param vLev
|
||||
*/
|
||||
public void setVerbosityLevel(InterfaceStatisticsParameters.OutputVerbosity vLev) {
|
||||
proc.getStatistics().getStatisticsParameters().setOutputVerbosity(vLev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output direction in the statistics module.
|
||||
*
|
||||
* @param outp
|
||||
*/
|
||||
public void setOutputTo(InterfaceStatisticsParameters.OutputTo outp) {
|
||||
proc.getStatistics().getStatisticsParameters().setOutputTo(outp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of multiruns in the statistics module.
|
||||
*
|
||||
* @param multis
|
||||
*/
|
||||
public void setMultiRuns(int multis) {
|
||||
proc.getStatistics().getStatisticsParameters().setMultiRuns(multis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether full stats should be printed as text (or only selected entries).
|
||||
*
|
||||
* @param addInfo
|
||||
*/
|
||||
public void setOutputFullStatsToText(boolean addInfo) {
|
||||
proc.getStatistics().getStatisticsParameters().setOutputAllFieldsAsText(addInfo);
|
||||
}
|
||||
}
|
||||
8
src/main/java/eva2/cli/META-INF/MANIFEST.MF
Normal file
8
src/main/java/eva2/cli/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,8 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path: xml-apis-1.0.b2.jar gson-2.2.4.jar reflections-0.9.9-RC1.j
|
||||
ar jide-oss-2.4.8.jar jsr305-1.3.9.jar commons-math3-3.1.1.jar common
|
||||
s-cli-1.2.jar xmlgraphics-commons-1.3.1.jar javahelp-2.0.05.jar jchar
|
||||
t2d-3.3.2.jar commons-io-1.3.1.jar guava-11.0.2.jar commons-logging-1
|
||||
.0.4.jar javassist-3.16.1-GA.jar dom4j-1.6.1.jar
|
||||
Main-Class: eva2.cli.Main
|
||||
|
||||
297
src/main/java/eva2/cli/Main.java
Normal file
297
src/main/java/eva2/cli/Main.java
Normal file
@@ -0,0 +1,297 @@
|
||||
package eva2.cli;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.optimization.InterfaceOptimizationParameters;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.Processor;
|
||||
import eva2.optimization.individuals.IndividualInterface;
|
||||
import eva2.optimization.operator.terminators.InterfaceTerminator;
|
||||
import eva2.optimization.population.PopulationInterface;
|
||||
import eva2.optimization.population.Population;
|
||||
import eva2.optimization.statistics.*;
|
||||
import eva2.optimization.strategies.InterfaceOptimizer;
|
||||
import eva2.problems.InterfaceAdditionalPopulationInformer;
|
||||
import eva2.problems.InterfaceOptimizationProblem;
|
||||
import eva2.tools.ReflectPackage;
|
||||
import eva2.tools.StringTools;
|
||||
import eva2.util.annotation.Description;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0 || (args.length == 1 && args[0].equals("--help"))) {
|
||||
/* Show help for empty argument list or --help */
|
||||
printHelp();
|
||||
System.exit(-1);
|
||||
} else if (args.length == 1 && args[0].equals("--version")) {
|
||||
printVersion();
|
||||
System.exit(-1);
|
||||
} else if (args.length == 2 && args[0].equals("--help")) {
|
||||
/* Show help for specific class */
|
||||
String className = args[1];
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
printHelpFor(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.out.printf("No help available for %s.\n", className);
|
||||
}
|
||||
System.exit(-1);
|
||||
} else {
|
||||
executeArguments(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print current version number.
|
||||
*/
|
||||
private static void printVersion() {
|
||||
System.out.printf("EvA2 version \"%s\"\n", EvAInfo.getVersion());
|
||||
}
|
||||
|
||||
private static void printHelp() {
|
||||
System.out.println("Usage: java -cp EvA2.jar eva2.cli.Main [args...]\n");
|
||||
|
||||
printHelpFor(OptimizationParameters.class);
|
||||
printHelpFor(StatisticsParameters.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints formatted help output for a specific class.
|
||||
*
|
||||
* If the class is an interface or abstract class additional information
|
||||
* on assignable subclasses will be shown.
|
||||
*
|
||||
* @param clazz The class to show help for.
|
||||
*/
|
||||
private static void printHelpFor(Class<?> clazz) {
|
||||
System.out.println(clazz.getName() + "\n");
|
||||
if (clazz.isAnnotationPresent(Description.class)) {
|
||||
Description description = clazz.getAnnotation(Description.class);
|
||||
System.out.printf("%s\n\n", description.value());
|
||||
}
|
||||
|
||||
/**
|
||||
* In case we have an Abstract class or Interface show available
|
||||
* sub types.
|
||||
*/
|
||||
if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
|
||||
Class<?>[] subTypes = ReflectPackage.getAssignableClassesInPackage(clazz.getPackage().getName(), clazz, true, true);
|
||||
if (subTypes.length > 0) {
|
||||
System.out.printf("Available types for %s\n\n", clazz.getName());
|
||||
for (Class<?> type : subTypes) {
|
||||
if (Modifier.isAbstract(type.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
Description description = clazz.getAnnotation(Description.class);
|
||||
System.out.printf("\t\033[1m%s\033[0m (%s)\n", type.getName(), StringTools.cutClassName(type.getName()));
|
||||
if (description != null) {
|
||||
System.out.printf("\t\t%s", description.value());
|
||||
} else {
|
||||
System.out.println("\t\tNo description available.");
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available parameters for this class and list them with their
|
||||
* description.
|
||||
*/
|
||||
ParameterGenerator generator = new ParameterGenerator(clazz, false);
|
||||
generator.generate();
|
||||
Map<String, List<Parameter>> paramList = generator.getParameterList();
|
||||
|
||||
List<Parameter> parameters = paramList.get(clazz.getName());
|
||||
if (parameters.size() > 0) {
|
||||
System.out.println("Options:");
|
||||
|
||||
for (Parameter key : parameters) {
|
||||
Class<?> type = key.getType();
|
||||
String typeDefinition;
|
||||
if (type.isEnum()) {
|
||||
Enum[] enumConstants = (Enum[])type.getEnumConstants();
|
||||
typeDefinition = "{";
|
||||
for (int i = 0; i < enumConstants.length; i++) {
|
||||
typeDefinition += enumConstants[i].name();
|
||||
if (i != enumConstants.length - 1) {
|
||||
typeDefinition += ",";
|
||||
}
|
||||
}
|
||||
typeDefinition += "}";
|
||||
} else {
|
||||
typeDefinition = key.getType().getName();
|
||||
}
|
||||
System.out.printf("\t\033[1m--%s\033[0m \033[4m%s\033[0m\n", key.getName(), typeDefinition);
|
||||
System.out.printf("\t\t%s\n", key.getDescription());
|
||||
}
|
||||
}
|
||||
System.out.print("\n\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a set of command line arguments and tries to construct
|
||||
* OptimizationParameters and StatisticsParameters from it. It will use defaults if
|
||||
* not otherwise configured.
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
private static void executeArguments(String[] args) {
|
||||
InterfaceOptimizationParameters parameters = OptimizationBuilder.parseOptimizerArguments(args);
|
||||
InterfaceStatisticsParameters statisticsParameters = OptimizationBuilder.parseStatisticsArguments(args);
|
||||
|
||||
InterfaceTerminator terminator = parameters.getTerminator();
|
||||
InterfaceOptimizer optimizer = parameters.getOptimizer();
|
||||
InterfaceOptimizationProblem problem = parameters.getProblem();
|
||||
|
||||
LinkedHashMap<String, Object> optimizationLog = new LinkedHashMap<>();
|
||||
// Meta parameters
|
||||
optimizationLog.put("populationSize", parameters.getOptimizer().getPopulation().getTargetSize());
|
||||
optimizationLog.put("numberOfRuns", statisticsParameters.getMultiRuns());
|
||||
optimizationLog.put("seed", parameters.getRandomSeed());
|
||||
optimizationLog.put("problem", parameters.getProblem());
|
||||
|
||||
CommandLineStatistics yamlStatistics = new CommandLineStatistics(statisticsParameters);
|
||||
|
||||
/**
|
||||
* Runs optimization
|
||||
*/
|
||||
Processor optimizationProcessor = new Processor(yamlStatistics, parameters);
|
||||
optimizationProcessor.setSaveParams(false);
|
||||
optimizationProcessor.startOptimization();
|
||||
optimizationProcessor.runOptimizationOnce();
|
||||
|
||||
/**
|
||||
* Get run statistics
|
||||
*/
|
||||
optimizationLog.put("runs", yamlStatistics.getRuns());
|
||||
|
||||
/**
|
||||
* Yaml configuration
|
||||
*/
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setExplicitStart(true);
|
||||
options.setExplicitEnd(true);
|
||||
Yaml yaml = new Yaml();
|
||||
|
||||
System.out.println(yaml.dump(optimizationLog));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class CommandLineStatistics implements InterfaceStatistics {
|
||||
private InterfaceStatisticsParameters statisticsParameters;
|
||||
private List<LinkedHashMap<String, Object>> runs;
|
||||
private LinkedHashMap<String, Object> currentRun;
|
||||
private ArrayList<Map<String, Object>> currentGenerations;
|
||||
private InterfaceOptimizationParameters currentParameters;
|
||||
private int currentGeneration;
|
||||
|
||||
|
||||
public CommandLineStatistics(InterfaceStatisticsParameters statisticsParameters) {
|
||||
super();
|
||||
this.statisticsParameters = statisticsParameters;
|
||||
this.runs = new ArrayList<>(statisticsParameters.getMultiRuns());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startOptimizationPerformed(String infoString, int runNumber, InterfaceOptimizationParameters params, List<InterfaceAdditionalPopulationInformer> informerList) {
|
||||
this.currentRun = new LinkedHashMap<>();
|
||||
this.currentRun.put("name", infoString);
|
||||
this.currentRun.put("runNumber", runNumber + 1);
|
||||
this.currentGenerations = new ArrayList<>();
|
||||
this.currentGeneration = 0;
|
||||
this.currentParameters = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopOptimizationPerformed(boolean normal, String stopMessage) {
|
||||
this.currentRun.put("stopMessage", stopMessage);
|
||||
this.currentRun.put("totalFunctionCalls", this.currentParameters.getOptimizer().getPopulation().getFunctionCalls());
|
||||
// ToDo: Figure out a sane way to do this. Having multirun > 1 increases SnakeYAML memory consumption to beyond infinity
|
||||
//this.currentRun.put("generations", currentGenerations);
|
||||
Population pop = this.currentParameters.getOptimizer().getAllSolutions().getSolutions();
|
||||
this.currentRun.put("solution", pop.getBestEAIndividual().getDoublePosition().clone());
|
||||
this.currentRun.put("bestFitness", pop.getBestFitness().clone());
|
||||
this.currentRun.put("meanFitness", pop.getMeanFitness().clone());
|
||||
this.runs.add(currentRun);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDataListener(InterfaceStatisticsListener listener) {
|
||||
// We don't support that.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeDataListener(InterfaceStatisticsListener listener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTextListener(InterfaceTextListener listener) {
|
||||
// We don't support that.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeTextListener(InterfaceTextListener listener) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printToTextListener(String... s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNextGenerationPerformed(PopulationInterface pop, InterfaceOptimizer opt, List<InterfaceAdditionalPopulationInformer> informerList) {
|
||||
LinkedHashMap<String, Object> generation = new LinkedHashMap<>();
|
||||
generation.put("generation", currentGeneration);
|
||||
generation.put("bestFitness", pop.getBestFitness().clone());
|
||||
generation.put("meanFitness", pop.getMeanFitness().clone());
|
||||
generation.put("functionCalls", pop.getFunctionCalls());
|
||||
this.currentGenerations.add(generation);
|
||||
this.currentGeneration++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceStatisticsParameters getStatisticsParameters() {
|
||||
return statisticsParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndividualInterface getRunBestSolution() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndividualInterface getBestSolution() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getBestFitness() {
|
||||
return new double[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessingPerformed(Population resultPop) {
|
||||
|
||||
}
|
||||
|
||||
public List<LinkedHashMap<String, Object>> getRuns() {
|
||||
return this.runs;
|
||||
}
|
||||
}
|
||||
225
src/main/java/eva2/cli/OptimizationBuilder.java
Normal file
225
src/main/java/eva2/cli/OptimizationBuilder.java
Normal file
@@ -0,0 +1,225 @@
|
||||
package eva2.cli;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.optimization.InterfaceOptimizationParameters;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.statistics.InterfaceStatisticsParameters;
|
||||
import eva2.optimization.statistics.StatisticsParameters;
|
||||
import eva2.tools.ReflectPackage;
|
||||
import eva2.util.annotation.Hidden;
|
||||
import eva2.util.annotation.Parameter;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
class ArgumentTree extends LinkedHashMap<String, Object> {
|
||||
private Object value;
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ((value != null) ? value.toString() + ", " : "") + super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* If there are no key/value pairs present and the value is unset,
|
||||
* this tree belongs to a flag.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFlag() {
|
||||
return this.size() == 0 && this.value == null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final class OptimizationBuilder {
|
||||
private OptimizationBuilder() {}
|
||||
|
||||
public static InterfaceOptimizationParameters parseOptimizerArguments(String[] args) {
|
||||
ArgumentTree argumentTree = parseArguments(args);
|
||||
return constructFromArgumentTree(OptimizationParameters.class, argumentTree);
|
||||
}
|
||||
|
||||
public static InterfaceStatisticsParameters parseStatisticsArguments(String[] args) {
|
||||
ArgumentTree argumentTree = parseArguments(args);
|
||||
return constructFromArgumentTree(StatisticsParameters.class, argumentTree);
|
||||
}
|
||||
|
||||
private static ArgumentTree parseArguments(String[] args) {
|
||||
HashMap<String, String> argumentMap = new HashMap<>(args.length/2);
|
||||
int i = 0;
|
||||
while (i < args.length) {
|
||||
// Is it a parameter?
|
||||
if (args[i].startsWith("--")) {
|
||||
String key = args[i].substring(2);
|
||||
// Is the next a value?
|
||||
if (i < args.length - 1 && !args[i+1].startsWith("--")) {
|
||||
argumentMap.put(key, args[i + 1]);
|
||||
i += 2;
|
||||
} else {
|
||||
argumentMap.put(key, null);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArgumentTree argumentTree = new ArgumentTree();
|
||||
for (String key : argumentMap.keySet()) {
|
||||
insertIntoArgumentTree(argumentTree, key, argumentMap.get(key));
|
||||
}
|
||||
|
||||
return argumentTree;
|
||||
}
|
||||
|
||||
private static void insertIntoArgumentTree(ArgumentTree tree, String key, String value) {
|
||||
// Basic type?
|
||||
if (!key.contains("-")) {
|
||||
if (!tree.containsKey(key)) {
|
||||
tree.put(key, new ArgumentTree());
|
||||
}
|
||||
((ArgumentTree)tree.get(key)).setValue(value);
|
||||
} else {
|
||||
String baseKey = key.substring(0, key.indexOf('-'));
|
||||
String restKey = key.substring(key.indexOf('-') + 1);
|
||||
if (!tree.containsKey(baseKey)) {
|
||||
tree.put(baseKey, new ArgumentTree());
|
||||
}
|
||||
insertIntoArgumentTree((ArgumentTree)tree.get(baseKey), restKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param clazz
|
||||
* @param tree Tree containing key, value pairs
|
||||
*/
|
||||
private static <T> T constructFromArgumentTree(Class<T> clazz, ArgumentTree tree) {
|
||||
T instance = null;
|
||||
|
||||
// Create new instance
|
||||
if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
|
||||
// Find subclasses of clazz that match tree.getValue()
|
||||
} else {
|
||||
Class<?>[] params = new Class[0];
|
||||
try {
|
||||
Constructor constructor = clazz.getConstructor(params);
|
||||
instance = (T)constructor.newInstance();
|
||||
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to continue if there are no parameters to set */
|
||||
if (tree.isEmpty()) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
BeanInfo info;
|
||||
try {
|
||||
if (clazz.isInterface()) {
|
||||
info = Introspector.getBeanInfo(clazz);
|
||||
} else {
|
||||
info = Introspector.getBeanInfo(clazz, Object.class);
|
||||
}
|
||||
PropertyDescriptor[] properties = info.getPropertyDescriptors();
|
||||
int foundParameters = 0;
|
||||
for (PropertyDescriptor pd : properties) {
|
||||
String name = pd.getName();
|
||||
Method getter = pd.getReadMethod();
|
||||
Method setter = pd.getWriteMethod();
|
||||
Class<?> type = pd.getPropertyType();
|
||||
// We skip non-existing setters or setters that are hidden by annotation
|
||||
if (getter == null || setter == null || setter.isAnnotationPresent(Hidden.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We use the name of the descriptor or if possible
|
||||
// one that is given by the @Parameter annotation.
|
||||
if (setter.isAnnotationPresent(Parameter.class)) {
|
||||
Parameter param = setter.getAnnotation(Parameter.class);
|
||||
if (!param.name().isEmpty()) {
|
||||
name = param.name();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the tree contains this property we try to set it on the object.
|
||||
*/
|
||||
if (tree.containsKey(name)) {
|
||||
foundParameters++;
|
||||
Object obj = null;
|
||||
if (type.isPrimitive() && ((ArgumentTree)tree.get(name)).getValue() != null) {
|
||||
obj = BeanInspector.stringToPrimitive((String) ((ArgumentTree) tree.get(name)).getValue(), type);
|
||||
} else if (type.isArray() && ((ArgumentTree)tree.get(name)).getValue() != null) {
|
||||
// ToDo: Implement array parsing
|
||||
} else if (type.isEnum() && ((ArgumentTree)tree.get(name)).getValue() != null) {
|
||||
String enumName = (String)((ArgumentTree)tree.get(name)).getValue();
|
||||
obj = Enum.valueOf((Class<Enum>)type, enumName);
|
||||
} else {
|
||||
// The subtree has the name of the class
|
||||
String className = (String)((ArgumentTree)tree.get(name)).getValue();
|
||||
|
||||
Class subType;
|
||||
if (className != null) {
|
||||
// Try to get the actual class from its name
|
||||
if (className.endsWith("Problem")) {
|
||||
subType = getClassFromName("eva2.problems", className, type);
|
||||
} else {
|
||||
subType = getClassFromName("eva2.optimization", className, type);
|
||||
}
|
||||
} else {
|
||||
subType = type;
|
||||
}
|
||||
|
||||
// Here the recursion starts
|
||||
obj = constructFromArgumentTree(subType, (ArgumentTree) tree.get(name));
|
||||
}
|
||||
|
||||
// We preserve the default if obj is null
|
||||
if (obj != null) {
|
||||
BeanInspector.callIfAvailable(instance, setter.getName(), new Object[]{obj});
|
||||
}
|
||||
}
|
||||
|
||||
// If we configured all parameters in the tree we can break the loop
|
||||
if (tree.size() == foundParameters) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IntrospectionException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static Class<?> getClassFromName(String packageName, String name, Class type) {
|
||||
Class<?>[] classes = ReflectPackage.getAssignableClassesInPackage(packageName, type, true, true);
|
||||
for (Class clazz : classes) {
|
||||
// We allow both the fully qualified name (eva2.optimization.strategies.GeneticAlgorithm
|
||||
// and the simple name (GeneticAlgorithm)
|
||||
if (clazz.getName().equals(name) || clazz.getSimpleName().equals(name)) {
|
||||
return clazz;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
48
src/main/java/eva2/cli/OptimizationLogger.java
Normal file
48
src/main/java/eva2/cli/OptimizationLogger.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package eva2.cli;
|
||||
|
||||
import eva2.optimization.InterfaceOptimizationParameters;
|
||||
import eva2.optimization.OptimizationStateListener;
|
||||
import eva2.optimization.population.InterfacePopulationChangedEventListener;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class OptimizationLogger implements InterfacePopulationChangedEventListener, OptimizationStateListener {
|
||||
private final OutputStream outputStream;
|
||||
private final InterfaceOptimizationParameters optimizationParameters;
|
||||
private LinkedHashMap<String, Object> optimizationData;
|
||||
|
||||
public OptimizationLogger(InterfaceOptimizationParameters optimizationParameters, OutputStream outputStream) {
|
||||
this.optimizationParameters = optimizationParameters;
|
||||
this.outputStream = outputStream;
|
||||
this.optimizationData = new LinkedHashMap<>(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPopulationStateChanged(Object source, String name) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedStop() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedStart(String infoString) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedRestart(String infoString) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(int percent, String msg) {
|
||||
|
||||
}
|
||||
}
|
||||
165
src/main/java/eva2/cli/ParameterGenerator.java
Normal file
165
src/main/java/eva2/cli/ParameterGenerator.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package eva2.cli;
|
||||
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.tools.ReflectPackage;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Generates a human readable document with all command line parameters available
|
||||
* for EvA2.
|
||||
*/
|
||||
public class ParameterGenerator {
|
||||
private Class<?> clazz;
|
||||
private boolean recursive;
|
||||
|
||||
/**
|
||||
* Maps class name to a list of parameters
|
||||
*/
|
||||
private Map<String, List<Parameter>> parameterList;
|
||||
|
||||
public ParameterGenerator(Class<?> clazz) {
|
||||
this(clazz, true);
|
||||
}
|
||||
|
||||
public ParameterGenerator(Class<?> clazz, boolean recursive) {
|
||||
this.clazz = clazz;
|
||||
this.parameterList = new HashMap<>();
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Map<String, List<Parameter>> getParameterList() {
|
||||
return parameterList;
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
generateForClass(this.clazz);
|
||||
}
|
||||
|
||||
private void generateForClass(Class<?> clazz) {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
|
||||
this.parameterList.put(clazz.getName(), parameters);
|
||||
|
||||
BeanInfo info;
|
||||
try {
|
||||
if (clazz.isInterface()) {
|
||||
info = Introspector.getBeanInfo(clazz);
|
||||
} else {
|
||||
info = Introspector.getBeanInfo(clazz, Object.class);
|
||||
}
|
||||
|
||||
PropertyDescriptor[] properties = info.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : properties) {
|
||||
String name = pd.getName();
|
||||
Method getter = pd.getReadMethod();
|
||||
Method setter = pd.getWriteMethod();
|
||||
Class<?> type = pd.getPropertyType();
|
||||
|
||||
// Skip if setter is hidden or getter is not available
|
||||
if (setter == null || setter.isAnnotationPresent(eva2.util.annotation.Hidden.class) || getter == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Parameter parameter;
|
||||
if (setter.isAnnotationPresent(eva2.util.annotation.Parameter.class)) {
|
||||
eva2.util.annotation.Parameter param = setter.getAnnotation(eva2.util.annotation.Parameter.class);
|
||||
if (!param.name().isEmpty()) {
|
||||
name = param.name();
|
||||
}
|
||||
parameter = new Parameter(name, param.description(), type);
|
||||
} else {
|
||||
parameter = new Parameter(name, "No description available.", type);
|
||||
}
|
||||
|
||||
parameters.add(parameter);
|
||||
|
||||
if (type == Object.class || !recursive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<?>[] classes = ReflectPackage.getAssignableClassesInPackage("eva2", type, true, true);
|
||||
for (Class assignable : classes) {
|
||||
// Recurse if not in List
|
||||
if (!parameterList.containsKey(assignable.getName()) && assignable.getName().startsWith("eva2") && !assignable.getName().startsWith("eva2.gui")) {
|
||||
System.out.println(type.getName() + "\t->\t" + assignable.getName());
|
||||
generateForClass(assignable);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IntrospectionException ex) {
|
||||
// die
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ParameterGenerator generator = new ParameterGenerator(OptimizationParameters.class);
|
||||
generator.generate();
|
||||
int paramCount = 0;
|
||||
Map<String, List<Parameter>> paramList = generator.getParameterList();
|
||||
for(String key : paramList.keySet()) {
|
||||
paramCount += paramList.get(key).size();
|
||||
}
|
||||
System.out.println("Total Parameter Count: " + paramCount);
|
||||
System.out.println("Total Type Count: " + paramList.size());
|
||||
}
|
||||
}
|
||||
|
||||
class Type {
|
||||
private List<Parameter> parameters;
|
||||
private final String name;
|
||||
private final String description;
|
||||
|
||||
public Type(String name, String description) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.parameters = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<Parameter> getParameters() {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
}
|
||||
|
||||
class Parameter {
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final Class<?> type;
|
||||
|
||||
public Parameter(String name, String description, Class<?> type) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
4
src/main/java/eva2/cli/package-info.java
Normal file
4
src/main/java/eva2/cli/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Implementation of Command-line Interface for EvA2
|
||||
*/
|
||||
package eva2.cli;
|
||||
46
src/main/java/eva2/examples/TerminatorExample.java
Normal file
46
src/main/java/eva2/examples/TerminatorExample.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package eva2.examples;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.optimization.operator.terminators.CombinedTerminator;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.optimization.operator.terminators.FitnessConvergenceTerminator;
|
||||
import eva2.optimization.operator.terminators.PhenotypeConvergenceTerminator;
|
||||
import eva2.optimization.operator.terminators.PopulationMeasureTerminator.ChangeTypeEnum;
|
||||
import eva2.optimization.operator.terminators.PopulationMeasureTerminator.DirectionTypeEnum;
|
||||
import eva2.optimization.operator.terminators.PopulationMeasureTerminator.StagnationTypeEnum;
|
||||
import eva2.problems.F1Problem;
|
||||
|
||||
public class TerminatorExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
F1Problem f1 = new F1Problem();
|
||||
double[] sol;
|
||||
// A combined terminator for fitness and phenotype convergence
|
||||
CombinedTerminator convT = new CombinedTerminator(
|
||||
// fitness-based stagnation period, absolute threshold, consider stagnation
|
||||
// in both direction (per dim.) or w.r.t. minimization only
|
||||
new FitnessConvergenceTerminator(0.0001, 1000, StagnationTypeEnum.fitnessCallBased, ChangeTypeEnum.absoluteChange, DirectionTypeEnum.decrease),
|
||||
new PhenotypeConvergenceTerminator(0.0001, 1000, StagnationTypeEnum.fitnessCallBased, ChangeTypeEnum.absoluteChange, DirectionTypeEnum.bidirectional),
|
||||
true
|
||||
);
|
||||
|
||||
// Adding an evaluation terminator with OR to the convergence criterion
|
||||
OptimizerFactory.setTerminator(new CombinedTerminator(
|
||||
new EvaluationTerminator(20000),
|
||||
convT,
|
||||
false
|
||||
));
|
||||
|
||||
sol = OptimizerFactory.optimizeToDouble(OptimizerFactory.PSO, f1, null);
|
||||
|
||||
System.out.println(OptimizerFactory.lastEvalsPerformed()
|
||||
+ " evals performed. "
|
||||
+ OptimizerFactory.terminatedBecause()
|
||||
+ " Found solution: ");
|
||||
|
||||
for (int i = 0; i < f1.getProblemDimension(); i++) {
|
||||
System.out.print(sol[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
42
src/main/java/eva2/examples/TestingCbnPostProc.java
Normal file
42
src/main/java/eva2/examples/TestingCbnPostProc.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package eva2.examples;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.optimization.operator.postprocess.PostProcessParams;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.problems.FM0Problem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TestingCbnPostProc {
|
||||
public static void main(String[] args) {
|
||||
// a simple bimodal target function, two optima near (1.7,0) and (-1.44/0)
|
||||
FM0Problem fm0 = new FM0Problem();
|
||||
AbstractEAIndividual best;
|
||||
List<AbstractEAIndividual> ppSols;
|
||||
|
||||
OptimizationParameters esParams = OptimizerFactory.standardCbnES(fm0);
|
||||
esParams.setTerminator(new EvaluationTerminator(2000));
|
||||
esParams.setRandomSeed(0);
|
||||
best = (AbstractEAIndividual) OptimizerFactory.optimizeToInd(esParams, null);
|
||||
|
||||
System.out.println(esParams.getTerminator().lastTerminationMessage() + "\nFound solution: "
|
||||
+ AbstractEAIndividual.getDefaultDataString(best));
|
||||
|
||||
// post-process with clustering only
|
||||
ppSols = OptimizerFactory.postProcessIndVec(new PostProcessParams(0, 0.1, 5));
|
||||
System.out.println("After clustering: ");
|
||||
for (AbstractEAIndividual indy : ppSols) {
|
||||
System.out.println(AbstractEAIndividual.getDefaultDataString(indy));
|
||||
}
|
||||
|
||||
// post-process with clustering and hill climbing
|
||||
ppSols = OptimizerFactory.postProcessIndVec(new PostProcessParams(1000, 0.1, 5));
|
||||
System.out.println("After clustering and local refinement: ");
|
||||
for (AbstractEAIndividual indy : ppSols) {
|
||||
System.out.println(AbstractEAIndividual.getDefaultDataString(indy));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
19
src/main/java/eva2/examples/TestingF1PSO.java
Normal file
19
src/main/java/eva2/examples/TestingF1PSO.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package eva2.examples;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.problems.F1Problem;
|
||||
|
||||
public class TestingF1PSO {
|
||||
|
||||
public static void main(String[] args) {
|
||||
F1Problem f1 = new F1Problem();
|
||||
// start a PSO with a runtime of 50000 evaluations
|
||||
OptimizerFactory.setEvaluationTerminator(50000);
|
||||
double[] sol = OptimizerFactory.optimizeToDouble(OptimizerFactory.PSO, f1, null);
|
||||
System.out.println(OptimizerFactory.terminatedBecause() + "\nFound solution: ");
|
||||
for (int i = 0; i < f1.getProblemDimension(); i++) {
|
||||
System.out.print(sol[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
40
src/main/java/eva2/examples/TestingGAB1.java
Normal file
40
src/main/java/eva2/examples/TestingGAB1.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package eva2.examples;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.operator.selection.SelectXProbRouletteWheel;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.optimization.population.Population;
|
||||
import eva2.optimization.strategies.GeneticAlgorithm;
|
||||
import eva2.problems.B1Problem;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
public class TestingGAB1 {
|
||||
public static void main(String[] args) {
|
||||
B1Problem b1 = new B1Problem();
|
||||
BitSet sol;
|
||||
// default go-parameter instance with a GA
|
||||
OptimizationParameters gaParams = OptimizerFactory.standardGA(b1);
|
||||
// add an evaluation terminator
|
||||
gaParams.setTerminator(new EvaluationTerminator(1000));
|
||||
// set a specific random seed
|
||||
gaParams.setRandomSeed(2342);
|
||||
|
||||
// access the GA
|
||||
GeneticAlgorithm ga = (GeneticAlgorithm) gaParams.getOptimizer();
|
||||
ga.setElitism(false);
|
||||
ga.setParentSelection(new SelectXProbRouletteWheel()); // roulette wheel selection
|
||||
ga.setPopulation(new Population(150)); // population size 150
|
||||
|
||||
// run optimization and print intermediate results to a file with given prefix
|
||||
sol = OptimizerFactory.optimizeToBinary(gaParams, "ga-opt-results");
|
||||
System.out.println(OptimizerFactory.terminatedBecause() + "\nFound solution: ");
|
||||
for (int i = 0; i < b1.getProblemDimension(); i++) {
|
||||
System.out.print(sol.get(i) + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
43
src/main/java/eva2/examples/TestingPlusCmaEs.java
Normal file
43
src/main/java/eva2/examples/TestingPlusCmaEs.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package eva2.examples;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.optimization.operator.crossover.CrossoverESDefault;
|
||||
import eva2.optimization.operator.mutation.MutateESCovarianceMatrixAdaption;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.optimization.strategies.EvolutionStrategies;
|
||||
import eva2.problems.FM0Problem;
|
||||
|
||||
public class TestingPlusCmaEs {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// a simple bimodal target function, two optima near (1.7,0) and (-1.44/0)
|
||||
FM0Problem fm0 = new FM0Problem();
|
||||
AbstractEAIndividual bestIndy;
|
||||
// create standard ES parameters
|
||||
OptimizationParameters esParams = OptimizerFactory.standardES(fm0);
|
||||
esParams.setTerminator(new EvaluationTerminator(2000));
|
||||
// set a random seed based on system time
|
||||
esParams.setRandomSeed(0);
|
||||
|
||||
// set evolutionary operators and probabilities
|
||||
AbstractEAIndividual.setOperators(
|
||||
fm0.getIndividualTemplate(),
|
||||
new MutateESCovarianceMatrixAdaption(true), 0.9,
|
||||
new CrossoverESDefault(), 0.1);
|
||||
|
||||
// access the ES
|
||||
EvolutionStrategies es = (EvolutionStrategies) esParams.getOptimizer();
|
||||
// set a (1+5) selection strategy
|
||||
es.setMu(1);
|
||||
es.setLambda(5);
|
||||
es.setPlusStrategy(true);
|
||||
|
||||
// run optimization and retrieve winner individual
|
||||
bestIndy = (AbstractEAIndividual) OptimizerFactory.optimizeToInd(esParams, null);
|
||||
System.out.println(esParams.getTerminator().lastTerminationMessage() + "\nFound solution: "
|
||||
+ AbstractEAIndividual.getDefaultDataString(bestIndy));
|
||||
}
|
||||
|
||||
}
|
||||
4
src/main/java/eva2/examples/package-info.java
Normal file
4
src/main/java/eva2/examples/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Contains example implementations for custom Terminators and Optimizations.
|
||||
*/
|
||||
package eva2.examples;
|
||||
104
src/main/java/eva2/gui/AboutDialog.java
Normal file
104
src/main/java/eva2/gui/AboutDialog.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* The About dialog used in the EvA2 GUI.
|
||||
*/
|
||||
class AboutDialog extends JDialog {
|
||||
private JLabel imageLabel;
|
||||
private JEditorPane infoEditorPane;
|
||||
private JTextArea aboutTextArea;
|
||||
|
||||
public AboutDialog(Frame parent) {
|
||||
super(parent);
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
setTitle("About");
|
||||
setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
|
||||
setSize(new Dimension(470, 600));
|
||||
setResizable(false);
|
||||
|
||||
/* Load EvA2 Image */
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(eva2.EvAInfo.splashLocation, true);
|
||||
ImageIcon imageIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(bytes));
|
||||
|
||||
/* Create a new JLabel with the image */
|
||||
imageLabel = new JLabel(imageIcon);
|
||||
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
gbConstraints.ipady = 10;
|
||||
gbConstraints.insets = new Insets(10, 10, 0, 10);
|
||||
gbConstraints.anchor = GridBagConstraints.PAGE_START;
|
||||
add(imageLabel, gbConstraints);
|
||||
|
||||
String infoMessage = "<html><head></head><body>"
|
||||
+ "<p>EvA2 (an Evolutionary Algorithms framework, revised version 2) is a comprehensive heuristic optimization framework with emphasis on Evolutionary Algorithms implemented in Java™.</p>"
|
||||
+ "<p>For more information, please visit the <a href=\"http://www.cogsys.cs.uni-tuebingen.de/software/JavaEvA/\">EvA2 Homepage</a>.</p>"
|
||||
+ "</body></html>";
|
||||
|
||||
infoEditorPane = new JEditorPane("text/html", infoMessage);
|
||||
infoEditorPane.setEditable(false);
|
||||
infoEditorPane.setOpaque(false);
|
||||
infoEditorPane.addHyperlinkListener(new HyperlinkListener() {
|
||||
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent hle) {
|
||||
if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
|
||||
java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
|
||||
|
||||
if (desktop.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
//java.net.URI uri = new java.net.URI(hle.getURL().toString());
|
||||
//desktop.browse(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
gbConstraints.gridy++;
|
||||
gbConstraints.anchor = GridBagConstraints.CENTER;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.weightx = 1.0;
|
||||
add(infoEditorPane, gbConstraints);
|
||||
|
||||
aboutTextArea = new JTextArea();
|
||||
aboutTextArea.setEditable(false);
|
||||
aboutTextArea.setRows(8);
|
||||
|
||||
gbConstraints.gridy++;
|
||||
gbConstraints.weighty = 1.0;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
add(new JScrollPane(aboutTextArea), gbConstraints);
|
||||
|
||||
JButton closeButton = new JButton("Close");
|
||||
closeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
AboutDialog.this.dispose();
|
||||
}
|
||||
|
||||
});
|
||||
gbConstraints.gridy++;
|
||||
gbConstraints.fill = GridBagConstraints.NONE;
|
||||
gbConstraints.weighty = 0.0;
|
||||
gbConstraints.insets = new Insets(10, 10, 10, 10);
|
||||
add(closeButton, gbConstraints);
|
||||
}
|
||||
}
|
||||
1041
src/main/java/eva2/gui/BeanInspector.java
Normal file
1041
src/main/java/eva2/gui/BeanInspector.java
Normal file
File diff suppressed because it is too large
Load Diff
80
src/main/java/eva2/gui/CPUPanel.java
Normal file
80
src/main/java/eva2/gui/CPUPanel.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package eva2.gui;
|
||||
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Small Panel that shows the current OS and Process CPU usage.
|
||||
*
|
||||
* Sliding window with n time steps, where each time step has a
|
||||
* resolution of 500ms.
|
||||
*/
|
||||
public class CPUPanel extends JPanel {
|
||||
private LinkedList<Double> processLoadList = new LinkedList<>();
|
||||
private LinkedList<Double> osLoadList = new LinkedList<>();
|
||||
private int maxTimeSteps = 100;
|
||||
private OperatingSystemMXBean osBean;
|
||||
|
||||
public CPUPanel(int timeSteps) {
|
||||
Timer timer = new Timer(500, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CPUPanel.this.updateLoad();
|
||||
CPUPanel.this.repaint();
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
maxTimeSteps = timeSteps;
|
||||
setMinimumSize(new Dimension(timeSteps, 1));
|
||||
setPreferredSize(new Dimension(timeSteps, 1));
|
||||
osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
|
||||
|
||||
}
|
||||
|
||||
private void updateLoad() {
|
||||
// What % CPU load this current JVM is taking, from 0.0-1.0
|
||||
processLoadList.add(osBean.getProcessCpuLoad());
|
||||
|
||||
// What % load the overall system is at, from 0.0-1.0
|
||||
osLoadList.add(osBean.getSystemCpuLoad());
|
||||
|
||||
if (processLoadList.size() > maxTimeSteps) {
|
||||
processLoadList.removeFirst();
|
||||
}
|
||||
|
||||
if (osLoadList.size() > maxTimeSteps) {
|
||||
osLoadList.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
Dimension panelSize = this.getSize();
|
||||
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
g2d.setColor(Color.LIGHT_GRAY);
|
||||
int pos = maxTimeSteps - osLoadList.size();
|
||||
for(Double load : osLoadList) {
|
||||
g2d.drawLine(pos, panelSize.height - 1, pos, (int)(panelSize.height - 1 - (panelSize.height * load)));
|
||||
pos++;
|
||||
}
|
||||
|
||||
g2d.setColor(Color.GREEN);
|
||||
pos = maxTimeSteps - processLoadList.size();
|
||||
for(Double load : processLoadList) {
|
||||
g2d.drawLine(pos, panelSize.height - 1, pos, (int)(panelSize.height - 1 - (panelSize.height * load)));
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/main/java/eva2/gui/ExtAction.java
Normal file
75
src/main/java/eva2/gui/ExtAction.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2003
|
||||
* Company: University of Tuebingen, Computer Architecture
|
||||
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
||||
* @version: $Revision: 10 $
|
||||
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
|
||||
* $Author: streiche $
|
||||
*/
|
||||
/*==========================================================================*
|
||||
* IMPORTS
|
||||
*==========================================================================*/
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class ExtAction extends AbstractAction {
|
||||
public final static String CAPTION = "Caption";
|
||||
public final static String MNEMONIC = "Mnemonic";
|
||||
public final static String TOOLTIP = "ToolTip";
|
||||
public final static String KEYSTROKE = "KeyStroke";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void setValues(String s, String toolTip) {
|
||||
Mnemonic m = new Mnemonic(s);
|
||||
putValue(MNEMONIC, new Character(m.getMnemonic()));
|
||||
putValue(Action.NAME, m.getText());
|
||||
putValue(TOOLTIP, toolTip);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ExtAction(String s, Icon i, String toolTip, KeyStroke key) {
|
||||
this(s, i, toolTip);
|
||||
if (i == null) {
|
||||
System.out.println("Icon == null");
|
||||
}
|
||||
putValue(KEYSTROKE, key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ExtAction(String s, Icon i, String toolTip) {
|
||||
super(null, i);
|
||||
if (i == null) {
|
||||
System.out.println("Icon == null");
|
||||
}
|
||||
setValues(s, toolTip);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ExtAction(String s, String toolTip, KeyStroke key) {
|
||||
this(s, toolTip);
|
||||
putValue(KEYSTROKE, key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ExtAction(String s, String toolTip) {
|
||||
super();
|
||||
setValues(s, toolTip);
|
||||
}
|
||||
}
|
||||
|
||||
46
src/main/java/eva2/gui/ExtActionChangedListener.java
Normal file
46
src/main/java/eva2/gui/ExtActionChangedListener.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2003
|
||||
* Company: University of Tuebingen, Computer Architecture
|
||||
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
||||
* @version: $Revision: 10 $
|
||||
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
|
||||
* $Author: streiche $
|
||||
*/
|
||||
/*==========================================================================*
|
||||
* IMPORTS
|
||||
*==========================================================================*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class ExtActionChangedListener implements PropertyChangeListener {
|
||||
protected JComponent component;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ExtActionChangedListener(JComponent c) {
|
||||
super();
|
||||
setTarget(c);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public abstract void propertyChange(PropertyChangeEvent e);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setTarget(JComponent c) {
|
||||
component = c;
|
||||
}
|
||||
}
|
||||
78
src/main/java/eva2/gui/ExtDesktopManager.java
Normal file
78
src/main/java/eva2/gui/ExtDesktopManager.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ExtDesktopManager extends DefaultDesktopManager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ExtDesktopManager.class.getName());
|
||||
|
||||
int WINDOW_LIST_START;
|
||||
public final static String INDEX = "Index";
|
||||
public final static String FRAME = "Frame";
|
||||
private JInternalFrame activeFrame = null;
|
||||
private JExtDesktopPane desktop;
|
||||
|
||||
public ExtDesktopManager(JExtDesktopPane desktop) {
|
||||
this.desktop = desktop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateFrame(JInternalFrame f) {
|
||||
super.activateFrame(f);
|
||||
activeFrame = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateFrame(JInternalFrame f) {
|
||||
super.deactivateFrame(f);
|
||||
if (activeFrame == f) {
|
||||
activeFrame = null;
|
||||
}
|
||||
}
|
||||
|
||||
public JInternalFrame getActiveFrame() {
|
||||
return activeFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeFrame(JInternalFrame internalFrame) {
|
||||
LOGGER.log(Level.FINE, "Closing Internal Frame: {0}", internalFrame.getTitle());
|
||||
super.closeFrame(internalFrame);
|
||||
int index = (Integer) internalFrame.getClientProperty(INDEX) + WINDOW_LIST_START - 1;
|
||||
int i;
|
||||
desktop.getWindowMenu().remove(index);
|
||||
for (i = index; i < Math.min(WINDOW_LIST_START + 9, desktop.getWindowMenu().getItemCount()); i++) {
|
||||
JMenuItem m = desktop.getWindowMenu().getItem(i);
|
||||
JInternalFrame frame = (JInternalFrame) m.getClientProperty(FRAME);
|
||||
frame.putClientProperty(INDEX, (Integer) frame.getClientProperty(INDEX) - 1);
|
||||
int winIndex = i - WINDOW_LIST_START + 1;
|
||||
m.setText((winIndex) + " " + frame.getTitle());
|
||||
m.setMnemonic((char) (0x30 + winIndex));
|
||||
m.setAccelerator(KeyStroke.getKeyStroke(0x30 + winIndex, InputEvent.ALT_MASK));
|
||||
}
|
||||
|
||||
if (internalFrame.isSelected()) {
|
||||
Component tmp = null;
|
||||
boolean found = false;
|
||||
for (i = 0; i < desktop.getComponentCount() && !found; i++) {
|
||||
tmp = desktop.getComponent(i);
|
||||
if (tmp instanceof JInternalFrame) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
desktop.selectFrame((JInternalFrame) tmp);
|
||||
} else {
|
||||
activeFrame = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
src/main/java/eva2/gui/HtmlDemo.java
Normal file
114
src/main/java/eva2/gui/HtmlDemo.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.text.html.HTMLDocument;
|
||||
import javax.swing.text.html.HTMLFrameHyperlinkEvent;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class HtmlDemo {
|
||||
private JEditorPane htmlEditorPane;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public HtmlDemo(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JEditorPane getPane() {
|
||||
return htmlEditorPane;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
HtmlDemo demo = new HtmlDemo("ES.html");
|
||||
demo.show();
|
||||
}
|
||||
|
||||
public boolean resourceExists() {
|
||||
URL url = ClassLoader.getSystemResource("html/" + name);
|
||||
return (url != null);
|
||||
}
|
||||
|
||||
public static boolean resourceExists(String mname) {
|
||||
URL url = ClassLoader.getSystemResource("html/" + mname);
|
||||
return (url != null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void show() {
|
||||
try {
|
||||
URL url = ClassLoader.getSystemResource("html/" + name);
|
||||
|
||||
try {
|
||||
htmlEditorPane = new JEditorPane(url);
|
||||
} catch (java.io.IOException ioe) {
|
||||
url = ClassLoader.getSystemResource("html/Default.html");
|
||||
htmlEditorPane = new JEditorPane(url);
|
||||
}
|
||||
htmlEditorPane.setEditable(false);
|
||||
htmlEditorPane.addHyperlinkListener(createHyperLinkListener());
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
System.out.println("Malformed URL: " + e);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
System.out.println("IOException: " + e);
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
JFrame frame = new JFrame(name);
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(EvAInfo.iconLocation, true);
|
||||
frame.setIconImage(Toolkit.getDefaultToolkit().createImage(bytes));
|
||||
JScrollPane scroller = new JScrollPane();
|
||||
JViewport vp = scroller.getViewport();
|
||||
vp.add(htmlEditorPane);
|
||||
scroller.setPreferredSize(new Dimension(600, 500));
|
||||
frame.getContentPane().add(scroller, BorderLayout.CENTER);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public HyperlinkListener createHyperLinkListener() {
|
||||
return new HyperlinkListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
if (e instanceof HTMLFrameHyperlinkEvent) {
|
||||
((HTMLDocument) htmlEditorPane.getDocument()).processHTMLFrameHyperlinkEvent(
|
||||
(HTMLFrameHyperlinkEvent) e);
|
||||
} else {
|
||||
try {
|
||||
htmlEditorPane.setPage(e.getURL());
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("IOE: " + ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
45
src/main/java/eva2/gui/InterfaceSelectablePointIcon.java
Normal file
45
src/main/java/eva2/gui/InterfaceSelectablePointIcon.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.optimization.mocco.paretofrontviewer.InterfaceRefSolutionListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface InterfaceSelectablePointIcon {
|
||||
|
||||
/**
|
||||
* This method allows to add a selection listner to the PointIcon
|
||||
* it should need more than one listener to this abstruse event
|
||||
*
|
||||
* @param a The selection listener
|
||||
*/
|
||||
void addSelectionListener(InterfaceRefSolutionListener a);
|
||||
|
||||
/**
|
||||
* This method allows to remove the selection listner to the PointIcon
|
||||
*/
|
||||
void removeSelectionListeners();
|
||||
|
||||
/**
|
||||
* This method returns the selection listner to the PointIcon
|
||||
*
|
||||
* @return InterfacePointIconSelectionListener
|
||||
*/
|
||||
InterfaceRefSolutionListener getSelectionListener();
|
||||
|
||||
/**
|
||||
* Of course the PointIcon needs a reference to the individual
|
||||
* otherwise it can't tell the listener what has been selected.
|
||||
*
|
||||
* @param indy
|
||||
*/
|
||||
void setEAIndividual(AbstractEAIndividual indy);
|
||||
|
||||
/**
|
||||
* This method allows you to get the EAIndividual the icon stands for
|
||||
*
|
||||
* @return AbstractEAIndividual
|
||||
*/
|
||||
AbstractEAIndividual getEAIndividual();
|
||||
}
|
||||
10
src/main/java/eva2/gui/InterfaceStandaloneOptimization.java
Normal file
10
src/main/java/eva2/gui/InterfaceStandaloneOptimization.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface InterfaceStandaloneOptimization {
|
||||
void startExperiment();
|
||||
|
||||
void setShow(boolean t);
|
||||
}
|
||||
98
src/main/java/eva2/gui/JDocFrame.java
Normal file
98
src/main/java/eva2/gui/JDocFrame.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class JDocFrame extends JInternalFrame {
|
||||
private File file;
|
||||
private String titleStr;
|
||||
protected boolean changed = false;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JDocFrame(String title) {
|
||||
super(title, true, true /* not closable*/, true, true);
|
||||
titleStr = title;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JDocFrame(File file) {
|
||||
this(file.getName());
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getFileTitle() {
|
||||
return titleStr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void save() {
|
||||
if (file != null) {
|
||||
save(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void save(File f) {
|
||||
if (!f.equals(file)) {
|
||||
file = f;
|
||||
titleStr = f.getName();
|
||||
}
|
||||
setChangedImpl(false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void setChangedImpl(boolean value) {
|
||||
changed = value;
|
||||
if (changed) {
|
||||
setTitle(titleStr + " *");
|
||||
} else {
|
||||
setTitle(titleStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void setChanged(boolean value) {
|
||||
if (changed != value) {
|
||||
setChangedImpl(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public abstract String[] getActionGroups();
|
||||
|
||||
public abstract JMenu getMenu(String group);
|
||||
|
||||
public abstract JToolBar getToolBar(String group);
|
||||
}
|
||||
|
||||
115
src/main/java/eva2/gui/JEFrame.java
Normal file
115
src/main/java/eva2/gui/JEFrame.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.InternalFrameAdapter;
|
||||
import javax.swing.event.InternalFrameEvent;
|
||||
import javax.swing.event.InternalFrameListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class JEFrame extends JInternalFrame {
|
||||
private boolean closeAllOnClose = false;
|
||||
|
||||
public JEFrame() {
|
||||
super();
|
||||
init();
|
||||
}
|
||||
|
||||
public JEFrame(String name) {
|
||||
super(name);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if all registered JEFrames should be closed if this frame is closed.
|
||||
*
|
||||
* @param c
|
||||
*/
|
||||
public void setCloseAllOnClosed(boolean c) {
|
||||
closeAllOnClose = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInternalFrameListener(InternalFrameListener l) {
|
||||
super.addInternalFrameListener(l);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
|
||||
this.addInternalFrameListener(new InternalFrameAdapter() {
|
||||
|
||||
@Override
|
||||
public void internalFrameClosed(InternalFrameEvent e) {
|
||||
super.internalFrameClosed(e);
|
||||
JEFrameRegister.getInstance().unregister((JEFrame) e.getInternalFrame());
|
||||
if (closeAllOnClose) {
|
||||
JEFrameRegister.getInstance().closeAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameOpened(InternalFrameEvent e) {
|
||||
super.internalFrameOpened(e);
|
||||
JEFrameRegister.getInstance().register((JEFrame) e.getInternalFrame());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameActivated(InternalFrameEvent e) {
|
||||
JEFrameRegister.getInstance().register((JEFrame) e.getInternalFrame());
|
||||
super.internalFrameActivated(e);
|
||||
}
|
||||
});
|
||||
this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK),
|
||||
"ctrlFpressed"
|
||||
);
|
||||
this.getRootPane().getActionMap().put(
|
||||
"ctrlFpressed",
|
||||
new AbstractAction("ctrlFpressed") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
JEFrameRegister.getInstance().getFrameList().get(0).toFront();
|
||||
}
|
||||
}
|
||||
);
|
||||
this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK),
|
||||
"ctrlOpressed"
|
||||
);
|
||||
this.getRootPane().getActionMap().put(
|
||||
"ctrlOpressed",
|
||||
new AbstractAction("ctrlOpressed") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
java.util.List<JEFrame> frameList = JEFrameRegister.getInstance().getFrameList();
|
||||
for (JEFrame frame : frameList) {
|
||||
frame.toFront();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_LESS, InputEvent.CTRL_MASK),
|
||||
"ctrlSmallerpressed"
|
||||
);
|
||||
final JEFrame self = this;
|
||||
this.getRootPane().getActionMap().put(
|
||||
"ctrlSmallerpressed",
|
||||
new AbstractAction("ctrlSmallerpressed") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
JEFrameRegister.getInstance().setFocusToNext(self);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
this.setMaximizable(true);
|
||||
this.setResizable(true);
|
||||
this.setIconifiable(false);
|
||||
this.setClosable(true);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
120
src/main/java/eva2/gui/JEFrameRegister.java
Normal file
120
src/main/java/eva2/gui/JEFrameRegister.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
public final class JEFrameRegister {
|
||||
/**
|
||||
* Singleton instance.
|
||||
*/
|
||||
private static JEFrameRegister instance = null;
|
||||
|
||||
/**
|
||||
* List of all frames maintained.
|
||||
*/
|
||||
private List<JEFrame> frameList;
|
||||
|
||||
private JDesktopPane desktopPane;
|
||||
|
||||
private JEFrameRegister() {
|
||||
this.frameList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static JEFrameRegister getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new JEFrameRegister();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setDesktopPane(JDesktopPane desktopPane) {
|
||||
this.desktopPane = desktopPane;
|
||||
if (!frameList.isEmpty()) {
|
||||
for (JEFrame frame : frameList) {
|
||||
this.desktopPane.add(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void register(JEFrame jeFrame) {
|
||||
if (!frameList.contains(jeFrame)) {
|
||||
frameList.add(jeFrame);
|
||||
|
||||
if (desktopPane != null) {
|
||||
desktopPane.add(jeFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister(JEFrame jeFrame) {
|
||||
// Plot windows produce double closing events, so ignore it
|
||||
frameList.remove(jeFrame);
|
||||
}
|
||||
|
||||
public List<JEFrame> getFrameList() {
|
||||
return frameList;
|
||||
}
|
||||
|
||||
public void setFocusToNext(JEFrame jeFrame) {
|
||||
int idx = frameList.indexOf(jeFrame);
|
||||
idx = (idx + 1) % frameList.size();
|
||||
JEFrame toset = frameList.get(idx);
|
||||
toset.toFront();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all prefixes which occur at least twice in the registered frame list.
|
||||
*
|
||||
* @param prefLen Preferred length of prefixes
|
||||
* @return List of prefixes
|
||||
*/
|
||||
public String[] getCommonPrefixes(final int prefLen) {
|
||||
List<String> prefixes = new ArrayList<>();
|
||||
List<Integer> count = new ArrayList<>();
|
||||
for (int i = 0; i < frameList.size(); i++) {
|
||||
String title = frameList.get(i).getTitle();
|
||||
String titPref = title.substring(0, Math.min(prefLen, title.length()));
|
||||
int earlierIndex = prefixes.indexOf(titPref);
|
||||
if (earlierIndex < 0) {
|
||||
prefixes.add(titPref);
|
||||
count.add(1);
|
||||
} else {
|
||||
count.set(earlierIndex, 1 + count.get(earlierIndex));
|
||||
}
|
||||
}
|
||||
for (int i = prefixes.size() - 1; i >= 0; i--) {
|
||||
if (count.get(i) <= 1) {
|
||||
prefixes.remove(i);
|
||||
count.remove(i);
|
||||
}
|
||||
}
|
||||
return prefixes.toArray(new String[prefixes.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close (dispose) all frames whose title starts with a given prefix.
|
||||
*
|
||||
* @param prefix The prefix
|
||||
*/
|
||||
public void closeAllByPrefix(final String prefix) {
|
||||
for (int i = 0; i < frameList.size(); i++) {
|
||||
String title = frameList.get(i).getTitle();
|
||||
if (title.startsWith(prefix)) {
|
||||
frameList.get(i).dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close (dispose) all frames registered in this list.
|
||||
*/
|
||||
public void closeAll() {
|
||||
for (int i = 0; i < frameList.size(); i++) {
|
||||
frameList.get(i).dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
264
src/main/java/eva2/gui/JExtDesktopPane.java
Normal file
264
src/main/java/eva2/gui/JExtDesktopPane.java
Normal file
@@ -0,0 +1,264 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.gui.editor.ComponentFilter;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JExtDesktopPane extends JDesktopPane {
|
||||
|
||||
private ActionListener actMenuFrame;
|
||||
private ExtDesktopManager desktopManager;
|
||||
private JExtMenu windowMenu;
|
||||
private ExtAction actWindowTileVert;
|
||||
private ExtAction actWindowTileHorz;
|
||||
private ExtAction actWindowOverlap;
|
||||
public final static int WINDOW_TILEVERT = 0;
|
||||
public final static int WINDOW_TILEHORZ = 1;
|
||||
public final static int WINDOW_OVERLAP = 2;
|
||||
public final static int WINDOW_ARRANGEICONS = 3;
|
||||
public final static int WINDOW_LIST = 4;
|
||||
public final static int TITLEBAR_HEIGHT = 25;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JExtDesktopPane() {
|
||||
super();
|
||||
|
||||
windowMenu = new JExtMenu("&Windows");
|
||||
desktopManager = new ExtDesktopManager(this);
|
||||
setDesktopManager(desktopManager);
|
||||
|
||||
actMenuFrame = new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
if (!(event.getSource() instanceof JMenuItem)) {
|
||||
return;
|
||||
}
|
||||
JInternalFrame frame = (JInternalFrame) ((JMenuItem) event.getSource()).getClientProperty(ExtDesktopManager.FRAME);
|
||||
selectFrame(frame);
|
||||
}
|
||||
};
|
||||
|
||||
actWindowTileVert = new ExtAction("Tile &Vertically", "Tiles all windows vertically",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, InputEvent.CTRL_MASK)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
tileWindows(SwingConstants.HORIZONTAL);
|
||||
}
|
||||
};
|
||||
windowMenu.add(actWindowTileVert);
|
||||
|
||||
actWindowTileHorz = new ExtAction("Tile &Horizontally", "Tiles all windows horizontically",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, InputEvent.CTRL_MASK)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
tileWindows(SwingConstants.VERTICAL);
|
||||
}
|
||||
};
|
||||
windowMenu.add(actWindowTileHorz);
|
||||
|
||||
actWindowOverlap = new ExtAction("&Cascade Windows", "Cascades all visible windows",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.CTRL_MASK)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
overlapWindows();
|
||||
}
|
||||
};
|
||||
windowMenu.add(actWindowOverlap);
|
||||
|
||||
windowMenu.addSeparator();
|
||||
desktopManager.WINDOW_LIST_START = 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to access the window actions.
|
||||
*
|
||||
* @param action The desired action (use JExtDesktopPane constants). Default is null
|
||||
* @return The ExtAction
|
||||
* @deprecated
|
||||
*/
|
||||
public ExtAction getWindowAction(int action) {
|
||||
switch (action) {
|
||||
case WINDOW_TILEVERT:
|
||||
return actWindowTileVert;
|
||||
case WINDOW_TILEHORZ:
|
||||
return actWindowTileHorz;
|
||||
case WINDOW_OVERLAP:
|
||||
return actWindowOverlap;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void overlapWindows() {
|
||||
final int minWidth = 150, minHeight = 100;
|
||||
int fWidth, fHeight,
|
||||
oCount, i, indent;
|
||||
|
||||
JInternalFrame[] frames = getOpenFrames();
|
||||
if (frames.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
oCount = Math.min(frames.length, Math.min((getWidth() - minWidth) / TITLEBAR_HEIGHT + 1, (getHeight() - minHeight) / TITLEBAR_HEIGHT + 1));
|
||||
fWidth = getWidth() - (oCount - 1) * TITLEBAR_HEIGHT;
|
||||
fHeight = getHeight() - (oCount - 1) * TITLEBAR_HEIGHT;
|
||||
|
||||
indent = 0;
|
||||
for (i = 0; i < frames.length; i++) {
|
||||
frames[frames.length - i - 1].setLocation(indent * TITLEBAR_HEIGHT, indent * TITLEBAR_HEIGHT);
|
||||
frames[frames.length - i - 1].setSize(fWidth, fHeight);
|
||||
indent = (i + 1) % oCount == 0 ? 0 : indent + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void tileWindows(int orientation) {
|
||||
int rows, cols,
|
||||
rHeight, cWidth,
|
||||
row, col,
|
||||
i;
|
||||
|
||||
JInternalFrame[] frames = getOpenFrames();
|
||||
if (frames.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (orientation == SwingConstants.HORIZONTAL) {
|
||||
rows = (int) (Math.rint(Math.sqrt(frames.length) - 0.49));
|
||||
cols = frames.length / rows;
|
||||
rHeight = getHeight() / rows;
|
||||
cWidth = getWidth() / cols;
|
||||
row = col = 0;
|
||||
for (i = 0; i < frames.length; i++) {
|
||||
frames[i].setLocation(col * cWidth, row * rHeight);
|
||||
frames[i].setSize(cWidth, rHeight);
|
||||
if (col == cols - 1) {
|
||||
row++;
|
||||
col = 0;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
if (row > 0 && frames.length - i - (cols + 1) * (rows - row) > 0) {
|
||||
cols++;
|
||||
cWidth = getWidth() / cols;
|
||||
}
|
||||
}
|
||||
} else if (orientation == SwingConstants.VERTICAL) {
|
||||
cols = (int) (Math.rint(Math.sqrt(frames.length) - 0.49));
|
||||
rows = frames.length / cols;
|
||||
cWidth = getWidth() / cols;
|
||||
rHeight = getHeight() / rows;
|
||||
col = row = 0;
|
||||
for (i = 0; i < frames.length; i++) {
|
||||
frames[i].setLocation(col * cWidth, row * rHeight);
|
||||
frames[i].setSize(cWidth, rHeight);
|
||||
if (row == rows - 1) {
|
||||
col++;
|
||||
row = 0;
|
||||
} else {
|
||||
row++;
|
||||
}
|
||||
if (col > 0 && frames.length - i - (rows + 1) * (cols - col) > 0) {
|
||||
rows++;
|
||||
rHeight = getHeight() / rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JInternalFrame[] getOpenFrames() {
|
||||
JInternalFrame[] result;
|
||||
Vector vResults = new Vector(10);
|
||||
Component tmp;
|
||||
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
tmp = getComponent(i);
|
||||
if (tmp instanceof JInternalFrame) {
|
||||
vResults.addElement(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
result = new JInternalFrame[vResults.size()];
|
||||
vResults.copyInto(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getFrameCount() {
|
||||
return getComponentCount(new ComponentFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(Component c) {
|
||||
return c instanceof JInternalFrame
|
||||
|| (c instanceof JInternalFrame.JDesktopIcon
|
||||
&& ((JInternalFrame.JDesktopIcon) c).getInternalFrame() != null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getComponentCount(ComponentFilter c) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < getComponentCount(); i++) {
|
||||
if (c.accept(getComponent(i))) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void selectFrame(JInternalFrame f) {
|
||||
if (f != null) {
|
||||
try {
|
||||
if (f.isIcon()) {
|
||||
f.setIcon(false);
|
||||
} else {
|
||||
f.setSelected(true);
|
||||
}
|
||||
} catch (PropertyVetoException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addImpl(Component comp, Object constraints, int index) {
|
||||
super.addImpl(comp, constraints, index);
|
||||
if (comp instanceof JInternalFrame) {
|
||||
JInternalFrame docFrame = (JInternalFrame) comp;
|
||||
int frameIndex = windowMenu.getItemCount() - desktopManager.WINDOW_LIST_START + 1;
|
||||
if (docFrame.getClientProperty(ExtDesktopManager.INDEX) != null) {
|
||||
return;
|
||||
}
|
||||
docFrame.putClientProperty(ExtDesktopManager.INDEX, frameIndex);
|
||||
JMenuItem m = new JMenuItem((frameIndex < 10 ? frameIndex + " " : "") + docFrame.getTitle());
|
||||
if (frameIndex < 10) {
|
||||
m.setMnemonic((char) (0x30 + frameIndex));
|
||||
m.setAccelerator(KeyStroke.getKeyStroke(0x30 + frameIndex, InputEvent.ALT_MASK));
|
||||
}
|
||||
m.setToolTipText("Shows the window " + docFrame.getTitle());
|
||||
m.putClientProperty(ExtDesktopManager.FRAME, docFrame);
|
||||
m.addActionListener(actMenuFrame);
|
||||
windowMenu.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
public JMenu getWindowMenu() {
|
||||
return windowMenu;
|
||||
}
|
||||
}
|
||||
60
src/main/java/eva2/gui/JExtDesktopPaneToolBar.java
Normal file
60
src/main/java/eva2/gui/JExtDesktopPaneToolBar.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.tools.ToolBoxGui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* @author becker
|
||||
*/
|
||||
public class JExtDesktopPaneToolBar extends JToolBar {
|
||||
|
||||
private JExtDesktopPane desktopPane;
|
||||
|
||||
public JExtDesktopPaneToolBar(JExtDesktopPane desktopPane) {
|
||||
this.desktopPane = desktopPane;
|
||||
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
/* We don't want the ToolBar to be draggable */
|
||||
setFloatable(false);
|
||||
|
||||
/* Add Buttons to tile the desktopPane */
|
||||
JButton verticalButton = ToolBoxGui.createIconifiedButton("images/TileVertical16.png", "Tile vertically", false);
|
||||
verticalButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
desktopPane.tileWindows(SwingConstants.VERTICAL);
|
||||
}
|
||||
|
||||
});
|
||||
add(verticalButton);
|
||||
|
||||
JButton horizontalButton = ToolBoxGui.createIconifiedButton("images/TileHorizontal16.png", "Tile horizontally", false);
|
||||
horizontalButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
desktopPane.tileWindows(SwingConstants.HORIZONTAL);
|
||||
}
|
||||
|
||||
});
|
||||
add(horizontalButton);
|
||||
|
||||
JButton cascadeButton = ToolBoxGui.createIconifiedButton("images/Cascade16.png", "Cascade windows", false);
|
||||
cascadeButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
desktopPane.overlapWindows();
|
||||
}
|
||||
|
||||
});
|
||||
add(cascadeButton);
|
||||
}
|
||||
}
|
||||
44
src/main/java/eva2/gui/JExtFileChooser.java
Normal file
44
src/main/java/eva2/gui/JExtFileChooser.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2003
|
||||
* Company: University of Tuebingen, Computer Architecture
|
||||
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
||||
* @version: $Revision: 10 $
|
||||
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
|
||||
* $Author: streiche $
|
||||
*/
|
||||
/*==========================================================================*
|
||||
* IMPORTS
|
||||
*==========================================================================*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
|
||||
public class JExtFileChooser extends JFileChooser {
|
||||
private boolean overwriteWarning = true;
|
||||
|
||||
public void setOverwriteWarning(boolean value) {
|
||||
overwriteWarning = value;
|
||||
}
|
||||
|
||||
public boolean getOverwriteWarning() {
|
||||
return overwriteWarning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void approveSelection() {
|
||||
if (getDialogType() == JFileChooser.SAVE_DIALOG && overwriteWarning) {
|
||||
File f = getSelectedFile();
|
||||
|
||||
if (f != null && f.exists()) {
|
||||
if (JOptionPane.showConfirmDialog(this, "Die Datei " + f.getPath() + " existiert bereits.\nSoll sie <20>berschrieben werden?", "Achtung", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.NO_OPTION) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.approveSelection();
|
||||
}
|
||||
}
|
||||
105
src/main/java/eva2/gui/JExtMenu.java
Normal file
105
src/main/java/eva2/gui/JExtMenu.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2003
|
||||
* Company: University of Tuebingen, Computer Architecture
|
||||
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
||||
* @version: $Revision: 10 $
|
||||
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
|
||||
* $Author: streiche $
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JExtMenu extends JMenu {
|
||||
|
||||
public final static String ACTION = "Action";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JExtMenu() {
|
||||
//super();
|
||||
//Mnemonic m = new Mnemonic(s);
|
||||
//setText(m.getText());
|
||||
//setMnemonic(m.getMnemonic());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JExtMenu(String s) {
|
||||
super();
|
||||
Mnemonic m = new Mnemonic(s);
|
||||
setText(m.getText());
|
||||
setMnemonic(m.getMnemonic());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public JMenuItem add(Action a) {
|
||||
JMenuItem item = super.add(a);
|
||||
Object o;
|
||||
o = a.getValue(ExtAction.MNEMONIC);
|
||||
if (o != null) {
|
||||
item.setMnemonic(((Character) o).charValue());
|
||||
}
|
||||
o = a.getValue(ExtAction.TOOLTIP);
|
||||
if (o != null) {
|
||||
item.setToolTipText((String) o);
|
||||
}
|
||||
o = a.getValue(ExtAction.KEYSTROKE);
|
||||
if (o != null) {
|
||||
item.setAccelerator((KeyStroke) o);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected PropertyChangeListener createActionChangeListener(JMenuItem b) {
|
||||
return new ExtActionChangedListener(b) {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
JMenuItem menuItem = (JMenuItem) component;
|
||||
if (menuItem == null) {
|
||||
return;
|
||||
}
|
||||
String propertyName = e.getPropertyName();
|
||||
switch (propertyName) {
|
||||
case Action.NAME:
|
||||
menuItem.setText((String) e.getNewValue());
|
||||
break;
|
||||
case "enabled":
|
||||
menuItem.setEnabled(((Boolean) e.getNewValue()).booleanValue());
|
||||
break;
|
||||
case Action.SMALL_ICON:
|
||||
Icon icon = (Icon) e.getNewValue();
|
||||
menuItem.setIcon(icon);
|
||||
menuItem.invalidate();
|
||||
menuItem.repaint();
|
||||
break;
|
||||
case ExtAction.MNEMONIC:
|
||||
menuItem.setMnemonic(((Character) e.getNewValue()).charValue());
|
||||
break;
|
||||
case ExtAction.TOOLTIP:
|
||||
menuItem.setToolTipText((String) e.getNewValue());
|
||||
break;
|
||||
case ExtAction.KEYSTROKE:
|
||||
menuItem.setAccelerator((KeyStroke) e.getNewValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
85
src/main/java/eva2/gui/JExtToolBar.java
Normal file
85
src/main/java/eva2/gui/JExtToolBar.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2
|
||||
* Description:
|
||||
* Copyright: Copyright (c) 2003
|
||||
* Company: University of Tuebingen, Computer Architecture
|
||||
* @author Holger Ulmer, Felix Streichert, Hannes Planatscher
|
||||
* @version: $Revision: 10 $
|
||||
* $Date: 2006-01-18 11:02:22 +0100 (Wed, 18 Jan 2006) $
|
||||
* $Author: streiche $
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JExtToolBar extends JToolBar {
|
||||
@Override
|
||||
public JButton add(Action a) {
|
||||
JButton button = super.add(a);
|
||||
button.setText(null);
|
||||
button.setMargin(new Insets(0, 0, 0, 0));
|
||||
|
||||
Object o;
|
||||
o = a.getValue(ExtAction.TOOLTIP);
|
||||
String toolTip = o != null ? (String) o : "";
|
||||
|
||||
o = a.getValue(ExtAction.KEYSTROKE);
|
||||
button.setToolTipText(toolTip + getKeyText((KeyStroke) o));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private String getKeyText(KeyStroke k) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
if (k != null) {
|
||||
int modifiers = k.getModifiers();
|
||||
if (modifiers > 0) {
|
||||
result.append(KeyEvent.getKeyModifiersText(modifiers)).append("+");
|
||||
}
|
||||
result.append(KeyEvent.getKeyText(k.getKeyCode()));
|
||||
}
|
||||
if (result.length() > 0) {
|
||||
result.insert(0, " [");
|
||||
result.append("]");
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyChangeListener createActionChangeListener(JButton b) {
|
||||
return new ExtActionChangedListener(b) {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
JButton button = (JButton) component;
|
||||
|
||||
String propertyName = e.getPropertyName();
|
||||
if (propertyName.equals(Action.NAME)) {
|
||||
/* Nichts tun! */
|
||||
} else if (propertyName.equals("enabled")) {
|
||||
button.setEnabled(((Boolean) e.getNewValue()).booleanValue());
|
||||
button.repaint();
|
||||
} else if (e.getPropertyName().equals(Action.SMALL_ICON)) {
|
||||
button.setIcon((Icon) e.getNewValue());
|
||||
button.invalidate();
|
||||
button.repaint();
|
||||
} else if (propertyName.equals(ExtAction.TOOLTIP) || propertyName.equals(ExtAction.KEYSTROKE)) {
|
||||
Action source = (Action) e.getSource();
|
||||
|
||||
Object o = source.getValue(ExtAction.TOOLTIP);
|
||||
String toolTip = o != null ? (String) o : "";
|
||||
o = source.getValue(ExtAction.KEYSTROKE);
|
||||
button.setToolTipText(toolTip + getKeyText((KeyStroke) o));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
74
src/main/java/eva2/gui/JParaPanel.java
Normal file
74
src/main/java/eva2/gui/JParaPanel.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.gui.editor.GenericObjectEditor;
|
||||
import eva2.optimization.statistics.OptimizationJobList;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorManager;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JParaPanel implements Serializable, PanelMaker {
|
||||
|
||||
protected String name = "undefined";
|
||||
protected Object localParameter;
|
||||
protected PropertyEditor propertyEditor;
|
||||
|
||||
/**
|
||||
* ToDo: Should be removed in future.
|
||||
*/
|
||||
private JPanel tempPanel = new JPanel();
|
||||
|
||||
/**
|
||||
*/
|
||||
public JParaPanel(Object Parameter, String name) {
|
||||
this.name = name;
|
||||
localParameter = Parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
@Override
|
||||
public JComponent makePanel() {
|
||||
PropertyEditorProvider.installEditors();
|
||||
|
||||
if (localParameter instanceof OptimizationJobList) {
|
||||
/* ToDo: First parameter is useless and should be removed */
|
||||
propertyEditor = OptimizationJobList.makeEditor(tempPanel, (OptimizationJobList) localParameter);
|
||||
} else {
|
||||
propertyEditor = new GenericObjectEditor();
|
||||
((GenericObjectEditor) (propertyEditor)).setClassType(localParameter.getClass());
|
||||
propertyEditor.setValue(localParameter);
|
||||
((GenericObjectEditor) (propertyEditor)).disableOKCancel();
|
||||
}
|
||||
|
||||
return (JComponent) propertyEditor.getCustomEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PropertyEditor getEditor() {
|
||||
return propertyEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to add a new Editor to a given class
|
||||
*
|
||||
* @param object
|
||||
* @param editor
|
||||
* @return False if failed true else.
|
||||
*/
|
||||
public boolean registerEditor(Class object, Class editor) {
|
||||
try {
|
||||
PropertyEditorManager.registerEditor(object, editor);
|
||||
} catch (Exception ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
317
src/main/java/eva2/gui/JTextEditorInternalFrame.java
Normal file
317
src/main/java/eva2/gui/JTextEditorInternalFrame.java
Normal file
@@ -0,0 +1,317 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.event.UndoableEditEvent;
|
||||
import javax.swing.event.UndoableEditListener;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.Keymap;
|
||||
import javax.swing.undo.CannotRedoException;
|
||||
import javax.swing.undo.CannotUndoException;
|
||||
import javax.swing.undo.UndoManager;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
||||
public class JTextEditorInternalFrame extends JDocFrame {
|
||||
public final static String GROUP_EDIT = "Edit";
|
||||
private JTextArea textArea;
|
||||
private final String[] actionGroups = {GROUP_EDIT};
|
||||
protected UndoManager undo = new UndoManager();
|
||||
|
||||
private class UndoAction extends ExtAction {
|
||||
public UndoAction() {
|
||||
super("R<EFBFBD>ckg<EFBFBD>ngig", new ImageIcon("images/EditUndo.gif"), "Macht die letzte Aktion r<>ckg<6B>ngig",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK));
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
undo.undo();
|
||||
} catch (CannotUndoException exc) {
|
||||
}
|
||||
|
||||
update();
|
||||
actRedo.update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (undo.canUndo()) {
|
||||
setEnabled(true);
|
||||
putValue(Action.NAME, undo.getUndoPresentationName());
|
||||
} else {
|
||||
setEnabled(false);
|
||||
putValue(Action.NAME, "R<EFBFBD>ckg<EFBFBD>ngig");
|
||||
}
|
||||
}
|
||||
} // end of inner class UndoAction
|
||||
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
///////////////////////////////////////////
|
||||
private class RedoAction extends ExtAction {
|
||||
public RedoAction() {
|
||||
super("Wiederholen", "Wiederholt die letzte Aktion", KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
undo.redo();
|
||||
} catch (CannotRedoException exc) {
|
||||
}
|
||||
|
||||
update();
|
||||
actUndo.update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (undo.canRedo()) {
|
||||
setEnabled(true);
|
||||
putValue(Action.NAME, undo.getRedoPresentationName());
|
||||
} else {
|
||||
setEnabled(false);
|
||||
putValue(Action.NAME, "Wiederholen");
|
||||
}
|
||||
}
|
||||
} // end of inner class RedoAction
|
||||
|
||||
private UndoAction actUndo;
|
||||
private RedoAction actRedo;
|
||||
public final static String undoAction = "undo";
|
||||
public final static String redoAction = "redo";
|
||||
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////////
|
||||
@Override
|
||||
public String[] getActionGroups() {
|
||||
return actionGroups;
|
||||
}
|
||||
|
||||
private JMenu mnuEdit;
|
||||
private JToolBar barEdit;
|
||||
|
||||
@Override
|
||||
public JMenu getMenu(String group) {
|
||||
if (GROUP_EDIT.equals(group)) {
|
||||
return mnuEdit;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JToolBar getToolBar(String group) {
|
||||
if (GROUP_EDIT.equals(group)) {
|
||||
return barEdit;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Hashtable hashActions = new Hashtable();
|
||||
|
||||
private Action cloneAction(Action a) {
|
||||
Action result = null;
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(bOut);
|
||||
out.writeObject(a);
|
||||
ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
|
||||
ObjectInputStream in = new ObjectInputStream(bIn);
|
||||
result = (Action) in.readObject();
|
||||
} catch (Exception exc) {
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
//////////////////////////////////////////////
|
||||
private void createActions() {
|
||||
hashActions.put(undoAction, actUndo = new UndoAction());
|
||||
hashActions.put(redoAction, actRedo = new RedoAction());
|
||||
|
||||
Action[] actions = textArea.getActions();
|
||||
for (int i = 0; i < actions.length; i++) {
|
||||
hashActions.put(actions[i].getValue(Action.NAME), actions[i]);
|
||||
}
|
||||
|
||||
mnuEdit = new JExtMenu("&Bearbeiten");
|
||||
barEdit = new JExtToolBar();
|
||||
|
||||
Action a;
|
||||
Keymap keys = textArea.getKeymap();
|
||||
KeyStroke[] keyActions;
|
||||
|
||||
mnuEdit.add(actUndo);
|
||||
barEdit.add(actUndo);
|
||||
mnuEdit.add(actRedo);
|
||||
mnuEdit.addSeparator();
|
||||
|
||||
a = (Action) hashActions.get(DefaultEditorKit.cutAction);
|
||||
keyActions = keys.getKeyStrokesForAction(a);
|
||||
if (keyActions != null && keyActions.length > 0) {
|
||||
a.putValue(ExtAction.KEYSTROKE, keyActions[0]);
|
||||
}
|
||||
a.putValue(Action.SMALL_ICON, new ImageIcon("images/EditCut.gif"));
|
||||
a.putValue(ExtAction.CAPTION, "Ausschneiden");
|
||||
a.putValue(ExtAction.MNEMONIC, 'a');
|
||||
a.putValue(ExtAction.TOOLTIP, "Schneidet den markierten Text aus und setzt ihn in die Zwischenablage");
|
||||
mnuEdit.add(a);
|
||||
barEdit.add(a);
|
||||
|
||||
a = (Action) hashActions.get(DefaultEditorKit.copyAction);
|
||||
keyActions = keys.getKeyStrokesForAction(a);
|
||||
if (keyActions != null && keyActions.length > 0) {
|
||||
a.putValue(ExtAction.KEYSTROKE, keyActions[0]);
|
||||
}
|
||||
a.putValue(Action.SMALL_ICON, new ImageIcon("images/EditCopy.gif"));
|
||||
a.putValue(ExtAction.CAPTION, "Kopieren");
|
||||
a.putValue(ExtAction.MNEMONIC, 'k');
|
||||
a.putValue(ExtAction.TOOLTIP, "Kopiert den markierten Text in die Zwischenablage");
|
||||
mnuEdit.add(a);
|
||||
barEdit.add(a);
|
||||
|
||||
a = (Action) hashActions.get(DefaultEditorKit.pasteAction);
|
||||
keyActions = keys.getKeyStrokesForAction(a);
|
||||
if (keyActions != null && keyActions.length > 0) {
|
||||
a.putValue(ExtAction.KEYSTROKE, keyActions[0]);
|
||||
}
|
||||
a.putValue(Action.SMALL_ICON, new ImageIcon("images/EditPaste.gif"));
|
||||
a.putValue(ExtAction.CAPTION, "Einf<EFBFBD>gen");
|
||||
a.putValue(ExtAction.MNEMONIC, 'e');
|
||||
a.putValue(ExtAction.TOOLTIP, "F<EFBFBD>gt Text aus der Zwischenablage ein");
|
||||
mnuEdit.add(a);
|
||||
barEdit.add(a);
|
||||
|
||||
mnuEdit.addSeparator();
|
||||
|
||||
a = (Action) hashActions.get(DefaultEditorKit.selectAllAction);
|
||||
keyActions = keys.getKeyStrokesForAction(a);
|
||||
if (keyActions != null && keyActions.length > 0) {
|
||||
a.putValue(ExtAction.KEYSTROKE, keyActions[0]);
|
||||
}
|
||||
a.putValue(ExtAction.CAPTION, "Alles markieren");
|
||||
a.putValue(ExtAction.MNEMONIC, 'm');
|
||||
a.putValue(ExtAction.TOOLTIP, "Markiert das ganze Dokument");
|
||||
mnuEdit.add(a);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////////
|
||||
private void createTextArea() {
|
||||
textArea = new JTextArea();
|
||||
getContentPane().add(new JScrollPane(textArea));
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////
|
||||
private void createListeners() {
|
||||
textArea.getDocument().addDocumentListener(new DocumentListener() {
|
||||
private void changed() {
|
||||
setChanged(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
changed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
changed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
changed();
|
||||
}
|
||||
});
|
||||
|
||||
textArea.getDocument().addUndoableEditListener(new UndoableEditListener() {
|
||||
@Override
|
||||
public void undoableEditHappened(UndoableEditEvent e) {
|
||||
undo.addEdit(e.getEdit());
|
||||
actUndo.update();
|
||||
actRedo.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
///////////////////////////////////////////////////
|
||||
public JTextEditorInternalFrame(String title) {
|
||||
super(title);
|
||||
createTextArea();
|
||||
createListeners();
|
||||
createActions();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////////////////
|
||||
public JTextEditorInternalFrame(File file) {
|
||||
super(file);
|
||||
createTextArea();
|
||||
|
||||
if (file.exists()) {
|
||||
FileReader in = null;
|
||||
try {
|
||||
in = new FileReader(file);
|
||||
textArea.read(in, null);
|
||||
} catch (IOException exc) {
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException exc) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createListeners();
|
||||
createActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(File f) {
|
||||
FileWriter out = null;
|
||||
try {
|
||||
out = new FileWriter(f);
|
||||
textArea.write(out);
|
||||
} catch (IOException exc) {
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException exc) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.save(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean value) throws java.beans.PropertyVetoException {
|
||||
super.setSelected(value);
|
||||
|
||||
if (value) {
|
||||
textArea.requestFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
190
src/main/java/eva2/gui/JTextoutputFrame.java
Normal file
190
src/main/java/eva2/gui/JTextoutputFrame.java
Normal file
@@ -0,0 +1,190 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.tools.FileTools;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.text.AbstractDocument;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DocumentFilter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JTextoutputFrame implements JTextoutputFrameInterface, ActionListener, Serializable {
|
||||
|
||||
private JMenuItem clearItem, saveItem;
|
||||
protected String frameTitle = "undefined";
|
||||
private transient JTextArea textArea = null;
|
||||
private final JInternalFrame frame;
|
||||
private JPopupMenu popup;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public JTextoutputFrame(String title) {
|
||||
frameTitle = title;
|
||||
frame = new JEFrame(frameTitle);
|
||||
frame.setClosable(false);
|
||||
textArea = null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void print(String text) {
|
||||
if (textArea == null) {
|
||||
createFrame();
|
||||
}
|
||||
textArea.append(text);
|
||||
textArea.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String txt) {
|
||||
print(txt + '\n');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShow(boolean bShow) {
|
||||
if (frame.isVisible() != bShow) {
|
||||
if (frame.isVisible()) {
|
||||
frame.dispose();
|
||||
textArea.setText(null);
|
||||
} else {
|
||||
if (textArea == null) {
|
||||
createFrame();
|
||||
} else {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
frame.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void createFrame() {
|
||||
textArea = new JTextArea(10, 80);
|
||||
textArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
textArea.setLineWrap(true);
|
||||
textArea.setWrapStyleWord(true);
|
||||
textArea.setEditable(false);
|
||||
textArea.setCaretPosition(0);
|
||||
textArea.setTabSize(16);
|
||||
textArea.setFont(new Font("Courier New", Font.PLAIN, 12));
|
||||
// Limit text output to 2500 Lines
|
||||
((AbstractDocument)textArea.getDocument()).setDocumentFilter(new LineBufferDocumentFilter(textArea, 2500));
|
||||
|
||||
|
||||
frame.getContentPane().setLayout(new BorderLayout());
|
||||
final JScrollPane scrollpane = new JScrollPane(textArea);
|
||||
frame.getContentPane().add(scrollpane, BorderLayout.CENTER);
|
||||
scrollpane.getViewport().addChangeListener(new ChangeListener() {
|
||||
|
||||
private int lastHeight;
|
||||
//
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
JViewport viewport = (JViewport) e.getSource();
|
||||
int height = viewport.getViewSize().height;
|
||||
if (height != lastHeight) {
|
||||
lastHeight = height;
|
||||
int x = height - viewport.getExtentSize().height;
|
||||
viewport.setViewPosition(new Point(0, x));
|
||||
}
|
||||
}
|
||||
});
|
||||
makePopupMenu();
|
||||
frame.pack();
|
||||
frame.setSize(800, 400);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
void makePopupMenu() {
|
||||
//Create the popup menu.
|
||||
popup = new JPopupMenu();
|
||||
clearItem = new JMenuItem("Clear");
|
||||
clearItem.addActionListener(this);
|
||||
popup.add(clearItem);
|
||||
saveItem = new JMenuItem("Save as...");
|
||||
saveItem.addActionListener(this);
|
||||
popup.add(saveItem);
|
||||
|
||||
//Add listener to components that can bring up popup menus.
|
||||
MouseListener popupListener = new PopupListener(popup);
|
||||
textArea.addMouseListener(popupListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JMenuItem src = (JMenuItem) e.getSource();
|
||||
if (src == clearItem) {
|
||||
textArea.setText(null);
|
||||
} else if (src == saveItem) {
|
||||
FileTools.saveObjectWithFileChooser(frame, textArea.getText(), null);
|
||||
} else {
|
||||
System.err.println("Unknown popup component (JTextoutputFrame)!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A popup listener opening a popup menu on right clicks.
|
||||
*
|
||||
* @author mkron
|
||||
*/
|
||||
class PopupListener extends MouseAdapter {
|
||||
|
||||
JPopupMenu popup;
|
||||
|
||||
public PopupListener(JPopupMenu pm) {
|
||||
popup = pm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
private void maybeShowPopup(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
popup.show(e.getComponent(),
|
||||
e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LineBufferDocumentFilter extends DocumentFilter {
|
||||
private JTextArea area;
|
||||
private int max;
|
||||
|
||||
public LineBufferDocumentFilter(JTextArea area, int max) {
|
||||
this.area = area;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
|
||||
super.insertString(fb, offset, text, attr);
|
||||
int lines = area.getLineCount();
|
||||
if (lines > max) {
|
||||
int linesToRemove = lines - max -1;
|
||||
int lengthToRemove = area.getLineStartOffset(linesToRemove);
|
||||
remove(fb, 0, lengthToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/main/java/eva2/gui/JTextoutputFrameInterface.java
Normal file
16
src/main/java/eva2/gui/JTextoutputFrameInterface.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.statistics.InterfaceTextListener;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
public interface JTextoutputFrameInterface extends InterfaceTextListener {
|
||||
|
||||
/**
|
||||
* Set the show property to define whether the Output Frame should be shown.
|
||||
*
|
||||
* @param bShow Whether the frame should be shown or not
|
||||
*/
|
||||
void setShow(boolean bShow);
|
||||
}
|
||||
117
src/main/java/eva2/gui/LoggingLevelLabel.java
Normal file
117
src/main/java/eva2/gui/LoggingLevelLabel.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* This is a JLabel that shows the current logging level
|
||||
* depending on the Logger provided. It creates a popup
|
||||
* menu on left-click to change the logging level. Logging
|
||||
* levels are as specified by "java.util.logging.Level.*"
|
||||
*
|
||||
* @author becker
|
||||
*/
|
||||
public final class LoggingLevelLabel extends JLabel {
|
||||
private JPopupMenu menu;
|
||||
private String[] options;
|
||||
private static final Logger LOGGER = Logger.getLogger(LoggingLevelLabel.class.getName());
|
||||
|
||||
public LoggingLevelLabel() {
|
||||
options = new String[]{"Info", "Warning", "Severe", "Fine", "Finer", "Finest", "All"};
|
||||
|
||||
|
||||
setToolTipText("Click to change current logging level");
|
||||
createPopupMenu();
|
||||
updateText();
|
||||
}
|
||||
|
||||
private void createPopupMenu() {
|
||||
this.menu = new JPopupMenu();
|
||||
addMouseListener(new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent ev) {
|
||||
menu.show(ev.getComponent(), ev.getX(), ev.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem menuItem;
|
||||
ActionListener menuAction = new MenuActionListener();
|
||||
for (String option : options) {
|
||||
menuItem = new JMenuItem(option);
|
||||
menuItem.addActionListener(menuAction);
|
||||
menu.add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the visible text on the label.
|
||||
*/
|
||||
private void updateText() {
|
||||
/* Get the current logging Level */
|
||||
Level lvl = LOGGER.getLevel();
|
||||
/* Level could be null, fetch parent level */
|
||||
if (lvl == null) {
|
||||
lvl = LOGGER.getParent().getLevel();
|
||||
}
|
||||
/* Show the updated text */
|
||||
setText("<html><b>Level</b>: " + lvl.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the level of the logger to a new level.
|
||||
*
|
||||
* @param level The new level for the logger
|
||||
*/
|
||||
private void setLoggerLevel(Level level) {
|
||||
// Recursively set logging level for all classes under eva2
|
||||
Logger.getLogger("eva2").setLevel(level);
|
||||
LOGGER.log(Level.INFO, "Logging Level changed to {0}", level.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class MenuActionListener implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent ev) {
|
||||
JMenuItem menuItem = (JMenuItem) ev.getSource();
|
||||
String levelName = menuItem.getText();
|
||||
|
||||
try {
|
||||
Level level = Level.parse(levelName.toUpperCase());
|
||||
LoggingLevelLabel.this.setLoggerLevel(level);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOGGER.log(Level.INFO, "Could not determine new logging level!", ex);
|
||||
}
|
||||
|
||||
LoggingLevelLabel.this.updateText();
|
||||
}
|
||||
}
|
||||
}
|
||||
109
src/main/java/eva2/gui/LoggingPanel.java
Normal file
109
src/main/java/eva2/gui/LoggingPanel.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Simple logging panel that shows logs produced by EvA2
|
||||
*/
|
||||
public class LoggingPanel extends JPanel {
|
||||
protected static Logger LOGGER = Logger.getLogger(LoggingPanel.class.getName());
|
||||
protected JTextArea loggingTextArea = new JTextArea(10, 20);
|
||||
protected Handler loggingHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public LoggingPanel() {
|
||||
loggingTextArea.setEditable(false);
|
||||
loggingTextArea.setLineWrap(true);
|
||||
loggingTextArea.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
add(new JLabel("Info"), BorderLayout.PAGE_START);
|
||||
|
||||
this.loggingHandler = new LoggingHandler(this);
|
||||
|
||||
// Create default logger at namespace root eva2
|
||||
Logger rootLogger = Logger.getLogger("eva2");
|
||||
rootLogger.addHandler(loggingHandler);
|
||||
|
||||
final JScrollPane scrollpane = new JScrollPane(loggingTextArea);
|
||||
scrollpane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
|
||||
// scrollpane.setAutoscrolls(false);
|
||||
add(scrollpane, BorderLayout.CENTER);
|
||||
scrollpane.getViewport().addChangeListener(new ChangeListener() {
|
||||
private int lastHeight;
|
||||
|
||||
//
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
JViewport viewport = (JViewport) e.getSource();
|
||||
int height = viewport.getViewSize().height;
|
||||
if (height != lastHeight) {
|
||||
lastHeight = height;
|
||||
int x = height - viewport.getExtentSize().height;
|
||||
viewport.setViewPosition(new Point(0, x));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected static String getTimestamp() {
|
||||
return (new SimpleDateFormat("HH:mm:ss:")).format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void logMessage(String message) {
|
||||
loggingTextArea.append(LoggingPanel.getTimestamp() + ' ' + message);
|
||||
loggingTextArea.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
class LoggingHandler extends Handler {
|
||||
protected LoggingPanel loggingPanel;
|
||||
|
||||
public LoggingHandler(LoggingPanel loggingPanel) {
|
||||
this.loggingPanel = loggingPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
StringBuilder sBuilder = new StringBuilder();
|
||||
sBuilder.append("[");
|
||||
sBuilder.append(record.getLevel().toString());
|
||||
sBuilder.append("] ");
|
||||
MessageFormat messageFormat = new MessageFormat(record.getMessage());
|
||||
sBuilder.append(messageFormat.format(record.getParameters()));
|
||||
// Show message on LogPanel
|
||||
this.loggingPanel.logMessage(sBuilder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
/*
|
||||
* We do nothing here as we don't buffer the entries
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException {
|
||||
/*
|
||||
* Nothing to close
|
||||
*/
|
||||
}
|
||||
}
|
||||
8
src/main/java/eva2/gui/META-INF/MANIFEST.MF
Normal file
8
src/main/java/eva2/gui/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,8 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path: xml-apis-1.0.b2.jar gson-2.2.4.jar reflections-0.9.9-RC1.j
|
||||
ar jide-oss-2.4.8.jar jsr305-1.3.9.jar commons-math3-3.1.1.jar common
|
||||
s-cli-1.2.jar xmlgraphics-commons-1.3.1.jar javahelp-2.0.05.jar jchar
|
||||
t2d-3.3.2.jar commons-io-1.3.1.jar guava-11.0.2.jar commons-logging-1
|
||||
.0.4.jar javassist-3.16.1-GA.jar dom4j-1.6.1.jar
|
||||
Main-Class: eva2.gui.Main
|
||||
|
||||
590
src/main/java/eva2/gui/MOCCOStandalone.java
Normal file
590
src/main/java/eva2/gui/MOCCOStandalone.java
Normal file
@@ -0,0 +1,590 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.optimization.mocco.*;
|
||||
import eva2.optimization.mocco.paretofrontviewer.MOCCOViewer;
|
||||
import eva2.optimization.operator.moso.InterfaceMOSOConverter;
|
||||
import eva2.optimization.operator.moso.MOSOWeightedFitness;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.optimization.population.InterfacePopulationChangedEventListener;
|
||||
import eva2.optimization.population.Population;
|
||||
import eva2.optimization.strategies.InterfaceOptimizer;
|
||||
import eva2.optimization.strategies.IslandModelEA;
|
||||
import eva2.problems.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MOCCOStandalone implements InterfaceStandaloneOptimization, InterfacePopulationChangedEventListener, Serializable {
|
||||
|
||||
public volatile MOCCOState state;
|
||||
private eva2.gui.SwingWorker worker;
|
||||
private volatile boolean stillWorking = false;
|
||||
public int iteration = -1;
|
||||
private JFrame mainFrame;
|
||||
//public ParetoFrontView n_ParetoFrontView;
|
||||
private boolean debug = false;
|
||||
public MOCCOViewer view;
|
||||
public JPanel mainPanel, parameterPanel, controlPanel, buttonPanel;
|
||||
private JLabel currentState;
|
||||
private JProgressBar progressBar;
|
||||
|
||||
public MOCCOStandalone() {
|
||||
this.state = new MOCCOState();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the main MOCCO GUI
|
||||
* frame
|
||||
*/
|
||||
public void initMOCCOFrame() {
|
||||
|
||||
this.state.isVisible = true;
|
||||
this.mainFrame = new JFrame();
|
||||
this.mainFrame.setTitle("MOCCO - Interactive Multi-Objective Optimization");
|
||||
this.mainFrame.setSize(1200, 750);
|
||||
this.mainFrame.setLocation(50, 50);
|
||||
this.mainFrame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent ev) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
// initialize basic panel structure
|
||||
this.mainPanel = new JPanel();
|
||||
this.parameterPanel = new JPanel();
|
||||
this.parameterPanel.setPreferredSize(new Dimension(500, 300));
|
||||
this.parameterPanel.setMinimumSize(new Dimension(500, 300));
|
||||
this.controlPanel = new JPanel();
|
||||
this.view = new MOCCOViewer(this);
|
||||
this.mainFrame.getContentPane().add(this.mainPanel);
|
||||
this.mainPanel.setLayout(new BorderLayout());
|
||||
this.mainPanel.add(this.parameterPanel, BorderLayout.WEST);
|
||||
this.mainPanel.add(this.view, BorderLayout.CENTER);
|
||||
this.buttonPanel = new JPanel();
|
||||
this.buttonPanel.setLayout(new BorderLayout());
|
||||
JPanel tmpP = new JPanel();
|
||||
tmpP.setLayout(new GridLayout(2, 1));
|
||||
this.currentState = new JLabel("Problem Initialization");
|
||||
tmpP.add(this.currentState);
|
||||
this.progressBar = new JProgressBar();
|
||||
tmpP.add(this.progressBar);
|
||||
this.buttonPanel.add(tmpP, BorderLayout.CENTER);
|
||||
this.controlPanel.setMinimumSize(new Dimension(400, 0));
|
||||
this.controlPanel.setPreferredSize(new Dimension(400, 0));
|
||||
this.buttonPanel.add(this.controlPanel, BorderLayout.EAST);
|
||||
this.mainPanel.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.mainFrame.validate();
|
||||
// everything is prepared let's start the main loop
|
||||
this.MOCCOOptimization();
|
||||
}
|
||||
|
||||
public void MOCCOOptimization() {
|
||||
boolean cont = true;
|
||||
InterfaceProcessElement tmpP;
|
||||
while (cont) {
|
||||
this.iteration++;
|
||||
while (stillWorking) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
if (this.state.originalProblem == null) {
|
||||
this.state.originalProblem = new TF1Problem();
|
||||
tmpP = new MOCCOProblemInitialization(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
this.state.currentProblem = (InterfaceOptimizationProblem) this.state.originalProblem.clone();
|
||||
this.view.problemChanged(true);
|
||||
this.parameterPanel.removeAll();
|
||||
tmpP = new MOCCOInitialPopulationSize(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
this.state.initialPopulationSize = Math.max(1, this.state.initialPopulationSize);
|
||||
Population pop = new Population();
|
||||
pop.setTargetSize(this.state.initialPopulationSize);
|
||||
this.state.currentProblem = (InterfaceOptimizationProblem) this.state.originalProblem.clone();
|
||||
this.state.currentProblem.initializePopulation(pop);
|
||||
this.state.currentProblem.evaluate(pop);
|
||||
this.state.addPopulation2History(pop);
|
||||
this.view.problemChanged(true);
|
||||
}
|
||||
((InterfaceMultiObjectiveDeNovoProblem) this.state.currentProblem).deactivateRepresentationEdit();
|
||||
this.updateStatus("Analysis/Redefinition", 33);
|
||||
tmpP = new MOCCOProblemRedefinition(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
this.state.makeFitnessCache(true);
|
||||
this.state.currentProblem.initializeProblem();
|
||||
this.state.makeBackup();
|
||||
this.view.problemChanged(true);
|
||||
if (this.state.currentProblem.isMultiObjective()) {
|
||||
this.updateStatus("MO Strategy Selection", 50);
|
||||
tmpP = new MOCCOChooseMOStrategy(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
switch (((MOCCOChooseMOStrategy) tmpP).getMOStrategy()) {
|
||||
case MOCCOChooseMOStrategy.STRATEGY_MOEA: {
|
||||
this.updateStatus("MOEA Parameterization", 75);
|
||||
tmpP = new MOCCOParameterizeMO(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MOCCOChooseMOStrategy.STRATEGY_STEP: {
|
||||
this.updateStatus("Reference Solution...", 75);
|
||||
tmpP = new MOCCOChooseReferenceSolution(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
AbstractEAIndividual reference = ((MOCCOChooseReferenceSolution) tmpP).getReferenceSolution();
|
||||
this.updateStatus("STEP Parameterization...", 90);
|
||||
tmpP = new MOCCOParameterizeSTEP(this);
|
||||
((MOCCOParameterizeSTEP) tmpP).setReferenceSolution(reference);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MOCCOChooseMOStrategy.STRATEGY_REFP: {
|
||||
this.updateStatus("Reference Point...", 75);
|
||||
tmpP = new MOCCOChooseReferencePoint(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
double[] reference = ((MOCCOChooseReferencePoint) tmpP).getReferencePoint();
|
||||
this.updateStatus("Reference Point Parameterization...", 90);
|
||||
tmpP = new MOCCOParameterizeRefPoint(this);
|
||||
((MOCCOParameterizeRefPoint) tmpP).setReferencePoint(reference);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MOCCOChooseMOStrategy.STRATEGY_TBCH: {
|
||||
this.updateStatus("Reference Point...", 75);
|
||||
tmpP = new MOCCOChooseReferencePoint(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
double[] reference = ((MOCCOChooseReferencePoint) tmpP).getReferencePoint();
|
||||
this.updateStatus("Tchebycheff Method Parameterization...", 90);
|
||||
tmpP = new MOCCOParameterizeTchebycheff(this);
|
||||
((MOCCOParameterizeTchebycheff) tmpP).setReferencePoint(reference);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MOCCOChooseMOStrategy.STRATEGY_GDF: {
|
||||
this.updateStatus("Reference Solution...", 75);
|
||||
tmpP = new MOCCOChooseReferenceSolution(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
AbstractEAIndividual reference = ((MOCCOChooseReferenceSolution) tmpP).getReferenceSolution();
|
||||
this.updateStatus("Geoffrion-Dyer-Feinberg Method Parameterization...", 90);
|
||||
tmpP = new MOCCOParameterizeGDF(this);
|
||||
((MOCCOParameterizeGDF) tmpP).setReferenceSolution(reference);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpP = new MOCCOParameterizeMO(this);
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.updateStatus("SO-Optimizer Parameterization", 66);
|
||||
tmpP = new MOCCOParameterizeSO(this);
|
||||
tmpP.initProcessElementParametrization();
|
||||
while (!tmpP.isFinished()) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (java.lang.InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// now optimize
|
||||
this.updateStatus("Optimizing...", 0);
|
||||
this.startExperiment();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForObjectives(String w) {
|
||||
System.out.println("I'm currently " + w);
|
||||
System.out.print("Original Problem is ");
|
||||
if (this.state.originalProblem.isMultiObjective()) {
|
||||
System.out.println("multi-objective.");
|
||||
} else {
|
||||
System.out.println("single-objective.");
|
||||
}
|
||||
System.out.print("Current Problem is ");
|
||||
if (this.state.currentProblem.isMultiObjective()) {
|
||||
System.out.println("multi-objective.");
|
||||
} else {
|
||||
System.out.println("single-objective.");
|
||||
}
|
||||
if (this.state.backupProblem != null) {
|
||||
System.out.print("Backup Problem is ");
|
||||
if (this.state.backupProblem.isMultiObjective()) {
|
||||
System.out.println("multi-objective.");
|
||||
} else {
|
||||
System.out.println("single-objective.");
|
||||
}
|
||||
} else {
|
||||
System.out.println("No Backup Problem");
|
||||
}
|
||||
}
|
||||
|
||||
private void checktForMOSO(String w) {
|
||||
String s;
|
||||
System.out.println("I'm currently at " + w);
|
||||
InterfaceMOSOConverter moso = ((AbstractMultiObjectiveOptimizationProblem) this.state.currentProblem).getMOSOConverter();
|
||||
System.out.println("MOSO selected: " + moso.getName());
|
||||
InterfaceOptimizationObjective[] obj = ((InterfaceMultiObjectiveDeNovoProblem) this.state.currentProblem).getProblemObjectives();
|
||||
s = "Objectives: {";
|
||||
for (int i = 0; i < obj.length; i++) {
|
||||
s += obj[i].getIdentName();
|
||||
if (i < (obj.length - 1)) {
|
||||
s += "; ";
|
||||
}
|
||||
}
|
||||
s += "}";
|
||||
System.out.println("" + s);
|
||||
if (moso instanceof MOSOWeightedFitness) {
|
||||
PropertyDoubleArray prop = ((MOSOWeightedFitness) moso).getWeights();
|
||||
s = "Weights : {";
|
||||
for (int i = 0; i < prop.getNumRows(); i++) {
|
||||
s += prop.getValue(i, 0);
|
||||
if (i < (prop.getNumRows() - 1)) {
|
||||
s += "; ";
|
||||
}
|
||||
}
|
||||
s += "}";
|
||||
System.out.println("" + s);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
public void test() {
|
||||
for (int a = 1; a < 10; a++) {
|
||||
ArrayList ProxyList = new ArrayList();
|
||||
ArrayList NormalList = new ArrayList();
|
||||
// Create a list of ThreadProxies of Something objects --> ProxyList
|
||||
// Create a list of Something objects --> NormalList
|
||||
for (int i = 0; i < a; i++) {
|
||||
ProxyList.add(ThreadProxy.newInstance(new Something(1000)));
|
||||
NormalList.add(new Something(1000));
|
||||
}
|
||||
long ProxyTime = System.currentTimeMillis();
|
||||
// calling a method of Something, everytime a call is performed a
|
||||
// new Thread is started processing this call.
|
||||
for (int i = 0; i < a; i++)
|
||||
((SomethingInterface)(ProxyList.get(i))).doit();
|
||||
long CallingProxyTime = ProxyTime-System.currentTimeMillis();
|
||||
// calling a second method of Something but the first call (doit)
|
||||
// is not finished until now. So the opeartion sequence waits
|
||||
// here until the first call is finished.
|
||||
for (int i = 0; i < a; i++)
|
||||
((SomethingInterface)(ProxyList.get(i))).nothing();
|
||||
ProxyTime = System.currentTimeMillis() - ProxyTime;
|
||||
System.out.print ("ProxyTime :" + ProxyTime + " CallingProxyTime :" +CallingProxyTime);
|
||||
long NormalTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < a; i++)
|
||||
((SomethingInterface)(NormalList.get(i))).doit();
|
||||
NormalTime = System.currentTimeMillis() - NormalTime;
|
||||
System.out.print (" NormalTime :" + NormalTime);
|
||||
double frac = ((double)NormalTime)/((double)ProxyTime);
|
||||
System.out.println(" Number of Threads=" + a+ " frac = "+frac);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* This is the main method
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
MOCCOStandalone go = new MOCCOStandalone();
|
||||
if (args.length == 0) {
|
||||
// start GUI
|
||||
go.initMOCCOFrame();
|
||||
} else {
|
||||
String file = args[0];
|
||||
go.openObject(file);
|
||||
if (go.state == null) {
|
||||
System.out.println("No valid input state!");
|
||||
System.exit(0);
|
||||
} else {
|
||||
if (go.state.optimizer.getPopulation().getFunctionCalls() == 0) {
|
||||
// start to optimize
|
||||
go.startExperiment();
|
||||
file = file.replaceAll(".ser", "");
|
||||
go.saveObject(file + "_Finished.ser");
|
||||
} else {
|
||||
// start GUI
|
||||
go.initMOCCOFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods loads the current state of MOCO from a serialized file
|
||||
*
|
||||
* @param loadFrom The name of the serialized file
|
||||
* @return The new state of MOCO
|
||||
*/
|
||||
public Object openObject(String loadFrom) {
|
||||
File selected = new File(loadFrom);
|
||||
try {
|
||||
ObjectInputStream oi = new ObjectInputStream(new BufferedInputStream(new FileInputStream(selected)));
|
||||
Object obj = oi.readObject();
|
||||
oi.close();
|
||||
if (!(obj instanceof MOCCOState)) {
|
||||
throw new Exception("Object not of type MOCCOState");
|
||||
}
|
||||
return obj;
|
||||
} catch (Exception ex) {
|
||||
if (this.mainFrame != null) {
|
||||
JOptionPane.showMessageDialog(this.mainFrame, "Couldn't read object: " + selected.getName() + "\n" + ex.getMessage(), "Open object file", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
System.out.println("Couldn't read object: " + selected.getName() + "\n" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method saves the current MOCOData into a serialized file
|
||||
*
|
||||
* @param saveAs The name of the outputfile
|
||||
*/
|
||||
public void saveObject(String saveAs) {
|
||||
File sFile = new File(saveAs);
|
||||
try {
|
||||
ObjectOutputStream oo = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(sFile)));
|
||||
oo.writeObject(this.state);
|
||||
oo.close();
|
||||
} catch (Exception ex) {
|
||||
if (this.mainFrame != null) {
|
||||
JOptionPane.showMessageDialog(this.mainFrame, "Couldn't write to file: " + sFile.getName() + "\n" + ex.getMessage(), "Save object", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
System.out.println("Couldn't write to file: " + sFile.getName() + "\n" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* InterfaceStandaloneOptimization
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method starts the actual optimization procedure
|
||||
*/
|
||||
@Override
|
||||
public void startExperiment() {
|
||||
if (this.mainFrame != null) {
|
||||
}
|
||||
this.stillWorking = true;
|
||||
this.state.optimizer.setProblem(this.state.currentProblem);
|
||||
if (this.debug) {
|
||||
System.out.println("" + this.state.optimizer.getStringRepresentation());
|
||||
}
|
||||
this.state.currentProblem.evaluate(this.state.optimizer.getPopulation());
|
||||
this.state.optimizer.getPopulation().setFunctionCalls(0);
|
||||
if (this.state.optimizer.getPopulation().size() == 0) {
|
||||
this.state.optimizer.initialize();
|
||||
}
|
||||
this.state.optimizer.addPopulationChangedEventListener(this);
|
||||
worker = new eva2.gui.SwingWorker() {
|
||||
@Override
|
||||
public Object construct() {
|
||||
return doWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished() {
|
||||
Population[] pop = null;
|
||||
if (state.optimizer instanceof IslandModelEA) {
|
||||
InterfaceOptimizer[] opt = ((IslandModelEA) state.optimizer).getOptimizers();
|
||||
pop = new Population[opt.length];
|
||||
for (int i = 0; i < opt.length; i++) {
|
||||
pop[i] = opt[i].getPopulation();
|
||||
}
|
||||
}
|
||||
state.restore();
|
||||
if (pop == null) {
|
||||
state.addPopulation2History(state.optimizer.getPopulation());
|
||||
} else {
|
||||
for (int i = 0; i < pop.length; i++) {
|
||||
state.currentProblem.evaluate(pop[i]);
|
||||
state.addPopulation2History(pop[i]);
|
||||
}
|
||||
}
|
||||
if (view != null) {
|
||||
view.problemChanged(true);
|
||||
}
|
||||
stillWorking = false;
|
||||
}
|
||||
};
|
||||
worker.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* When the worker needs to update the GUI we do so by queuing
|
||||
* a Runnable for the event dispatching thread with
|
||||
* SwingUtilities.invokeLater(). In this case we're just
|
||||
* changing the progress bars value.
|
||||
*/
|
||||
void updateStatus(final String t, final int i) {
|
||||
if (this.progressBar != null) {
|
||||
Runnable doSetProgressBarValue = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setValue(i);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(doSetProgressBarValue);
|
||||
}
|
||||
this.currentState.setText(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method represents the application code that we'd like to
|
||||
* run on a separate thread. It simulates slowly computing
|
||||
* a value, in this case just a string 'All Done'. It updates the
|
||||
* progress bar every half second to remind the user that
|
||||
* we're still busy.
|
||||
*/
|
||||
Object doWork() {
|
||||
try {
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
while (!this.state.terminator.isTerminated(this.state.optimizer.getPopulation())) {
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
this.state.optimizer.optimize();
|
||||
}
|
||||
System.gc();
|
||||
} catch (InterruptedException e) {
|
||||
updateStatus("Interrupted", 0);
|
||||
return "Interrupted";
|
||||
}
|
||||
updateStatus("All Done", 0);
|
||||
return "All Done";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShow(boolean t) {
|
||||
// i guess this is not necessary in this environment
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* InterfacePopulationChangedEventListener
|
||||
*/
|
||||
/**
|
||||
* This method allows an optimizer to register a change in the optimizer.
|
||||
*
|
||||
* @param source The source of the event.
|
||||
* @param name Could be used to indicate the nature of the event.
|
||||
*/
|
||||
@Override
|
||||
public void registerPopulationStateChanged(Object source, String name) {
|
||||
int currentProgress;
|
||||
if (name.equals(Population.NEXT_GENERATION_PERFORMED)) {
|
||||
if (this.state.isVisible) {
|
||||
Population population = ((InterfaceOptimizer) source).getPopulation();
|
||||
double x = 100;
|
||||
if (this.state.terminator instanceof EvaluationTerminator) {
|
||||
double y = x / (double) ((EvaluationTerminator) this.state.terminator).getFitnessCalls();
|
||||
currentProgress = (int) (population.getFunctionCalls() * y);
|
||||
} else {
|
||||
currentProgress = 0;
|
||||
}
|
||||
updateStatus("Optimizing...", currentProgress);
|
||||
} else {
|
||||
// perhaps i could write it to file!?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JFrame getMainFrame() {
|
||||
return this.mainFrame;
|
||||
}
|
||||
}
|
||||
109
src/main/java/eva2/gui/Main.java
Normal file
109
src/main/java/eva2/gui/Main.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.tools.StringTools;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Main method, creates and sets up MainFrame
|
||||
*/
|
||||
public class Main {
|
||||
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
|
||||
|
||||
/**
|
||||
* The one and only main of the client program. Possible arguments:
|
||||
* --autorun: immediately starts the optimization (with parameters loaded
|
||||
* from current directory if available.
|
||||
* --nosplash: skip the splash screen.
|
||||
* --params: PFILE: load the optimization parameter from the serialized file PFILE
|
||||
*
|
||||
* @param args command line parameters
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// Properties for Mac OS X support.
|
||||
if ((System.getProperty("mrj.version") != null)
|
||||
|| (System.getProperty("os.name").toLowerCase().contains("mac"))) {
|
||||
/*
|
||||
* Note: the xDock name property must be set before parsing
|
||||
* command-line arguments! See above!
|
||||
*/
|
||||
System.setProperty("com.apple.mrj.application.apple.menu.about.name", EvAInfo.productName);
|
||||
System.setProperty("apple.awt.application.name", EvAInfo.productName);
|
||||
System.setProperty("apple.awt.graphics.EnableQ2DX", "true");
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
System.setProperty("com.apple.macos.smallTabs", "true");
|
||||
System.setProperty("com.apple.macos.useScreenMenuBar", "true");
|
||||
|
||||
System.setProperty("com.apple.mrj.application.growbox.intrudes", "false");
|
||||
System.setProperty("com.apple.mrj.application.live-resize", "true");
|
||||
}
|
||||
|
||||
/* Available command-line parameters */
|
||||
String[] keys = new String[]{
|
||||
"--help", "--autorun", "--nosplash", "--nogui", "--params", "--treeView"
|
||||
};
|
||||
/* Number of arguments per parameter */
|
||||
int[] arities = new int[]{0, 0, 0, 0, 1, 0};
|
||||
Object[] values = new Object[keys.length];
|
||||
|
||||
Integer[] unknownArgs = StringTools.parseArguments(args, keys, arities, values, true);
|
||||
|
||||
if (unknownArgs.length > 0) {
|
||||
LOGGER.warning("Unrecognized command line options: ");
|
||||
for (Integer unknownArg : unknownArgs) {
|
||||
System.err.println(" " + args[unknownArg]);
|
||||
}
|
||||
if (values[0] == null) {
|
||||
System.err.println("Try --help as argument.");
|
||||
}
|
||||
}
|
||||
|
||||
// Set up logging
|
||||
Logger rootLogger = Logger.getLogger("eva2");
|
||||
rootLogger.setLevel(Level.INFO);
|
||||
rootLogger.setUseParentHandlers(false);
|
||||
|
||||
if (values[0] != null) {
|
||||
System.out.println(usage());
|
||||
} else {
|
||||
boolean autorun = (values[1] != null);
|
||||
boolean nosplash = (values[2] != null);
|
||||
boolean nogui = (values[3] != null);
|
||||
boolean treeView = (values[5] != null);
|
||||
String paramsFile = StringTools.checkSingleStringArg(keys[4], values[4], arities[4] - 1);
|
||||
|
||||
new MainFrame(paramsFile, autorun, nosplash, nogui, treeView);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a readable usage string.
|
||||
*
|
||||
* @return Returns usage message
|
||||
*/
|
||||
public static String usage() {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
sbuf.append(EvAInfo.productName);
|
||||
sbuf.append(" - ");
|
||||
sbuf.append(EvAInfo.productLongName);
|
||||
sbuf.append(" - Version ");
|
||||
sbuf.append(EvAInfo.getVersion());
|
||||
sbuf.append("\n");
|
||||
sbuf.append("License: ");
|
||||
sbuf.append(EvAInfo.LGPLFile);
|
||||
sbuf.append("\n");
|
||||
sbuf.append("Homepage: ");
|
||||
sbuf.append(EvAInfo.url);
|
||||
sbuf.append("\n");
|
||||
sbuf.append("Command-line arguments:\n");
|
||||
sbuf.append(" --help: Show this text and exit\n");
|
||||
sbuf.append(" --nosplash: Deactivate splash screen\n");
|
||||
sbuf.append(" --nogui: Deactivate GUI (makes most sense with autorun and params set)\n");
|
||||
sbuf.append(" --autorun: Start an optimization immediately and exit after execution\n");
|
||||
sbuf.append(" --params PARAMFILE: Load the (serialized) parameters file on start\n");
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
872
src/main/java/eva2/gui/MainFrame.java
Normal file
872
src/main/java/eva2/gui/MainFrame.java
Normal file
@@ -0,0 +1,872 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.optimization.InterfaceOptimizationParameters;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.OptimizationStateListener;
|
||||
import eva2.optimization.modules.AbstractModuleAdapter;
|
||||
import eva2.optimization.modules.GenericModuleAdapter;
|
||||
import eva2.optimization.modules.ModuleAdapter;
|
||||
import eva2.optimization.modules.OptimizationModuleAdapter;
|
||||
import eva2.optimization.statistics.AbstractStatistics;
|
||||
import eva2.optimization.statistics.InterfaceStatisticsListener;
|
||||
import eva2.optimization.statistics.InterfaceStatisticsParameters;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
import eva2.tools.EVAERROR;
|
||||
import eva2.tools.ReflectPackage;
|
||||
import eva2.util.ClassPreloader;
|
||||
|
||||
import javax.help.HelpSet;
|
||||
import javax.help.JHelpContentViewer;
|
||||
import javax.help.JHelpNavigator;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MainFrame extends JFrame implements OptimizationStateListener {
|
||||
|
||||
/**
|
||||
* Generated serial version identifier.
|
||||
*/
|
||||
private static final long serialVersionUID = 8232856334379977970L;
|
||||
private final int splashScreenTime;
|
||||
private boolean clientInitialized = false;
|
||||
private JDesktopPane desktopPane;
|
||||
private JPanel configurationPane;
|
||||
private Runnable initRunnable = null;
|
||||
|
||||
private transient JProgressBar progressBar;
|
||||
|
||||
// Option
|
||||
private ExtAction actPreferences;
|
||||
private ExtAction actQuit;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(MainFrame.class.getName());
|
||||
|
||||
// Configurable module:
|
||||
private ModuleAdapter currentModuleAdapter = null;
|
||||
|
||||
// Help:
|
||||
private ExtAction actHelp;
|
||||
private ExtAction actAbout;
|
||||
private ExtAction actLicense;
|
||||
|
||||
// if not null, the module is loaded automatically and no other can be selected
|
||||
private String useDefaultModule = null; //"Genetic_Optimization";
|
||||
|
||||
|
||||
// measuring optimization runtime
|
||||
private long startTime = 0;
|
||||
private boolean withGUI = true;
|
||||
private boolean withTreeView = false;
|
||||
private TabbedFrameMaker frameMaker = null;
|
||||
private Window parentWindow;
|
||||
|
||||
private java.util.List<OptimizationStateListener> superListenerList = null;
|
||||
|
||||
|
||||
public void addOptimizationStateListener(OptimizationStateListener l) {
|
||||
if (superListenerList == null) {
|
||||
superListenerList = new ArrayList<>();
|
||||
}
|
||||
superListenerList.add(l);
|
||||
}
|
||||
|
||||
public boolean removeOptimizationStateListener(OptimizationStateListener l) {
|
||||
return superListenerList != null && superListenerList.remove(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of GUI of EvA2. Works as client for the EvA2 server. Note
|
||||
* that the Main initialized multi-threaded for efficiency. Use {@link #awaitClientInitialized()} }
|
||||
* to await full initialization if necessary.
|
||||
*/
|
||||
public MainFrame() {
|
||||
this(null, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor. Splash screen is optional, Gui is activated, no parent
|
||||
* window. Note that the Main initialized multi-threaded for
|
||||
* efficiency. Use {@link #awaitClientInitialized()} to await full
|
||||
* initialization if necessary.
|
||||
*
|
||||
* @param paramsFile
|
||||
* @param autorun
|
||||
* @param nosplash
|
||||
*/
|
||||
public MainFrame(final String paramsFile, boolean autorun, boolean nosplash) {
|
||||
this(null, paramsFile, null, autorun, nosplash, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor with optional spash screen. Note that the Main is
|
||||
* initialized multi-threaded for efficiency. Use {@link #awaitClientInitialized()}
|
||||
* to await full initialization if necessary.
|
||||
*
|
||||
* @param autorun
|
||||
* @param nosplash
|
||||
* @see #MainFrame(String, boolean, boolean)
|
||||
*/
|
||||
public MainFrame(boolean autorun, boolean nosplash) {
|
||||
this(null, autorun, nosplash);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor with optional splash screen. Note that the Main
|
||||
* initialized multi-threaded for efficiency. Use {@link #awaitClientInitialized()}
|
||||
* to await full initialization if necessary.
|
||||
*
|
||||
* @param paramsFile
|
||||
* @param autorun
|
||||
* @param noSplash
|
||||
* @param noGui
|
||||
* @see #MainFrame(boolean, boolean)
|
||||
*/
|
||||
public MainFrame(String paramsFile, boolean autorun, boolean noSplash, boolean noGui, boolean withTreeView) {
|
||||
this(null, paramsFile, null, autorun, noSplash, noGui, withTreeView);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor with optional splash screen. Note that the Main
|
||||
* initialized multi-threaded for efficiency. Use {@link #awaitClientInitialized()}
|
||||
* to await full initialization if necessary.
|
||||
*
|
||||
* @param optimizationParameters
|
||||
* @param autorun
|
||||
* @param noSplash
|
||||
* @param noGui
|
||||
* @see #MainFrame(String, boolean, boolean)
|
||||
*/
|
||||
public MainFrame(InterfaceOptimizationParameters optimizationParameters, boolean autorun, boolean noSplash, boolean noGui) {
|
||||
this(null, null, optimizationParameters, autorun, noSplash, noGui, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use the tree view by default.
|
||||
*
|
||||
* @param parent
|
||||
* @param paramsFile
|
||||
* @param goParams
|
||||
* @param autorun
|
||||
* @param noSplash
|
||||
* @param noGui
|
||||
*/
|
||||
public MainFrame(final Window parent, final String paramsFile, final InterfaceOptimizationParameters goParams, final boolean autorun, final boolean noSplash, final boolean noGui) {
|
||||
this(parent, paramsFile, goParams, autorun, noSplash, noGui, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main constructor of the EvA2 client GUI. Works as standalone version
|
||||
* locally or as client for the EvA2 server. GO parameters may be loaded
|
||||
* from a file (paramsFile) or given directly as a java instance. Both may
|
||||
* be null to start with standard parameters. If both are non null, the java
|
||||
* instance has the higher priority. Note that the Main initialized
|
||||
* multi-threaded for efficiency. Use {@link #awaitClientInitialized()} to
|
||||
* await full initialization if necessary.
|
||||
*
|
||||
* @param parent
|
||||
* @param paramsFile
|
||||
* @param autorun
|
||||
* @param noSplash
|
||||
* @param noGui
|
||||
*/
|
||||
public MainFrame(final Window parent, final String paramsFile, final InterfaceOptimizationParameters optimizationParameters, final boolean autorun, final boolean noSplash, final boolean noGui, final boolean showTreeView) {
|
||||
clientInitialized = false;
|
||||
final eva2.gui.SplashScreen splashScreen = new eva2.gui.SplashScreen(EvAInfo.splashLocation);
|
||||
|
||||
// preload some classes (into system cache) in a parallel thread
|
||||
preloadClasses();
|
||||
|
||||
withGUI = !noGui;
|
||||
withTreeView = showTreeView;
|
||||
// activate the splash screen (show later using SwingUtilities)
|
||||
if (!noSplash && withGUI) {
|
||||
try {
|
||||
splashScreen.splash();
|
||||
} catch (HeadlessException e) {
|
||||
LOGGER.severe("Error: no xserver present - deactivating GUI.");
|
||||
withGUI = false;
|
||||
}
|
||||
}
|
||||
|
||||
splashScreenTime = 2500;
|
||||
initRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (this) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
init(paramsFile, optimizationParameters, parent); // this takes a bit
|
||||
|
||||
long wait = System.currentTimeMillis() - startTime;
|
||||
LOGGER.info("Loaded EvA2 in " + wait + "ms.");
|
||||
if (!autorun) {
|
||||
if (!noSplash) {
|
||||
try {
|
||||
// if splashScreenTime has not passed, sleep some more
|
||||
if (wait < splashScreenTime) {
|
||||
Thread.sleep(splashScreenTime - wait);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!withGUI && (currentModuleAdapter instanceof GenericModuleAdapter)) {
|
||||
// do not save new parameters for an autorun without GUI - they weren't changed manually anyways.
|
||||
((GenericModuleAdapter) currentModuleAdapter).getStatistics().setSaveParams(false);
|
||||
LOGGER.info("Autorun without GUI - not saving statistics parameters...");
|
||||
}
|
||||
if (withGUI) {
|
||||
frameMaker.onUserStart();
|
||||
} else {
|
||||
currentModuleAdapter.startOptimization();
|
||||
}
|
||||
}
|
||||
// close splash screen
|
||||
if (!noSplash && withGUI) {
|
||||
splashScreen.dispose();
|
||||
}
|
||||
clientInitialized = true;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(initRunnable);
|
||||
}
|
||||
|
||||
private void initLookAndFeel() {
|
||||
// The native L&F on Linux looks horrible - don't set it.
|
||||
if (System.getProperty("os.name").equals("Linux")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Properties for Mac OS X support.
|
||||
if ((System.getProperty("mrj.version") != null)
|
||||
|| (System.getProperty("os.name").toLowerCase().contains("mac"))) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
|
||||
LOGGER.log(Level.INFO, "Could not set Look&Feel", ex);
|
||||
}
|
||||
} else {
|
||||
/* Set Look and Feel */
|
||||
try {
|
||||
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
|
||||
} catch (Exception ex) {
|
||||
LOGGER.log(Level.INFO, "Could not set Look&Feel", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the constructor runs multi-threaded for efficiency, this method may
|
||||
* be called to await the full initialization of a client instance. As soon
|
||||
* as it returns, the Main GUI is fully initialized.
|
||||
*/
|
||||
public void awaitClientInitialized() {
|
||||
if (initRunnable != null) {
|
||||
synchronized (initRunnable) {
|
||||
if (!clientInitialized) {
|
||||
try {
|
||||
initRunnable.wait();
|
||||
initRunnable = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void preloadClasses() {
|
||||
ClassPreloader cp = new ClassPreloader("eva2.optimization.strategies.InterfaceOptimizer", "eva2.problems.InterfaceOptimizationProblem", "eva2.optimization.operator.terminators.InterfaceTerminator");
|
||||
new Thread(cp).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to start the optimization with current parameters on the loaded
|
||||
* module. Return true on success, otherwise false.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean startOptimization() {
|
||||
if (currentModuleAdapter != null) {
|
||||
currentModuleAdapter.startOptimization();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set UI Font for all controls.
|
||||
*
|
||||
* @param fontResource The FontUIResource for the controls
|
||||
*/
|
||||
private static void setUIFont(javax.swing.plaf.FontUIResource fontResource) {
|
||||
Enumeration keys = UIManager.getDefaults().keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
Object key = keys.nextElement();
|
||||
Object value = UIManager.get(key);
|
||||
if (value != null && value instanceof javax.swing.plaf.FontUIResource) {
|
||||
UIManager.put(key, fontResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load OptimizationParameters from given file if not null.
|
||||
*/
|
||||
private void init(String paramsFile, InterfaceOptimizationParameters optimizationParameters, final Window parent) {
|
||||
useDefaultModule = EvAInfo.propDefaultModule();
|
||||
this.parentWindow = parent;
|
||||
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
setUIFont(new javax.swing.plaf.FontUIResource(Font.SANS_SERIF, 0, 11));
|
||||
|
||||
if (useDefaultModule != null) {
|
||||
useDefaultModule = useDefaultModule.trim();
|
||||
if (useDefaultModule.length() < 1) {
|
||||
useDefaultModule = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (withGUI) {
|
||||
// Initialize look and feel for EvA2
|
||||
initLookAndFeel();
|
||||
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
|
||||
/* Create main frame with GridBagLayout */
|
||||
setTitle(EvAInfo.productName);
|
||||
setLayout(new GridBagLayout());
|
||||
setMinimumSize(new Dimension(1024, 800));
|
||||
|
||||
/* Creates the desktopPane for Plot/Text Output */
|
||||
desktopPane = new JExtDesktopPane();
|
||||
JEFrameRegister.getInstance().setDesktopPane(desktopPane);
|
||||
/* Creates desktopPane ToolBar to show tiling buttons */
|
||||
JExtDesktopPaneToolBar desktopToolBar = new JExtDesktopPaneToolBar((JExtDesktopPane) desktopPane);
|
||||
|
||||
/* Pane to hold ToolBar + DesktopPane */
|
||||
JPanel desktopPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints desktopConst = new GridBagConstraints();
|
||||
desktopConst.gridx = 0;
|
||||
desktopConst.gridy = 0;
|
||||
desktopConst.fill = GridBagConstraints.HORIZONTAL;
|
||||
desktopConst.weightx = 1.0;
|
||||
desktopPanel.add(desktopToolBar, desktopConst);
|
||||
desktopConst.gridy = 1;
|
||||
desktopConst.fill = GridBagConstraints.BOTH;
|
||||
desktopConst.weighty = 1.0;
|
||||
desktopPanel.add(desktopPane, desktopConst);
|
||||
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(EvAInfo.iconLocation, true);
|
||||
// TODO: use setIconImages (for better support of multiple icons when changing programs etc.)
|
||||
setIconImage(Toolkit.getDefaultToolkit().createImage(bytes));
|
||||
|
||||
LoggingPanel logPanel = new LoggingPanel();
|
||||
logPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
createActions();
|
||||
|
||||
setSize(1024, 800);
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
setLocation((screenSize.width - this.getWidth()) / 2, (int) ((screenSize.height - this.getHeight()) / 2.5));
|
||||
|
||||
/* Create a new ConfigurationPanel (left side) */
|
||||
configurationPane = new JPanel(new GridBagLayout());
|
||||
gbConstraints.ipadx = 5;
|
||||
gbConstraints.weightx = 0.0;
|
||||
gbConstraints.weighty = 1.0;
|
||||
/* Set configurationPane at 0,1 */
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 1;
|
||||
gbConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
gbConstraints.gridwidth = GridBagConstraints.RELATIVE;
|
||||
gbConstraints.gridheight = GridBagConstraints.RELATIVE;
|
||||
add(configurationPane, gbConstraints);
|
||||
|
||||
/* SplitPane for desktopPanel and loggingPanel */
|
||||
JSplitPane horizontalSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
|
||||
horizontalSplit.setTopComponent(desktopPanel);
|
||||
horizontalSplit.setBottomComponent(logPanel);
|
||||
horizontalSplit.setDividerSize(8);
|
||||
horizontalSplit.setOneTouchExpandable(true);
|
||||
horizontalSplit.setResizeWeight(1.0);
|
||||
horizontalSplit.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
|
||||
horizontalSplit.setContinuousLayout(true);
|
||||
|
||||
horizontalSplit.setDividerLocation(0.25);
|
||||
/* Add horizontal split pane at 1,1 */
|
||||
gbConstraints.gridx = 1;
|
||||
gbConstraints.gridy = 1;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
|
||||
gbConstraints.gridheight = GridBagConstraints.RELATIVE;
|
||||
add(horizontalSplit, gbConstraints);
|
||||
|
||||
/* StatusBar of the main frame */
|
||||
JPanel statusBar = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
JPanel statusBarControls = new JPanel();
|
||||
statusBarControls.setLayout(new BoxLayout(statusBarControls, BoxLayout.LINE_AXIS));
|
||||
|
||||
statusBarControls.add(Box.createHorizontalGlue());
|
||||
|
||||
/* Set default logging level to INFO */
|
||||
Logger.getLogger("eva2").setLevel(Level.INFO);
|
||||
/* Logging settings drop down */
|
||||
LoggingLevelLabel loggingOption = new LoggingLevelLabel();
|
||||
|
||||
statusBarControls.add(loggingOption);
|
||||
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
statusBarControls.add(new JSeparator(JSeparator.VERTICAL));
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
|
||||
/* Create ProgressBar and add it to the status bar */
|
||||
statusBarControls.add(new JLabel("Progress"));
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setValue(0);
|
||||
progressBar.setStringPainted(true);
|
||||
statusBarControls.add(progressBar);
|
||||
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
statusBarControls.add(new JSeparator(JSeparator.VERTICAL));
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
/* Create ProgressBar and add it to the status bar */
|
||||
statusBarControls.add(new JLabel("CPU"));
|
||||
statusBarControls.add(Box.createHorizontalStrut(5));
|
||||
statusBarControls.add(new CPUPanel(100));
|
||||
|
||||
statusBar.add(statusBarControls);
|
||||
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 2;
|
||||
gbConstraints.gridwidth = 2;
|
||||
gbConstraints.weighty = 0.0;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.anchor = GridBagConstraints.PAGE_END;
|
||||
add(statusBar, gbConstraints);
|
||||
}
|
||||
|
||||
if (useDefaultModule != null) {
|
||||
/*
|
||||
* if optimizationParameters are not defined and a params file is defined
|
||||
* try to load parameters from file
|
||||
*/
|
||||
if (optimizationParameters == null && (paramsFile != null && (paramsFile.length() > 0))) {
|
||||
optimizationParameters = OptimizationParameters.getInstance(paramsFile, false);
|
||||
}
|
||||
loadSpecificModule(useDefaultModule, optimizationParameters);//loadSpecificModule
|
||||
}
|
||||
|
||||
if (withGUI) {
|
||||
buildMenu();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
|
||||
@Override
|
||||
public void windowClosing(final WindowEvent event) {
|
||||
int result = JOptionPane.showConfirmDialog(
|
||||
MainFrame.this,
|
||||
"Do you really want to exit EvA2?",
|
||||
"Exit Application",
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
MainFrame.this.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
LOGGER.log(Level.INFO, "Working directory is: {0}", System.getProperty("user.dir"));
|
||||
LOGGER.log(Level.FINE, "Class path is: {0}", System.getProperty("java.class.path", "."));
|
||||
|
||||
if (!(configurationPane.isVisible())) {
|
||||
configurationPane.setVisible(true);
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
|
||||
// if this message is omitted, the stupid scroll pane runs to
|
||||
// the end of the last line which is ugly for a long class path
|
||||
LOGGER.info("EvA2 ready");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes EvA2 workbench. Will not kill the JVM iff
|
||||
* the MATLAB environment variable has been set.
|
||||
*/
|
||||
public void close() {
|
||||
LOGGER.info("Closing EvA2 Client. Bye!");
|
||||
Set<String> keys = System.getenv().keySet();
|
||||
if (keys.contains("MATLAB")) {
|
||||
LOGGER.info("EvA2 workbench has been started from Matlab: not killing JVM");
|
||||
} else {
|
||||
if (parentWindow == null) {
|
||||
System.exit(1);
|
||||
} else {
|
||||
this.setVisible(false);
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the parameter panels (if settings have been changed outside of
|
||||
* the GUI which should be updated in the GUI.
|
||||
*/
|
||||
public void refreshMainPanels() {
|
||||
frameMaker.refreshPanels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the client GUI with given parameters and set listeners. This
|
||||
* will return as soon as the GUI is visible and ready.
|
||||
*
|
||||
* @param goParams optimization parameters
|
||||
* @param statisticsListener statistics listener receiving data during
|
||||
* optimization
|
||||
* @param windowListener additional window listener for client frame
|
||||
*/
|
||||
public static MainFrame initClientGUI(OptimizationParameters goParams,
|
||||
InterfaceStatisticsListener statisticsListener,
|
||||
WindowListener windowListener, final Window parent) {
|
||||
MainFrame evaClient;
|
||||
|
||||
evaClient = new MainFrame(parent, null, goParams,
|
||||
false, true, false, false); // initializes GUI in the background
|
||||
// important: wait for GUI initialization before accessing any internal
|
||||
// settings:
|
||||
evaClient.awaitClientInitialized(); // this returns as soon as the
|
||||
// GUI is ready
|
||||
evaClient.addWindowListener(windowListener);
|
||||
// modify initial settings and activate output of all data:
|
||||
evaClient.getStatistics().getStatisticsParameters().setOutputAllFieldsAsText(true);
|
||||
// add a data listener instance:
|
||||
evaClient.getStatistics().addDataListener(statisticsListener);
|
||||
|
||||
// GUI update due to the changes made through the API
|
||||
evaClient.refreshMainPanels();
|
||||
|
||||
return evaClient;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void createActions() {
|
||||
|
||||
actAbout = new ExtAction("&About", "Product Information") {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
LOGGER.info(event.getActionCommand());
|
||||
showAboutDialog();
|
||||
}
|
||||
};
|
||||
actLicense = new ExtAction("&License", "View License") {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
LOGGER.info(event.getActionCommand());
|
||||
showLicense();
|
||||
}
|
||||
};
|
||||
|
||||
actQuit = new ExtAction("&Quit", "Quit EvA2 workbench",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
int result = JOptionPane.showConfirmDialog(
|
||||
MainFrame.this,
|
||||
"Do you really want to exit EvA2?",
|
||||
"Exit Application",
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
MainFrame.this.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
actPreferences = new ExtAction("&Preferences", "Show preferences dialog",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_MASK)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
// ToDo
|
||||
}
|
||||
};
|
||||
|
||||
actHelp = new ExtAction("&Help", "Show help contents",
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
// ToDo
|
||||
String helpHS = "EvA2Help/EvA2Help.hs";
|
||||
ClassLoader cl = MainFrame.class.getClassLoader();
|
||||
JHelpContentViewer helpPane;
|
||||
try {
|
||||
URL hsURL = HelpSet.findHelpSet(cl, helpHS);
|
||||
HelpSet helpSet = new HelpSet(null, hsURL);
|
||||
// Trigger the help viewer:
|
||||
helpPane = new JHelpContentViewer(helpSet);
|
||||
JHelpNavigator helpNavigator = (JHelpNavigator) helpSet.getNavigatorView("TOC").createNavigator(helpPane.getModel());
|
||||
JEFrame helpFrame = new JEFrame("Help contents");
|
||||
JSplitPane helpSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, helpNavigator, helpPane);
|
||||
helpFrame.add(helpSplit);
|
||||
helpFrame.setVisible(true);
|
||||
helpFrame.setMaximum(true);
|
||||
} catch (Exception ee) {
|
||||
// Say what the exception really is
|
||||
LOGGER.log(Level.WARNING, "Could not open application help", ee);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the main menu and add actions.
|
||||
*/
|
||||
private void buildMenu() {
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
setJMenuBar(menuBar);
|
||||
|
||||
JExtMenu menuHelp = new JExtMenu("&Help");
|
||||
menuHelp.add(actHelp);
|
||||
menuHelp.addSeparator();
|
||||
menuHelp.add(actAbout);
|
||||
menuHelp.add(actLicense);
|
||||
|
||||
JExtMenu menuOptions = new JExtMenu("&Options");
|
||||
menuOptions.add(actPreferences);
|
||||
menuOptions.addSeparator();
|
||||
menuOptions.add(actQuit);
|
||||
|
||||
menuBar.add(menuOptions);
|
||||
menuBar.add(((JExtDesktopPane) desktopPane).getWindowMenu());
|
||||
menuBar.add(menuHelp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the optimization parameters of a loaded module. Return null if no module is
|
||||
* loaded.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public InterfaceOptimizationParameters getOptimizationParameters() {
|
||||
if (currentModuleAdapter != null) {
|
||||
if (currentModuleAdapter instanceof AbstractModuleAdapter) {
|
||||
return ((AbstractModuleAdapter) currentModuleAdapter).getOptimizationParameters();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AbstractStatistics getStatistics() {
|
||||
return ((GenericModuleAdapter) currentModuleAdapter).getStatistics();
|
||||
}
|
||||
|
||||
public InterfaceStatisticsParameters getStatisticsParameter() {
|
||||
return ((GenericModuleAdapter) currentModuleAdapter).getStatistics().getStatisticsParameters();
|
||||
}
|
||||
|
||||
private void loadSpecificModule(String selectedModule, InterfaceOptimizationParameters optimizationParameters) {
|
||||
ModuleAdapter newModuleAdapter = null;
|
||||
//
|
||||
try {
|
||||
InterfaceOptimizationParameters params = optimizationParameters;
|
||||
if (optimizationParameters == null) {
|
||||
params = OptimizationParameters.getInstance();
|
||||
}
|
||||
newModuleAdapter = new OptimizationModuleAdapter(selectedModule, params, withGUI ? null : "EvA2");
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.SEVERE, "Error loading module.", e);
|
||||
EVAERROR.EXIT("Error while comAdapter.GetModuleAdapter Host: " + e.getMessage());
|
||||
}
|
||||
if (newModuleAdapter == null) {
|
||||
// When launching a Java Web Start application, baseDir will always be null!
|
||||
URL baseDir = getClass().getClassLoader().getResource("");
|
||||
String cp = System.getProperty("java.class.path", ".");
|
||||
String dir = (baseDir == null) ? System.getProperty("user.dir") : baseDir.getPath();
|
||||
|
||||
if (!cp.contains(dir)) {
|
||||
// this was added due to matlab not adding base dir to base path...
|
||||
System.err.println("classpath does not contain base directory!");
|
||||
System.err.println("adding base dir and trying again...");
|
||||
System.setProperty("java.class.path", cp + System.getProperty("path.separator") + dir);
|
||||
ReflectPackage.resetDynCP();
|
||||
loadSpecificModule(selectedModule, optimizationParameters); // end recursive call! handle with care!
|
||||
}
|
||||
} else {
|
||||
newModuleAdapter.addOptimizationStateListener(this);
|
||||
try {
|
||||
if (withGUI) {
|
||||
// this (or rather: ModuleButtonPanelMaker) is where the start button etc come from!
|
||||
frameMaker = newModuleAdapter.getModuleFrame();
|
||||
|
||||
/* This is the left TabPane on the main frame */
|
||||
JPanel moduleContainer = frameMaker.makePanel();
|
||||
|
||||
configurationPane.setVisible(false);
|
||||
configurationPane.removeAll();
|
||||
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
|
||||
/* ToDo: Find a way to properly add the TreeView to the GOPanel */
|
||||
if (false && (newModuleAdapter instanceof AbstractModuleAdapter)) {
|
||||
JComponent tree = null;
|
||||
tree = getEvATreeView(frameMaker.getOptimizationParametersPanel(), "OptimizationParameters", ((AbstractModuleAdapter) newModuleAdapter).getOptimizationParameters());
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 1.0;
|
||||
configurationPane.add(tree, gbConstraints);
|
||||
}
|
||||
|
||||
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 0.0;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
gbConstraints.gridwidth = 2;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.anchor = GridBagConstraints.PAGE_START;
|
||||
add(frameMaker.getToolBar(), gbConstraints);
|
||||
|
||||
GridBagConstraints gbConstraints2 = new GridBagConstraints();
|
||||
gbConstraints2.gridx = 0;
|
||||
gbConstraints2.gridy = 0;
|
||||
gbConstraints2.fill = GridBagConstraints.VERTICAL;
|
||||
gbConstraints2.weighty = 1.0;
|
||||
configurationPane.add(moduleContainer, gbConstraints2);
|
||||
configurationPane.validate();
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.SEVERE, "Error while newModuleAdapter.getModuleFrame(): " + e.getMessage(), e);
|
||||
EVAERROR.EXIT("Error while newModuleAdapter.getModuleFrame(): " + e.getMessage());
|
||||
}
|
||||
|
||||
currentModuleAdapter = newModuleAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tree view of an object based on TreeNode. It is encapsulated
|
||||
* in a JScrollPane.
|
||||
*
|
||||
* @param goPanel
|
||||
* @param title
|
||||
* @param object
|
||||
* @return
|
||||
* @see TreeNode
|
||||
*/
|
||||
public JComponent getEvATreeView(JParaPanel goPanel, String title, Object object) {
|
||||
TreeNode root = new TreeNode(title, object); // the root of the tree
|
||||
JTree jtree = new JTree(root);
|
||||
JScrollPane treeView = new JScrollPane(jtree);
|
||||
|
||||
TreeSelectionListener treeListener = new TreeSelectionListener(root, goPanel.getEditor(), jtree);
|
||||
// hooks itself up as the tree listener. It reacts both to changes in the selection
|
||||
// state of the tree (to update the parameter panel) and to changes in the
|
||||
// parameters to update the tree
|
||||
return treeView;
|
||||
}
|
||||
|
||||
private void showAboutDialog() {
|
||||
AboutDialog aboutDialog = new AboutDialog(this);
|
||||
aboutDialog.setLocationRelativeTo(this);
|
||||
aboutDialog.setVisible(true);
|
||||
aboutDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
|
||||
}
|
||||
|
||||
private void showLicense() {
|
||||
HtmlDemo lgpl = new HtmlDemo(EvAInfo.LGPLFile);
|
||||
HtmlDemo gpl = new HtmlDemo(EvAInfo.GPLFile);
|
||||
gpl.show();
|
||||
lgpl.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedRestart(String infoString) {
|
||||
if (superListenerList != null) {
|
||||
for (OptimizationStateListener l : superListenerList) {
|
||||
l.performedRestart(infoString);
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.INFO, "Restarted processing {0}", infoString);
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedStart(String infoString) {
|
||||
if (superListenerList != null) {
|
||||
for (OptimizationStateListener l : superListenerList) {
|
||||
l.performedStart(infoString);
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.INFO, "Started processing {0}", infoString);
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedStop() {
|
||||
if (superListenerList != null) {
|
||||
for (OptimizationStateListener l : superListenerList) {
|
||||
l.performedStop();
|
||||
}
|
||||
}
|
||||
long t = (System.currentTimeMillis() - startTime);
|
||||
LOGGER.info(String.format("Stopped after %1$d.%2$tL s", (t / 1000), (t % 1000)));
|
||||
if (!withGUI) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the worker needs to update the GUI we do so by queuing a Runnable
|
||||
* for the event dispatching thread with SwingUtilities.invokeLater(). In
|
||||
* this case we're just changing the progress bars value.
|
||||
*/
|
||||
@Override
|
||||
public void updateProgress(final int percent, String msg) {
|
||||
if (superListenerList != null) {
|
||||
for (OptimizationStateListener l : superListenerList) {
|
||||
l.updateProgress(percent, msg);
|
||||
}
|
||||
}
|
||||
if (msg != null) {
|
||||
LOGGER.info(msg);
|
||||
}
|
||||
if (this.progressBar != null) {
|
||||
Runnable doSetProgressBarValue = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setValue(percent);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(doSetProgressBarValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/main/java/eva2/gui/Mnemonic.java
Normal file
48
src/main/java/eva2/gui/Mnemonic.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Mnemonic {
|
||||
|
||||
private char mnemonic;
|
||||
private String text;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Mnemonic(String s) {
|
||||
setString(s);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setString(String s) {
|
||||
StringBuilder buf = new StringBuilder(s);
|
||||
for (int i = 0; i < buf.length(); i++) {
|
||||
if (buf.charAt(i) == '&') {
|
||||
buf.deleteCharAt(i);
|
||||
i++;
|
||||
if (i < buf.length() && buf.charAt(i) != '&') {
|
||||
mnemonic = buf.charAt(i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
text = buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public char getMnemonic() {
|
||||
return mnemonic;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
214
src/main/java/eva2/gui/ModuleButtonPanelMaker.java
Normal file
214
src/main/java/eva2/gui/ModuleButtonPanelMaker.java
Normal file
@@ -0,0 +1,214 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.OptimizationStateListener;
|
||||
import eva2.optimization.modules.ModuleAdapter;
|
||||
import eva2.optimization.statistics.OptimizationJob;
|
||||
import eva2.tools.ToolBoxGui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.Serializable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Contains the GUI elements of start and stop buttons and optionally a help
|
||||
* button.
|
||||
*/
|
||||
public class ModuleButtonPanelMaker implements OptimizationStateListener, Serializable, PanelMaker {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ModuleButtonPanelMaker.class.getName());
|
||||
private String name = "undefined";
|
||||
private ModuleAdapter moduleAdapter;
|
||||
private boolean runningState;
|
||||
private JButton runButton;
|
||||
private JButton postProcessButton;
|
||||
private JButton stopButton;
|
||||
private JButton scheduleButton;
|
||||
private JButton helpButton;
|
||||
private JToolBar toolBar;
|
||||
private String helpFileName;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ModuleButtonPanelMaker(ModuleAdapter adapter, boolean state) {
|
||||
name = "GENERAL";
|
||||
runningState = state;
|
||||
moduleAdapter = adapter;
|
||||
|
||||
toolBar = new JToolBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JToolBar makePanel() {
|
||||
toolBar.setFloatable(false);
|
||||
|
||||
moduleAdapter.addOptimizationStateListener(this);
|
||||
|
||||
runButton = ToolBoxGui.createIconifiedButton("images/Play24.gif", "Start", true);
|
||||
runButton.setToolTipText("Start the current optimization run.");
|
||||
|
||||
runButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
//Run Opt pressed !
|
||||
onUserStart();
|
||||
}
|
||||
});
|
||||
|
||||
runButton.setEnabled(!runningState); // enabled if not running
|
||||
|
||||
toolBar.add(runButton);
|
||||
|
||||
stopButton = ToolBoxGui.createIconifiedButton("images/Stop24.gif", "Stop", true);
|
||||
stopButton.setToolTipText("Stop the current optimization run.");
|
||||
stopButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
try {
|
||||
// this means user break
|
||||
moduleAdapter.stopOptimization();
|
||||
} catch (Exception ee) {
|
||||
LOGGER.log(Level.WARNING, "Error while stopping job.", ee);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
stopButton.setEnabled(runningState);
|
||||
toolBar.add(stopButton);
|
||||
|
||||
postProcessButton = ToolBoxGui.createIconifiedButton("images/History24.gif", "Post Process", true);
|
||||
postProcessButton.setToolTipText("Start post processing according to available parameters.");
|
||||
//postProcessButton.setBorderPainted(false);
|
||||
postProcessButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
try {
|
||||
if (!moduleAdapter.startPostProcessing()) {
|
||||
JOptionPane.showMessageDialog(null, "Post processing seems deactivated! Check the settings.", "Warning", JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
LOGGER.log(Level.WARNING, "Error in run", ee);
|
||||
}
|
||||
}
|
||||
});
|
||||
postProcessButton.setEnabled(runningState && moduleAdapter.hasPostProcessing());
|
||||
toolBar.add(postProcessButton);
|
||||
|
||||
scheduleButton = ToolBoxGui.createIconifiedButton("images/Server24.gif", "Schedule", true);
|
||||
scheduleButton.setToolTipText("Schedule the currently configured optimization as a job.");
|
||||
scheduleButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
OptimizationJob job = moduleAdapter.scheduleJob();
|
||||
if (job == null) {
|
||||
LOGGER.log(Level.WARNING, "There was an error on scheduling your job");
|
||||
}
|
||||
}
|
||||
});
|
||||
scheduleButton.setEnabled(true);
|
||||
toolBar.add(scheduleButton);
|
||||
|
||||
makeHelpButton();
|
||||
|
||||
return toolBar;
|
||||
}
|
||||
|
||||
public void onUserStart() {
|
||||
try {
|
||||
moduleAdapter.startOptimization();
|
||||
stopButton.setEnabled(true);
|
||||
runButton.setEnabled(false);
|
||||
postProcessButton.setEnabled(false);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.err.print("Error in run: " + ex + " : " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void makeHelpButton() {
|
||||
if (helpFileName != null && (!helpFileName.equals(""))) {
|
||||
helpButton = new JButton("Description");
|
||||
helpButton.setToolTipText("Description of the current optimization algorithm.");
|
||||
helpButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
if (helpFileName != null) {
|
||||
HtmlDemo temp = new HtmlDemo(helpFileName);
|
||||
temp.show();
|
||||
}
|
||||
helpButton.setEnabled(true);
|
||||
} catch (Exception ee) {
|
||||
ee.printStackTrace();
|
||||
System.out.print("Error in run: " + ee + " : " + ee.getMessage());
|
||||
}
|
||||
}
|
||||
});
|
||||
toolBar.add(helpButton);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void performedStop() {
|
||||
runButton.setEnabled(true);
|
||||
postProcessButton.setEnabled(true);
|
||||
runButton.repaint();
|
||||
stopButton.setEnabled(false);
|
||||
toolBar.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedStart(String infoString) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performedRestart(String infoString) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(final int percent, String msg) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setHelperFilename(String fileName) {
|
||||
if ((fileName == null) && (fileName.equals(helpFileName))) {
|
||||
return; // both are null, do nothing
|
||||
}
|
||||
if (fileName != null) {
|
||||
if (helpFileName == null) {
|
||||
// only old is null, nothing to be removed
|
||||
helpFileName = fileName;
|
||||
makeHelpButton();
|
||||
} else {
|
||||
if (!helpFileName.equals(fileName)) {
|
||||
toolBar.remove(helpButton);
|
||||
helpFileName = fileName;
|
||||
makeHelpButton();
|
||||
} //else // both are equal, do nothing
|
||||
}
|
||||
} else { // s is null, so just remove
|
||||
toolBar.remove(helpButton);
|
||||
helpFileName = fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/main/java/eva2/gui/MultiLineString.java
Normal file
27
src/main/java/eva2/gui/MultiLineString.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
* @author not attributable
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class MultiLineString {
|
||||
|
||||
public String string = "";
|
||||
|
||||
public MultiLineString() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MultiLineString multiLineString1 = new MultiLineString();
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
public void setString(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
}
|
||||
484
src/main/java/eva2/gui/OptimizationEditorPanel.java
Normal file
484
src/main/java/eva2/gui/OptimizationEditorPanel.java
Normal file
@@ -0,0 +1,484 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.gui.editor.GenericObjectEditor;
|
||||
import eva2.optimization.tools.FileTools;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
import eva2.tools.SerializedObject;
|
||||
import eva2.tools.StringTools;
|
||||
import eva2.util.annotation.Description;
|
||||
import eva2.yaml.BeanSerializer;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class OptimizationEditorPanel extends JPanel implements ItemListener {
|
||||
private static final Logger LOGGER = Logger.getLogger(OptimizationEditorPanel.class.getName());
|
||||
|
||||
private Object backupObject;
|
||||
private PropertyChangeSupport propChangeSupport;
|
||||
/**
|
||||
* The chooser component
|
||||
*/
|
||||
private JComboBox objectChooser;
|
||||
/**
|
||||
* The component that performs classifier customization
|
||||
*/
|
||||
private PropertySheetPanel propertySheetPanel;
|
||||
/**
|
||||
* The model containing the list of names to select from
|
||||
*/
|
||||
private DefaultComboBoxModel comboBoxModel;
|
||||
/**
|
||||
* Open object from disk
|
||||
*/
|
||||
private JButton openButton;
|
||||
/**
|
||||
* Save object to disk
|
||||
*/
|
||||
private JButton saveButton;
|
||||
/**
|
||||
* ok button
|
||||
*/
|
||||
private JButton okayButton;
|
||||
/**
|
||||
* cancel button
|
||||
*/
|
||||
private JButton cancelButton;
|
||||
/**
|
||||
* Creates the GUI editor component
|
||||
*/
|
||||
private GenericObjectEditor genericObjectEditor = null;
|
||||
private int tipMaxLen = 100; // maximum length of tool tip
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public OptimizationEditorPanel(Object target, Object backup, PropertyChangeSupport support, GenericObjectEditor goe) {
|
||||
this(target, backup, support, goe, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public OptimizationEditorPanel(Object target, Object backup, PropertyChangeSupport support, GenericObjectEditor goe, boolean withCancel) {
|
||||
backupObject = backup;
|
||||
propChangeSupport = support;
|
||||
genericObjectEditor = goe;
|
||||
|
||||
try {
|
||||
if (!(Proxy.isProxyClass(target.getClass()))) {
|
||||
backupObject = copyObject(target);
|
||||
}
|
||||
} catch (OutOfMemoryError err) {
|
||||
backupObject = null;
|
||||
System.gc();
|
||||
System.err.println("Could not create backup object: not enough memory (OptimizationEditorPanel backup of " + target + ")");
|
||||
}
|
||||
comboBoxModel = new DefaultComboBoxModel(new Vector<Item>());
|
||||
objectChooser = new JComboBox(comboBoxModel);
|
||||
objectChooser.setEditable(false);
|
||||
propertySheetPanel = new PropertySheetPanel();
|
||||
propertySheetPanel.addPropertyChangeListener(
|
||||
new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
propChangeSupport.firePropertyChange("", backupObject, genericObjectEditor.getValue());
|
||||
}
|
||||
});
|
||||
openButton = makeIconButton("images/Open16.gif", "Open");
|
||||
openButton.setToolTipText("Load a configured object");
|
||||
openButton.setEnabled(true);
|
||||
openButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
FileFilter filter = new FileNameExtensionFilter("YAML file", "yml", "yaml");
|
||||
Object object = FileTools.openObject(openButton, genericObjectEditor.getClassType(), filter);
|
||||
if (object != null) {
|
||||
// setValue takes care of: Making sure obj is of right type,
|
||||
// and firing property change.
|
||||
genericObjectEditor.setValue(object);
|
||||
// Need a second setValue to get property values filled in OK.
|
||||
// Not sure why.
|
||||
genericObjectEditor.setValue(object); // <- Hannes ?!?!?
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
saveButton = makeIconButton("images/Save16.gif", "Save");
|
||||
saveButton.setToolTipText("Save the current configured object");
|
||||
saveButton.setEnabled(true);
|
||||
saveButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
FileFilter filter = new FileNameExtensionFilter("YAML file", "yml", "yaml");
|
||||
FileTools.saveObjectWithFileChooser(saveButton, BeanSerializer.serializeObject(genericObjectEditor.getValue()), filter);
|
||||
}
|
||||
});
|
||||
|
||||
okayButton = new JButton("OK");
|
||||
okayButton.setEnabled(true);
|
||||
okayButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
//backupObject = copyObject(genericObjectEditor.getValue());
|
||||
|
||||
updateClassType();
|
||||
updateChildPropertySheet();
|
||||
|
||||
/*
|
||||
* ToDo: This is really ugly. Find a way to make this better.
|
||||
*/
|
||||
Container container = OptimizationEditorPanel.this.getParent();
|
||||
while (!(container instanceof JDialog)) {
|
||||
container = container.getParent();
|
||||
}
|
||||
((JDialog) container).dispose();
|
||||
}
|
||||
});
|
||||
|
||||
cancelButton = new JButton("Cancel");
|
||||
cancelButton.setEnabled(true);
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
if (backupObject != null) {
|
||||
genericObjectEditor.setValue(copyObject(backupObject));
|
||||
updateClassType();
|
||||
updateChooser();
|
||||
updateChildPropertySheet();
|
||||
}
|
||||
/*
|
||||
* ToDo: This is really ugly. Find a way to make this better.
|
||||
*/
|
||||
Container container = OptimizationEditorPanel.this.getParent();
|
||||
while (!(container instanceof JDialog)) {
|
||||
container = container.getParent();
|
||||
}
|
||||
((JDialog) container).dispose();
|
||||
}
|
||||
});
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
add(objectChooser, gbConstraints);
|
||||
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 1.0;
|
||||
gbConstraints.gridy = 1;
|
||||
gbConstraints.gridheight = GridBagConstraints.RELATIVE;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
add(propertySheetPanel, gbConstraints);
|
||||
|
||||
JToolBar buttonBar = new JToolBar();
|
||||
buttonBar.setRollover(true);
|
||||
buttonBar.setFloatable(false);
|
||||
buttonBar.add(openButton);
|
||||
buttonBar.add(saveButton);
|
||||
|
||||
/* Add spacer to the end of the line */
|
||||
buttonBar.add(Box.createHorizontalGlue());
|
||||
|
||||
if (withCancel) {
|
||||
buttonBar.add(cancelButton);
|
||||
}
|
||||
buttonBar.add(okayButton);
|
||||
|
||||
gbConstraints.weightx = 0.0;
|
||||
gbConstraints.weighty = 0.0;
|
||||
gbConstraints.gridy = 2;
|
||||
gbConstraints.anchor = GridBagConstraints.LINE_START;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
add(buttonBar, gbConstraints);
|
||||
|
||||
if (genericObjectEditor.getClassType() != null) {
|
||||
updateClassType();
|
||||
updateChooser();
|
||||
updateChildPropertySheet();
|
||||
}
|
||||
objectChooser.addItemListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is duplicated from ModuleButtonPanelMaker. ToDo: Refactor
|
||||
* this.
|
||||
*
|
||||
* @param iconSrc Source path of icon
|
||||
* @param title Title of button
|
||||
* @return A JButton with the title and icon
|
||||
*/
|
||||
private JButton makeIconButton(final String iconSrc, final String title) {
|
||||
JButton newButton;
|
||||
byte[] bytes;
|
||||
bytes = BasicResourceLoader.getInstance().getBytesFromResourceLocation(iconSrc, false);
|
||||
if (bytes == null) {
|
||||
newButton = new JButton(title);
|
||||
} else {
|
||||
newButton = new JButton(new ImageIcon(Toolkit.getDefaultToolkit().createImage(bytes)));
|
||||
}
|
||||
return newButton;
|
||||
}
|
||||
|
||||
public void setEnabledOkCancelButtons(boolean enabled) {
|
||||
okayButton.setEnabled(enabled);
|
||||
okayButton.setVisible(enabled);
|
||||
cancelButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of an object using serialization.
|
||||
*
|
||||
* @param source the object to copy
|
||||
* @return a copy of the source object
|
||||
*/
|
||||
protected Object copyObject(Object source) {
|
||||
Object result = null;
|
||||
try {
|
||||
SerializedObject so = new SerializedObject(source);
|
||||
result = so.getObject();
|
||||
} catch (Exception ex) {
|
||||
System.err.println("GenericObjectEditor: Problem making backup object");
|
||||
System.err.println(source.getClass().getName());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button.
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okayButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the cancel button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addCancelListener(ActionListener a) {
|
||||
cancelButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okayButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the cancel button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeCancelListener(ActionListener a) {
|
||||
cancelButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
public void setTarget(Object o) {
|
||||
propertySheetPanel.setTarget(o);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void updateClassType() {
|
||||
List<String> classesLongNames;
|
||||
ArrayList<Class<?>> instances = new ArrayList<>(5);
|
||||
classesLongNames = GenericObjectEditor.getClassesFromProperties(genericObjectEditor.getClassType().getName(), instances);
|
||||
LOGGER.finest("Selected type for OptimizationEditorPanel: " + genericObjectEditor.getClassType().getName());
|
||||
if (classesLongNames.size() > 1) {
|
||||
Vector<Item> classesList = new Vector<>();
|
||||
String[] toolTips = collectComboToolTips(instances, tipMaxLen);
|
||||
int i = 0;
|
||||
for (String className : classesLongNames) {
|
||||
String displayName = StringTools.cutClassName(className);
|
||||
|
||||
classesList.add(new Item(className, displayName, toolTips[i++]));
|
||||
}
|
||||
comboBoxModel = new DefaultComboBoxModel(classesList);
|
||||
objectChooser.setModel(comboBoxModel);
|
||||
objectChooser.setRenderer(new ToolTipComboBoxRenderer());
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
add(objectChooser, gbConstraints);
|
||||
} else {
|
||||
remove(objectChooser);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] collectComboToolTips(List<Class<?>> instances, int maxLen) {
|
||||
String[] tips = new String[instances.size()];
|
||||
|
||||
for (int i = 0; i < tips.length; i++) {
|
||||
tips[i] = null;
|
||||
|
||||
String tip = null;
|
||||
|
||||
Description description = instances.get(i).getAnnotation(Description.class);
|
||||
if (description != null) {
|
||||
tip = description.value();
|
||||
}
|
||||
|
||||
if (tip != null) {
|
||||
if (tip.length() <= maxLen) {
|
||||
tips[i] = tip;
|
||||
} else {
|
||||
tips[i] = tip.substring(0, maxLen - 2) + "..";
|
||||
}
|
||||
}
|
||||
}
|
||||
return tips;
|
||||
}
|
||||
|
||||
public void updateChooser() {
|
||||
String objectName = genericObjectEditor.getValue().getClass().getName();
|
||||
for (int i = 0; i < comboBoxModel.getSize(); i++) {
|
||||
Item element = (Item)comboBoxModel.getElementAt(i);
|
||||
|
||||
if (objectName.equals(element.getId())) {
|
||||
objectChooser.getModel().setSelectedItem(element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the child property sheet, and creates if needed
|
||||
*/
|
||||
public void updateChildPropertySheet() {
|
||||
// Set the object as the target of the PropertySheet
|
||||
propertySheetPanel.setTarget(genericObjectEditor.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* When the chooser selection is changed, ensures that the Object is changed
|
||||
* appropriately.
|
||||
*
|
||||
* @param e a value of type 'ItemEvent'
|
||||
*/
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
String className;
|
||||
|
||||
if ((e.getSource() == objectChooser) && (e.getStateChange() == ItemEvent.SELECTED)) {
|
||||
className = ((Item)objectChooser.getSelectedItem()).getId();
|
||||
try {
|
||||
Object n = Class.forName(className).newInstance();
|
||||
genericObjectEditor.setValue(n);
|
||||
// TODO ? setObject(n);
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Exception in itemStateChanged " + ex.getMessage());
|
||||
System.err.println("Classpath is " + System.getProperty("java.class.path"));
|
||||
ex.printStackTrace();
|
||||
objectChooser.hidePopup();
|
||||
objectChooser.setSelectedIndex(0);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Could not create an example of\n"
|
||||
+ className + "\n"
|
||||
+ "from the current classpath. Is the resource folder at the right place?\nIs the class abstract or the default constructor missing?",
|
||||
"GenericObjectEditor",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ToolTipComboBoxRenderer extends BasicComboBoxRenderer {
|
||||
|
||||
private static final long serialVersionUID = -5781643352198561208L;
|
||||
|
||||
public ToolTipComboBoxRenderer() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
super.getListCellRendererComponent(list, value, index,
|
||||
isSelected, cellHasFocus);
|
||||
|
||||
if (value != null) {
|
||||
Item item = (Item)value;
|
||||
setText(item.getDisplayName());
|
||||
|
||||
if (isSelected) {
|
||||
setBackground(list.getSelectionBackground());
|
||||
setForeground(list.getSelectionForeground());
|
||||
list.setToolTipText(item.getDescription());
|
||||
} else {
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
Item item = (Item)value;
|
||||
setText(item.getDisplayName());
|
||||
}
|
||||
|
||||
setFont(list.getFont());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
class Item
|
||||
{
|
||||
private String id;
|
||||
private String displayName;
|
||||
private String description;
|
||||
|
||||
public Item(String id, String displayName, String description)
|
||||
{
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
12
src/main/java/eva2/gui/PanelMaker.java
Normal file
12
src/main/java/eva2/gui/PanelMaker.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Simple helper interface.
|
||||
*
|
||||
* @author mkron
|
||||
*/
|
||||
public interface PanelMaker {
|
||||
JComponent makePanel();
|
||||
}
|
||||
38
src/main/java/eva2/gui/PropertyBoolSelector.java
Normal file
38
src/main/java/eva2/gui/PropertyBoolSelector.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
* A checkbox for boolean editors.
|
||||
*/
|
||||
public class PropertyBoolSelector extends JCheckBox {
|
||||
private static final long serialVersionUID = 8181005734895597714L;
|
||||
private PropertyEditor propertyEditor;
|
||||
|
||||
public PropertyBoolSelector(PropertyEditor pe) {
|
||||
super();
|
||||
setBackground(Color.WHITE);
|
||||
propertyEditor = pe;
|
||||
if (propertyEditor.getAsText().equals("True")) {
|
||||
setSelected(true);
|
||||
} else {
|
||||
setSelected(false);
|
||||
}
|
||||
|
||||
addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent evt) {
|
||||
if (evt.getStateChange() == ItemEvent.SELECTED) {
|
||||
propertyEditor.setValue(Boolean.TRUE);
|
||||
}
|
||||
if (evt.getStateChange() == ItemEvent.DESELECTED) {
|
||||
propertyEditor.setValue(Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
77
src/main/java/eva2/gui/PropertyDialog.java
Normal file
77
src/main/java/eva2/gui/PropertyDialog.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
import eva2.tools.StringTools;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyDialog extends JDialog {
|
||||
|
||||
private PropertyEditor propertyEditor;
|
||||
private Component editorComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyDialog(Window parent, PropertyEditor editor, String title) {
|
||||
super(parent, title, ModalityType.APPLICATION_MODAL);
|
||||
setTitle(getFrameNameFromEditor(editor));
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(EvAInfo.iconLocation, true);
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
setLayout(new BorderLayout());
|
||||
propertyEditor = editor;
|
||||
editorComponent = editor.getCustomEditor();
|
||||
add(editorComponent, BorderLayout.CENTER);
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
protected static String getFrameNameFromEditor(PropertyEditor editor) {
|
||||
if (editor.getValue().getClass().isArray()) {
|
||||
return "Array of " + StringTools.cutClassName(editor.getValue().getClass().getComponentType().getName());
|
||||
} else {
|
||||
return StringTools.cutClassName(editor.getValue().getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the name of the dialogue from an editor instance.
|
||||
*
|
||||
* @param editor
|
||||
*/
|
||||
public void updateFrameTitle(PropertyEditor editor) {
|
||||
setTitle(getFrameNameFromEditor(editor));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyEditor getEditor() {
|
||||
return propertyEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JRootPane createRootPane() {
|
||||
JRootPane rootPane = new JRootPane();
|
||||
KeyStroke stroke = KeyStroke.getKeyStroke("ESCAPE");
|
||||
Action actionListener = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
setVisible(false);
|
||||
}
|
||||
} ;
|
||||
InputMap inputMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
inputMap.put(stroke, "ESCAPE");
|
||||
rootPane.getActionMap().put("ESCAPE", actionListener);
|
||||
|
||||
return rootPane;
|
||||
}
|
||||
}
|
||||
225
src/main/java/eva2/gui/PropertyDoubleArray.java
Normal file
225
src/main/java/eva2/gui/PropertyDoubleArray.java
Normal file
@@ -0,0 +1,225 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
* A property for a double array. May be of dimensions m times n.
|
||||
*/
|
||||
public class PropertyDoubleArray implements java.io.Serializable {
|
||||
private double[][] doubleArray;
|
||||
private int numCols = 1;
|
||||
|
||||
public PropertyDoubleArray(double[] d) {
|
||||
setDoubleArray(d);
|
||||
}
|
||||
|
||||
public PropertyDoubleArray(double[][] d) {
|
||||
setDoubleArray(d);
|
||||
}
|
||||
|
||||
public PropertyDoubleArray(PropertyDoubleArray d) {
|
||||
this.doubleArray = d.doubleArray.clone();
|
||||
this.numCols = d.numCols;
|
||||
// System.arraycopy(d.doubleArray, 0, this.doubleArray, 0, this.doubleArray.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that creates a double matrix with given dimensions and fills
|
||||
* it cyclically with values given.
|
||||
*
|
||||
* @param rows
|
||||
* @param cols
|
||||
* @param d
|
||||
*/
|
||||
public PropertyDoubleArray(int rows, int cols, double... d) {
|
||||
if (rows > 0 && cols > 0) {
|
||||
this.doubleArray = new double[rows][cols];
|
||||
} else {
|
||||
this.doubleArray = null;
|
||||
}
|
||||
this.numCols = cols;
|
||||
int index = 0;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
doubleArray[i][j] = d[index];
|
||||
index++;
|
||||
if (index >= d.length) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyDoubleArray(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set the value of the double array
|
||||
*
|
||||
* @param d The double[]
|
||||
*/
|
||||
public void setDoubleArray(double[] d) {
|
||||
this.doubleArray = new double[d.length][1];
|
||||
for (int i = 0; i < d.length; i++) {
|
||||
doubleArray[i][0] = d[i];
|
||||
}
|
||||
numCols = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set the value of the double array
|
||||
*
|
||||
* @param d The double[]
|
||||
*/
|
||||
public void setDoubleArray(double[][] d) {
|
||||
this.doubleArray = d;
|
||||
if (d.length > 0) {
|
||||
numCols = d[0].length;
|
||||
} else {
|
||||
numCols = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the double array itself (no clone)
|
||||
*/
|
||||
public double[][] getDoubleArrayShallow() {
|
||||
return this.doubleArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a column as a vector (in copy)
|
||||
*
|
||||
* @return a column as a vector (in copy)
|
||||
*/
|
||||
public double[] getDoubleColumnAsVector(int col) {
|
||||
if (col >= numCols) {
|
||||
throw new IllegalArgumentException("Error, invalid column selected, " + col + " of " + numCols);
|
||||
}
|
||||
double[] ret = new double[doubleArray.length];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = doubleArray[i][col];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int getNumCols() {
|
||||
return numCols;
|
||||
}
|
||||
|
||||
public int getNumRows() {
|
||||
return doubleArray.length;
|
||||
}
|
||||
|
||||
public double getValue(int i, int j) {
|
||||
if (i < 0 || j < 0 || (i >= getNumRows()) || (j >= getNumCols())) {
|
||||
throw new IllegalArgumentException("Error, invalid access to double array: " + i + "," + j + " within " + getNumRows() + "," + getNumCols());
|
||||
}
|
||||
return doubleArray[i][j];
|
||||
}
|
||||
|
||||
public void adaptRowCount(int k) {
|
||||
if (k != doubleArray.length) {
|
||||
double[][] newDD = new double[k][numCols];
|
||||
for (int i = 0; i < k; i++) {
|
||||
for (int j = 0; j < numCols; j++) {
|
||||
if (i < doubleArray.length) {
|
||||
newDD[i][j] = doubleArray[i][j];
|
||||
} else {
|
||||
newDD[i][j] = doubleArray[doubleArray.length - 1][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
setDoubleArray(newDD);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteRow(int k) {
|
||||
if (k < 0 || k >= getNumRows()) {
|
||||
throw new IllegalArgumentException("Invalid index to deleteRow: " + k + " is not a valid row.");
|
||||
}
|
||||
double[][] newDD = new double[getNumRows() - 1][getNumCols()];
|
||||
int inc = 0;
|
||||
for (int i = 0; i < newDD.length; i++) {
|
||||
if (i == k) {
|
||||
inc = 1;
|
||||
}
|
||||
System.arraycopy(doubleArray[i + inc], 0, newDD[i], 0, getNumCols());
|
||||
}
|
||||
setDoubleArray(newDD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a copy of an indexed row at the end. If the given index
|
||||
* is invalid, the last row is copied.
|
||||
*
|
||||
* @param k
|
||||
*/
|
||||
public void addRowCopy(int k) {
|
||||
if (k < 0 || k >= getNumRows()) {
|
||||
k = getNumRows() - 1;
|
||||
}
|
||||
double[][] newDD = new double[getNumRows() + 1][getNumCols()];
|
||||
|
||||
for (int i = 0; i < getNumRows(); i++) {
|
||||
System.arraycopy(doubleArray[i], 0, newDD[i], 0, getNumCols());
|
||||
}
|
||||
if (k >= 0) {
|
||||
System.arraycopy(newDD[k], 0, newDD[newDD.length - 1], 0, getNumCols());
|
||||
} else {
|
||||
for (int j = 0; j < getNumCols(); j++) {
|
||||
newDD[newDD.length - 1][j] = 1.;
|
||||
}
|
||||
} // if the array was empty
|
||||
setDoubleArray(newDD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize all columns of the array by dividing through the sum.
|
||||
*/
|
||||
public void normalizeColumns() {
|
||||
double colSum = 0;
|
||||
for (int j = 0; j < getNumCols(); j++) {
|
||||
colSum = 0;
|
||||
for (int i = 0; i < getNumRows(); i++) {
|
||||
colSum += doubleArray[i][j];
|
||||
}
|
||||
if (colSum != 0) {
|
||||
for (int i = 0; i < getNumRows(); i++) {
|
||||
doubleArray[i][j] /= colSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if k is a valid row index (within 0 and numRows-1).
|
||||
*
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidRow(int k) {
|
||||
return (k >= 0) && (k < getNumRows());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return BeanInspector.toString(doubleArray);
|
||||
}
|
||||
|
||||
// /** This method will allow you to set the value of the double array
|
||||
// * @param d The double[]
|
||||
// */
|
||||
// public void setDoubleArray(double[] d) {
|
||||
// this.doubleArray = new double[d.length][1];
|
||||
// for (int i=0; i<d.length; i++) doubleArray[i][0] = d[i];
|
||||
// }
|
||||
//
|
||||
// /** This method will return the complete name of the file
|
||||
// * which filepath
|
||||
// * @return The complete filename with path.
|
||||
// */
|
||||
// public double[] getDoubleArray() {
|
||||
// return this.doubleArray;
|
||||
// }
|
||||
}
|
||||
138
src/main/java/eva2/gui/PropertyEditorProvider.java
Normal file
138
src/main/java/eva2/gui/PropertyEditorProvider.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.gui.editor.*;
|
||||
import eva2.optimization.individuals.codings.gp.GPArea;
|
||||
import eva2.optimization.operator.terminators.InterfaceTerminator;
|
||||
import eva2.tools.SelectedTag;
|
||||
import eva2.tools.StringSelection;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorManager;
|
||||
|
||||
public class PropertyEditorProvider {
|
||||
// if true, we use the GenericObjectEditor whenever no specific one is registered, so keep it true
|
||||
// unless you want to register every single possibility.
|
||||
public static boolean useDefaultGOE = true;
|
||||
|
||||
/**
|
||||
* Retrieve an editor object for a given class.
|
||||
* This method seems unable to retrieve a primitive editor for obscure reasons.
|
||||
* So better use the one based on PropertyDescriptor if possible.
|
||||
*/
|
||||
public static PropertyEditor findEditor(Class<?> cls) {
|
||||
PropertyEditor editor = PropertyEditorManager.findEditor(cls);
|
||||
|
||||
if ((editor == null) && useDefaultGOE) {
|
||||
if (cls.isArray()) {
|
||||
editor = new ArrayEditor();
|
||||
} else if (cls.isEnum()) {
|
||||
editor = new EnumEditor();
|
||||
} else {
|
||||
editor = new GenericObjectEditor();
|
||||
}
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param prop
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static PropertyEditor findEditor(PropertyDescriptor prop, Object value) {
|
||||
PropertyEditor editor = null;
|
||||
Class pec = prop.getPropertyEditorClass();
|
||||
Class type = prop.getPropertyType();
|
||||
|
||||
try {
|
||||
if (pec != null) {
|
||||
editor = (PropertyEditor) pec.newInstance();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
editor = null;
|
||||
}
|
||||
|
||||
if (editor == null) {
|
||||
if (value != null) {
|
||||
|
||||
// ToDo: This should be handled by the registerEditor below. findEditor however always returns the sun.beans.editor stuff.
|
||||
if (value instanceof Enum) {
|
||||
editor = new EnumEditor();
|
||||
} else {
|
||||
editor = PropertyEditorManager.findEditor(value.getClass());
|
||||
}
|
||||
}
|
||||
if (editor == null && (BeanInspector.isJavaPrimitive(value.getClass()))) {
|
||||
Class<?> prim = BeanInspector.getBoxedType(value.getClass());
|
||||
if (prim != null) {
|
||||
editor = PropertyEditorManager.findEditor(prim);
|
||||
}
|
||||
if (editor == null) {
|
||||
|
||||
prim = BeanInspector.getUnboxedType(value.getClass());
|
||||
if (prim != null) {
|
||||
editor = PropertyEditorManager.findEditor(prim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (editor == null) {
|
||||
editor = PropertyEditorManager.findEditor(type);
|
||||
}
|
||||
|
||||
if ((editor == null) && useDefaultGOE) {
|
||||
if (type.isArray()) {
|
||||
editor = new ArrayEditor();
|
||||
} else if (type.isEnum()) {
|
||||
editor = new EnumEditor();
|
||||
} else {
|
||||
editor = new GenericObjectEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (editor == null) {
|
||||
// If it's a user-defined property we give a warning.
|
||||
String getterClass = prop.getReadMethod().getDeclaringClass().getName();
|
||||
if (getterClass.indexOf("java.") != 0) {
|
||||
System.err.println("Warning: Can't find public property editor"
|
||||
+ " for property \"" + prop.getDisplayName() + "\" (class \""
|
||||
+ type.getName() + "\"). Skipping.");
|
||||
}
|
||||
} else if (editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) editor).setClassType(type);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public static void installEditors() {
|
||||
// First unregister the default EnumEditor provided by sun.*
|
||||
PropertyEditorManager.registerEditor(Enum.class, null);
|
||||
|
||||
PropertyEditorManager.registerEditor(SelectedTag.class, TagEditor.class);
|
||||
PropertyEditorManager.registerEditor(Enum.class, EnumEditor.class);
|
||||
PropertyEditorManager.registerEditor(int[].class, ArrayEditor.class);
|
||||
PropertyEditorManager.registerEditor(double[].class, ArrayEditor.class);
|
||||
PropertyEditorManager.registerEditor(InterfaceTerminator[].class, ArrayEditor.class);
|
||||
|
||||
|
||||
// The Editor for the new GO
|
||||
|
||||
PropertyEditorManager.registerEditor(StringSelection.class, StringSelectionEditor.class);
|
||||
// Traveling Salesman problem
|
||||
PropertyEditorManager.registerEditor(GPArea.class, AreaEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyDoubleArray.class, DoubleArrayEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyIntArray.class, IntArrayEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyEpsilonThreshold.class, EpsilonThresholdEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyEpsilonConstraint.class, EpsilonConstraintEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyWeightedLPTchebycheff.class, WeigthedLPTchebycheffEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyFilePath.class, FilePathEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyOptimizationObjectives.class, OptimizationObjectivesEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertyOptimizationObjectivesWithParam.class, OptimizationObjectivesWithParamEditor.class);
|
||||
PropertyEditorManager.registerEditor(eva2.gui.MultiLineString.class, MultiLineStringEditor.class);
|
||||
PropertyEditorManager.registerEditor(PropertySelectableList.class, ArrayEditor.class);
|
||||
}
|
||||
}
|
||||
26
src/main/java/eva2/gui/PropertyEpsilonConstraint.java
Normal file
26
src/main/java/eva2/gui/PropertyEpsilonConstraint.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyEpsilonConstraint implements java.io.Serializable {
|
||||
|
||||
public double[] targetValue;
|
||||
public int optimizeObjective;
|
||||
|
||||
public PropertyEpsilonConstraint() {
|
||||
}
|
||||
|
||||
public PropertyEpsilonConstraint(PropertyEpsilonConstraint e) {
|
||||
if (e.targetValue != null) {
|
||||
this.targetValue = new double[e.targetValue.length];
|
||||
System.arraycopy(e.targetValue, 0, this.targetValue, 0, this.targetValue.length);
|
||||
}
|
||||
this.optimizeObjective = e.optimizeObjective;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyEpsilonConstraint(this);
|
||||
}
|
||||
}
|
||||
31
src/main/java/eva2/gui/PropertyEpsilonThreshold.java
Normal file
31
src/main/java/eva2/gui/PropertyEpsilonThreshold.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyEpsilonThreshold implements java.io.Serializable {
|
||||
|
||||
public double[] punishment;
|
||||
public double[] targetValue;
|
||||
public int optimizeObjective;
|
||||
|
||||
public PropertyEpsilonThreshold() {
|
||||
}
|
||||
|
||||
public PropertyEpsilonThreshold(PropertyEpsilonThreshold e) {
|
||||
if (e.targetValue != null) {
|
||||
this.targetValue = new double[e.targetValue.length];
|
||||
System.arraycopy(e.targetValue, 0, this.targetValue, 0, this.targetValue.length);
|
||||
}
|
||||
if (e.punishment != null) {
|
||||
this.punishment = new double[e.punishment.length];
|
||||
System.arraycopy(e.punishment, 0, this.punishment, 0, this.punishment.length);
|
||||
}
|
||||
this.optimizeObjective = e.optimizeObjective;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyEpsilonThreshold(this);
|
||||
}
|
||||
}
|
||||
105
src/main/java/eva2/gui/PropertyFilePath.java
Normal file
105
src/main/java/eva2/gui/PropertyFilePath.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.tools.ReflectPackage;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyFilePath implements java.io.Serializable {
|
||||
|
||||
public String fileName = "";
|
||||
public String filePath = "";
|
||||
public String fileExtension = "";
|
||||
|
||||
/**
|
||||
* Constructor setting the absolute path. F
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private PropertyFilePath(String s) {
|
||||
this.setCompleteFilePath(s);
|
||||
}
|
||||
|
||||
public PropertyFilePath(PropertyFilePath d) {
|
||||
this.fileName = d.fileName;
|
||||
this.filePath = d.filePath;
|
||||
this.fileExtension = d.fileExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance by an absolute path.
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static PropertyFilePath getFilePathAbsolute(String path) {
|
||||
return new PropertyFilePath(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance by a relative path.
|
||||
*
|
||||
* @param relPath
|
||||
* @return
|
||||
*/
|
||||
public static PropertyFilePath getFilePathFromResource(String relPath) {
|
||||
String fName = ReflectPackage.getResourcePathFromCP(relPath);
|
||||
if (fName == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new PropertyFilePath(fName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyFilePath(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set a complete string
|
||||
* which will be separated into Path, Name and extension
|
||||
*
|
||||
* @param s The complete filepath and filename
|
||||
*/
|
||||
public void setCompleteFilePath(String s) {
|
||||
boolean trace = false;
|
||||
String filesep;
|
||||
|
||||
String old = this.getCompleteFilePath();
|
||||
try {
|
||||
if (trace) {
|
||||
System.out.println("Complete Filename: " + s);
|
||||
}
|
||||
filesep = System.getProperty("file.separator");
|
||||
if (trace) {
|
||||
System.out.println("File.Separator: " + filesep);
|
||||
}
|
||||
this.fileName = s.substring(s.lastIndexOf(filesep) + 1);
|
||||
this.fileExtension = this.fileName.substring(this.fileName.lastIndexOf("."));
|
||||
this.filePath = s.substring(0, s.lastIndexOf(filesep) + 1);
|
||||
|
||||
if (trace) {
|
||||
System.out.println("filePath: " + this.filePath);
|
||||
}
|
||||
if (trace) {
|
||||
System.out.println("Filename: " + this.fileName);
|
||||
}
|
||||
if (trace) {
|
||||
System.out.println("Fileext.: " + this.fileExtension);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.setCompleteFilePath(old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the complete name of the file
|
||||
* which filepath
|
||||
*
|
||||
* @return The complete filename with path.
|
||||
*/
|
||||
public String getCompleteFilePath() {
|
||||
return this.filePath + this.fileName;
|
||||
}
|
||||
}
|
||||
40
src/main/java/eva2/gui/PropertyIntArray.java
Normal file
40
src/main/java/eva2/gui/PropertyIntArray.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyIntArray implements java.io.Serializable {
|
||||
public int[] intArray;
|
||||
|
||||
public PropertyIntArray(int[] d) {
|
||||
this.intArray = d;
|
||||
}
|
||||
|
||||
public PropertyIntArray(PropertyIntArray d) {
|
||||
this.intArray = new int[d.intArray.length];
|
||||
System.arraycopy(d.intArray, 0, this.intArray, 0, this.intArray.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyIntArray(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set the value of the double array
|
||||
*
|
||||
* @param d The int[]
|
||||
*/
|
||||
public void setIntArray(int[] d) {
|
||||
this.intArray = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the int array
|
||||
*
|
||||
* @return The int array
|
||||
*/
|
||||
public int[] getIntArray() {
|
||||
return this.intArray;
|
||||
}
|
||||
}
|
||||
92
src/main/java/eva2/gui/PropertyOptimizationObjectives.java
Normal file
92
src/main/java/eva2/gui/PropertyOptimizationObjectives.java
Normal file
@@ -0,0 +1,92 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.problems.InterfaceOptimizationObjective;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyOptimizationObjectives implements java.io.Serializable {
|
||||
public InterfaceOptimizationObjective[] availableObjectives;
|
||||
public InterfaceOptimizationObjective[] selectedObjectives;
|
||||
|
||||
public PropertyOptimizationObjectives(InterfaceOptimizationObjective[] d) {
|
||||
this.availableObjectives = d;
|
||||
this.selectedObjectives = null;
|
||||
}
|
||||
|
||||
public PropertyOptimizationObjectives(PropertyOptimizationObjectives d) {
|
||||
this.availableObjectives = new InterfaceOptimizationObjective[d.availableObjectives.length];
|
||||
for (int i = 0; i < this.availableObjectives.length; i++) {
|
||||
this.availableObjectives[i] = (InterfaceOptimizationObjective) d.availableObjectives[i].clone();
|
||||
}
|
||||
this.selectedObjectives = new InterfaceOptimizationObjective[d.selectedObjectives.length];
|
||||
for (int i = 0; i < this.selectedObjectives.length; i++) {
|
||||
this.selectedObjectives[i] = (InterfaceOptimizationObjective) d.selectedObjectives[i].clone();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyOptimizationObjectives(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set the value of the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @param d The InterfaceOptimizationTarget[]
|
||||
*/
|
||||
public void setSelectedTargets(InterfaceOptimizationObjective[] d) {
|
||||
this.selectedObjectives = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @return The InterfaceOptimizationTarget[].
|
||||
*/
|
||||
public InterfaceOptimizationObjective[] getSelectedTargets() {
|
||||
return this.selectedObjectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @return The InterfaceOptimizationTarget[].
|
||||
*/
|
||||
public InterfaceOptimizationObjective[] getAvailableTargets() {
|
||||
return this.availableObjectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to remove a Target from the list
|
||||
*
|
||||
* @param index The index of the target to be removed.
|
||||
*/
|
||||
public void removeTarget(int index) {
|
||||
if ((index < 0) || (index >= this.selectedObjectives.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InterfaceOptimizationObjective[] newList = new InterfaceOptimizationObjective[this.selectedObjectives.length - 1];
|
||||
int j = 0;
|
||||
for (int i = 0; i < this.selectedObjectives.length; i++) {
|
||||
if (index != i) {
|
||||
newList[j] = this.selectedObjectives[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
this.selectedObjectives = newList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to add a new target to the list
|
||||
*
|
||||
* @param optTarget
|
||||
*/
|
||||
public void addTarget(InterfaceOptimizationObjective optTarget) {
|
||||
InterfaceOptimizationObjective[] newList = new InterfaceOptimizationObjective[this.selectedObjectives.length + 1];
|
||||
System.arraycopy(this.selectedObjectives, 0, newList, 0, this.selectedObjectives.length);
|
||||
newList[this.selectedObjectives.length] = optTarget;
|
||||
this.selectedObjectives = newList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.problems.InterfaceOptimizationObjective;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyOptimizationObjectivesWithParam implements java.io.Serializable {
|
||||
|
||||
public InterfaceOptimizationObjective[] availableObjectives;
|
||||
public InterfaceOptimizationObjective[] selectedObjectives;
|
||||
public double[] weights;
|
||||
public String descriptiveString = "No Description given.";
|
||||
public String weightsLabel = "-";
|
||||
public boolean normalizationEnabled = true;
|
||||
|
||||
public PropertyOptimizationObjectivesWithParam(InterfaceOptimizationObjective[] d) {
|
||||
this.availableObjectives = d;
|
||||
this.selectedObjectives = null;
|
||||
}
|
||||
|
||||
public PropertyOptimizationObjectivesWithParam(PropertyOptimizationObjectivesWithParam d) {
|
||||
this.descriptiveString = d.descriptiveString;
|
||||
this.weightsLabel = d.weightsLabel;
|
||||
this.normalizationEnabled = d.normalizationEnabled;
|
||||
this.availableObjectives = new InterfaceOptimizationObjective[d.availableObjectives.length];
|
||||
for (int i = 0; i < this.availableObjectives.length; i++) {
|
||||
this.availableObjectives[i] = (InterfaceOptimizationObjective) d.availableObjectives[i].clone();
|
||||
}
|
||||
this.selectedObjectives = new InterfaceOptimizationObjective[d.selectedObjectives.length];
|
||||
for (int i = 0; i < this.selectedObjectives.length; i++) {
|
||||
this.selectedObjectives[i] = (InterfaceOptimizationObjective) d.selectedObjectives[i].clone();
|
||||
}
|
||||
if (d.weights != null) {
|
||||
this.weights = new double[d.weights.length];
|
||||
System.arraycopy(d.weights, 0, this.weights, 0, this.weights.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyOptimizationObjectivesWithParam(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will allow you to set the value of the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @param d The InterfaceOptimizationTarget[]
|
||||
*/
|
||||
public void setSelectedTargets(InterfaceOptimizationObjective[] d) {
|
||||
this.selectedObjectives = d;
|
||||
|
||||
if (this.weights == null) {
|
||||
this.weights = new double[d.length];
|
||||
for (int i = 0; i < this.weights.length; i++) {
|
||||
this.weights[i] = 1.0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (d.length == this.weights.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (d.length > this.weights.length) {
|
||||
double[] newWeights = new double[d.length];
|
||||
System.arraycopy(this.weights, 0, newWeights, 0, this.weights.length);
|
||||
this.weights = newWeights;
|
||||
} else {
|
||||
double[] newWeights = new double[d.length];
|
||||
System.arraycopy(this.weights, 0, newWeights, 0, d.length);
|
||||
this.weights = newWeights;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @return The InterfaceOptimizationTarget[].
|
||||
*/
|
||||
public InterfaceOptimizationObjective[] getSelectedTargets() {
|
||||
return this.selectedObjectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return the InterfaceOptimizationTarget array
|
||||
*
|
||||
* @return The InterfaceOptimizationTarget[].
|
||||
*/
|
||||
public InterfaceOptimizationObjective[] getAvailableTargets() {
|
||||
return this.availableObjectives;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to read the weights
|
||||
*
|
||||
* @return the weights
|
||||
*/
|
||||
public double[] getWeights() {
|
||||
return this.weights;
|
||||
}
|
||||
|
||||
public void setWeights(double[] d) {
|
||||
this.weights = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to set/get the descriptive string
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String getDescriptiveString() {
|
||||
return this.descriptiveString;
|
||||
}
|
||||
|
||||
public void setDescriptiveString(String d) {
|
||||
this.descriptiveString = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to set/get the weights label
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String getWeigthsLabel() {
|
||||
return this.weightsLabel;
|
||||
}
|
||||
|
||||
public void setWeightsLabel(String d) {
|
||||
this.weightsLabel = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to set/get the weights label
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public boolean isNormalizationEnabled() {
|
||||
return this.normalizationEnabled;
|
||||
}
|
||||
|
||||
public void enableNormalization(boolean d) {
|
||||
this.normalizationEnabled = d;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to remove a Target from the list
|
||||
*
|
||||
* @param index The index of the target to be removed.
|
||||
*/
|
||||
public void removeTarget(int index) {
|
||||
if ((index < 0) || (index >= this.selectedObjectives.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InterfaceOptimizationObjective[] newList = new InterfaceOptimizationObjective[this.selectedObjectives.length - 1];
|
||||
double[] newWeights = new double[this.weights.length - 1];
|
||||
int j = 0;
|
||||
for (int i = 0; i < this.selectedObjectives.length; i++) {
|
||||
if (index != i) {
|
||||
newList[j] = this.selectedObjectives[i];
|
||||
newWeights[j] = this.weights[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
this.selectedObjectives = newList;
|
||||
this.weights = newWeights;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to add a new target to the list
|
||||
*
|
||||
* @param optTarget
|
||||
*/
|
||||
public void addTarget(InterfaceOptimizationObjective optTarget) {
|
||||
InterfaceOptimizationObjective[] newList = new InterfaceOptimizationObjective[this.selectedObjectives.length + 1];
|
||||
double[] newWeights = new double[this.weights.length + 1];
|
||||
for (int i = 0; i < this.selectedObjectives.length; i++) {
|
||||
newList[i] = this.selectedObjectives[i];
|
||||
newWeights[i] = this.weights[i];
|
||||
}
|
||||
newList[this.selectedObjectives.length] = optTarget;
|
||||
newWeights[this.selectedObjectives.length] = 1.0;
|
||||
this.selectedObjectives = newList;
|
||||
this.weights = newWeights;
|
||||
}
|
||||
}
|
||||
83
src/main/java/eva2/gui/PropertyPanel.java
Normal file
83
src/main/java/eva2/gui/PropertyPanel.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.tools.StringTools;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyPanel extends JPanel {
|
||||
private PropertyEditor propertyEditor;
|
||||
private PropertyDialog propertyDialog;
|
||||
|
||||
private JLabel textLabel;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyPanel(PropertyEditor editor) {
|
||||
setToolTipText("Click to edit properties for this object");
|
||||
setOpaque(true);
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
propertyEditor = editor;
|
||||
|
||||
textLabel = new JLabel();
|
||||
add(textLabel, gbConstraints);
|
||||
}
|
||||
|
||||
public final void showDialog() {
|
||||
Window parent = (Window)this.getRootPane().getParent();
|
||||
if (propertyDialog == null) {
|
||||
propertyDialog = new PropertyDialog(parent, propertyEditor, StringTools.cutClassName(propertyEditor.getClass().getName()));
|
||||
propertyDialog.setPreferredSize(new Dimension(500, 300));
|
||||
propertyDialog.setModal(true);
|
||||
propertyDialog.setVisible(true);
|
||||
} else {
|
||||
propertyDialog.updateFrameTitle(propertyEditor);
|
||||
propertyDialog.setVisible(false);
|
||||
propertyDialog.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
if (propertyDialog != null) {
|
||||
propertyDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Insets i = textLabel.getInsets();
|
||||
Rectangle box = new Rectangle(i.left, i.top,
|
||||
getSize().width - i.left - i.right,
|
||||
getSize().height - i.top - i.bottom);
|
||||
Color back = g.getColor();
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(i.left, i.top,
|
||||
getSize().width - i.right - i.left,
|
||||
getSize().height - i.bottom - i.top);
|
||||
g.setColor(back);
|
||||
propertyEditor.paintValue(g, box);
|
||||
}
|
||||
|
||||
public PropertyEditor getEditor() {
|
||||
return propertyEditor;
|
||||
}
|
||||
}
|
||||
132
src/main/java/eva2/gui/PropertySelectableList.java
Normal file
132
src/main/java/eva2/gui/PropertySelectableList.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package eva2.gui;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PropertySelectableList<T> implements java.io.Serializable {
|
||||
|
||||
protected T[] objects;
|
||||
protected boolean[] selections;
|
||||
private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
public PropertySelectableList(T[] initial) {
|
||||
objects = initial;
|
||||
selections = new boolean[initial.length];
|
||||
}
|
||||
|
||||
public PropertySelectableList(PropertySelectableList<T> b) {
|
||||
if (b.objects != null) {
|
||||
this.objects = b.objects.clone();
|
||||
}
|
||||
if (b.selections != null) {
|
||||
this.selections = new boolean[b.selections.length];
|
||||
System.arraycopy(b.selections, 0, this.selections, 0, this.selections.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertySelectableList<>(this);
|
||||
}
|
||||
|
||||
public void setObjects(T[] o) {
|
||||
this.objects = o;
|
||||
this.selections = new boolean[o.length];
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
|
||||
public void setObjects(T[] o, boolean[] selection) {
|
||||
this.objects = o;
|
||||
this.selections = selection;
|
||||
if (o.length != selection.length) {
|
||||
throw new RuntimeException("Error, mismatching length of arrays in " + this.getClass());
|
||||
}
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
|
||||
public T[] getObjects() {
|
||||
return this.objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the elements represented by this list where only the selected elements are non-null.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public T[] getSelectedObjects() {
|
||||
T[] selObjects = getObjects().clone();
|
||||
for (int i = 0; i < selObjects.length; i++) {
|
||||
if (!selections[i]) {
|
||||
selObjects[i] = null;
|
||||
}
|
||||
}
|
||||
return selObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selection by giving a list of selected indices.
|
||||
*
|
||||
* @param selection
|
||||
*/
|
||||
public void setSelectionByIndices(int[] selection) {
|
||||
selections = new boolean[getObjects().length];
|
||||
for (int i = 0; i < selection.length; i++) {
|
||||
selections[selection[i]] = true;
|
||||
}
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
|
||||
public void setSelection(boolean[] selection) {
|
||||
this.selections = selection;
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
|
||||
public boolean[] getSelection() {
|
||||
return this.selections;
|
||||
}
|
||||
|
||||
public void setSelectionForElement(int index, boolean b) {
|
||||
if (selections[index] != b) {
|
||||
this.selections[index] = b;
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
if (objects == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return objects.length;
|
||||
}
|
||||
}
|
||||
|
||||
public T get(int i) {
|
||||
return objects[i];
|
||||
}
|
||||
|
||||
public boolean isSelected(int i) {
|
||||
return selections[i];
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
objects = null;
|
||||
selections = null;
|
||||
propertyChangeSupport.firePropertyChange("PropertySelectableList", null, this);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
}
|
||||
1090
src/main/java/eva2/gui/PropertySheetPanel.java
Normal file
1090
src/main/java/eva2/gui/PropertySheetPanel.java
Normal file
File diff suppressed because it is too large
Load Diff
104
src/main/java/eva2/gui/PropertySlider.java
Normal file
104
src/main/java/eva2/gui/PropertySlider.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package eva2.gui;
|
||||
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PropertySlider extends JPanel {
|
||||
|
||||
private PropertyEditor propertyEditor;
|
||||
private JSlider slider;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
PropertySlider(PropertyEditor pe) {
|
||||
//super(pe.getAsText());
|
||||
propertyEditor = pe;
|
||||
//setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
|
||||
//setBorder(new TitledBorder(getString("SliderDemo.plain")));
|
||||
slider = new JSlider(-10, 90, 20);
|
||||
//s.getAccessibleContext().setAccessibleName(getString("SliderDemo.plain"));
|
||||
//s.getAccessibleContext().setAccessibleDescription(getString("SliderDemo.a_plain_slider"));
|
||||
slider.addChangeListener(new SliderListener());
|
||||
slider.setValue((Integer) propertyEditor.getValue());
|
||||
slider.setPaintTicks(true);
|
||||
slider.setMajorTickSpacing(20);
|
||||
slider.setMinorTickSpacing(5);
|
||||
slider.setPaintLabels(true);
|
||||
this.add(slider);
|
||||
propertyEditor.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
updateUs();
|
||||
}
|
||||
});
|
||||
addKeyListener(new KeyAdapter() {
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
// if (e.getKeyCode() == KeyEvent.VK_ENTER)
|
||||
updateEditor();
|
||||
}
|
||||
});
|
||||
addFocusListener(new FocusAdapter() {
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
updateEditor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void updateUs() {
|
||||
try {
|
||||
//String x = editor.getAsText();
|
||||
slider.setValue((Integer) propertyEditor.getValue());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void updateEditor() {
|
||||
try {
|
||||
propertyEditor.setValue(slider.getValue());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class SliderListener implements ChangeListener {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SliderListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
JSlider s1 = (JSlider) e.getSource();
|
||||
System.out.println("slider" + s1.getValue());
|
||||
updateEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/main/java/eva2/gui/PropertyText.java
Normal file
65
src/main/java/eva2/gui/PropertyText.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A text property editor view. Updates the editor on key release and lost focus
|
||||
* events.
|
||||
*/
|
||||
public class PropertyText extends JTextField {
|
||||
private Logger LOGGER = Logger.getLogger(PropertyText.class.getName());
|
||||
private PropertyEditor propertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyText(PropertyEditor pe) {
|
||||
super(pe.getAsText());
|
||||
this.setBorder(BorderFactory.createEmptyBorder());
|
||||
propertyEditor = pe;
|
||||
addKeyListener(new KeyAdapter() {
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
//if (e.getKeyCode() == KeyEvent.VK_ENTER)
|
||||
updateEditor();
|
||||
}
|
||||
});
|
||||
addFocusListener(new FocusAdapter() {
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
updateEditor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void updateEditor() {
|
||||
try {
|
||||
String x = getText();
|
||||
if (!propertyEditor.getAsText().equals(x)) {
|
||||
propertyEditor.setAsText(x);
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOGGER.finer(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkConsistency() {
|
||||
String x = getText();
|
||||
return x.equals(propertyEditor.getAsText());
|
||||
}
|
||||
|
||||
public void updateFromEditor() {
|
||||
setText(propertyEditor.getAsText());
|
||||
}
|
||||
}
|
||||
47
src/main/java/eva2/gui/PropertyValueSelector.java
Normal file
47
src/main/java/eva2/gui/PropertyValueSelector.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package eva2.gui;
|
||||
/*
|
||||
* Title: EvA2 Description: Copyright: Copyright (c) 2003 Company: University of Tuebingen, Computer
|
||||
* Architecture @author Holger Ulmer, Felix Streichert, Hannes Planatscher @version: $Revision: 57 $
|
||||
* $Date: 2007-05-04 14:22:16 +0200 (Fri, 04 May 2007) $ $Author: mkron $
|
||||
*/
|
||||
|
||||
import javax.swing.*;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
public class PropertyValueSelector extends JComboBox {
|
||||
|
||||
private PropertyEditor propertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PropertyValueSelector(PropertyEditor pe) {
|
||||
propertyEditor = pe;
|
||||
this.setBorder(BorderFactory.createEmptyBorder());
|
||||
Object value = propertyEditor.getAsText();
|
||||
String[] tags = propertyEditor.getTags();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ComboBoxModel model = new DefaultComboBoxModel(tags) {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Object getSelectedItem() {
|
||||
return propertyEditor.getAsText();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setSelectedItem(Object o) {
|
||||
propertyEditor.setAsText((String) o);
|
||||
}
|
||||
};
|
||||
setModel(model);
|
||||
setSelectedItem(value);
|
||||
}
|
||||
}
|
||||
31
src/main/java/eva2/gui/PropertyWeightedLPTchebycheff.java
Normal file
31
src/main/java/eva2/gui/PropertyWeightedLPTchebycheff.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package eva2.gui;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PropertyWeightedLPTchebycheff implements java.io.Serializable {
|
||||
|
||||
public double[] idealValue;
|
||||
public double[] weights;
|
||||
public int p = 0;
|
||||
|
||||
public PropertyWeightedLPTchebycheff() {
|
||||
}
|
||||
|
||||
public PropertyWeightedLPTchebycheff(PropertyWeightedLPTchebycheff e) {
|
||||
if (e.idealValue != null) {
|
||||
this.idealValue = new double[e.idealValue.length];
|
||||
System.arraycopy(e.idealValue, 0, this.idealValue, 0, this.idealValue.length);
|
||||
}
|
||||
if (e.weights != null) {
|
||||
this.weights = new double[e.weights.length];
|
||||
System.arraycopy(e.weights, 0, this.weights, 0, this.weights.length);
|
||||
}
|
||||
this.p = e.p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new PropertyWeightedLPTchebycheff(this);
|
||||
}
|
||||
}
|
||||
42
src/main/java/eva2/gui/SplashScreen.java
Normal file
42
src/main/java/eva2/gui/SplashScreen.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package eva2.gui;
|
||||
|
||||
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
|
||||
class SplashScreen extends JWindow {
|
||||
|
||||
private static final long serialVersionUID = 1281793825850423095L;
|
||||
private String imgLocation;
|
||||
|
||||
public SplashScreen(String imgLoc) {
|
||||
imgLocation = imgLoc;
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(imgLocation, true);
|
||||
ImageIcon ii = new ImageIcon(Toolkit.getDefaultToolkit().createImage(bytes));
|
||||
JLabel splashLabel = new JLabel(ii);
|
||||
|
||||
this.add(splashLabel);
|
||||
this.pack();
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
this.setLocation(screenSize.width / 2 - this.getSize().width / 2, screenSize.height / 2 - this.getSize().height / 2);
|
||||
setAlwaysOnTop(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the splash screen to the end user.
|
||||
* <p>
|
||||
* Once this method returns, the splash screen is realized, which means
|
||||
* that almost all work on the splash screen should proceed through the
|
||||
* event dispatch thread. In particular, any call to
|
||||
* <code>dispose</code> for the splash screen must be performed in the event
|
||||
* dispatch thread.
|
||||
*/
|
||||
public void splash() {
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
}
|
||||
711
src/main/java/eva2/gui/StandaloneOptimization.java
Normal file
711
src/main/java/eva2/gui/StandaloneOptimization.java
Normal file
@@ -0,0 +1,711 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.gui.plot.Plot;
|
||||
import eva2.optimization.OptimizationParameters;
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.optimization.individuals.ESIndividualDoubleData;
|
||||
import eva2.optimization.individuals.GAIndividualDoubleData;
|
||||
import eva2.optimization.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.optimization.operator.crossover.CrossoverGAGINPoint;
|
||||
import eva2.optimization.operator.mutation.InterfaceMutation;
|
||||
import eva2.optimization.operator.mutation.MutateESFixedStepSize;
|
||||
import eva2.optimization.operator.mutation.MutateESLocal;
|
||||
import eva2.optimization.operator.selection.SelectTournament;
|
||||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||||
import eva2.optimization.population.InterfacePopulationChangedEventListener;
|
||||
import eva2.optimization.population.Population;
|
||||
import eva2.optimization.strategies.EvolutionStrategies;
|
||||
import eva2.optimization.strategies.GeneticAlgorithm;
|
||||
import eva2.optimization.strategies.InterfaceOptimizer;
|
||||
import eva2.problems.F1Problem;
|
||||
import eva2.tools.math.RNG;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@eva2.util.annotation.Description(value = "This is a simple example framework for Evolutionary Algorithms.")
|
||||
public class StandaloneOptimization implements InterfaceStandaloneOptimization, InterfacePopulationChangedEventListener, java.io.Serializable {
|
||||
|
||||
// Interface GUI Stuff
|
||||
transient private JFrame mainFrame;
|
||||
transient private JPanel mainPanel;
|
||||
transient private JPanel buttonPanel;
|
||||
transient private JButton runButton, stopButton, continueButton, showSolutionButton;
|
||||
transient private JComponent optionsPanel, parameterPanel1, parameterPanel2;
|
||||
transient private JComponent statusPanel;
|
||||
transient private JLabel statusField;
|
||||
transient private JProgressBar progressBar;
|
||||
transient private eva2.gui.SwingWorker worker;
|
||||
transient private boolean show = false;
|
||||
// transient private InterfaceTest test = new Test1();
|
||||
// Opt. Algorithms and Parameters
|
||||
//transient private InterfaceOptimizer optimizer = new EvolutionaryMultiObjectiveOptimization();
|
||||
//transient private InterfaceOptimizationProblem problem = new TF1Problem();
|
||||
//transient private int functionCalls = 1000;
|
||||
private OptimizationParameters optimizationParameters;
|
||||
transient private int multiRuns = 1;
|
||||
transient private int recentFunctionCalls;
|
||||
transient private int currentExperiment = 0;
|
||||
transient private int currentRun;
|
||||
transient private int currentProgress;
|
||||
transient private String experimentName;
|
||||
transient private String outputPath = "";
|
||||
transient private String outputFileName = "none";
|
||||
// these parameters are for the continue option
|
||||
transient private Population backupPopulation;
|
||||
transient private boolean continueFlag;
|
||||
// Plot Panel stuff
|
||||
transient private Plot plot;
|
||||
transient private ArrayList performedRuns = new ArrayList();
|
||||
transient private ArrayList<Double[]> tmpData;
|
||||
transient private BufferedWriter outputFile;
|
||||
// Test
|
||||
transient private List list;
|
||||
|
||||
/**
|
||||
* Create a new EALectureGUI.
|
||||
*/
|
||||
public StandaloneOptimization() {
|
||||
this.optimizationParameters = OptimizationParameters.getInstance();
|
||||
this.experimentName = this.optimizationParameters.getOptimizer().getName() + "-" + this.performedRuns.size();
|
||||
this.optimizationParameters.addPopulationChangedEventListener(this);
|
||||
RNG.setRandomSeed(optimizationParameters.getRandomSeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to get the current GO parameters
|
||||
*/
|
||||
public OptimizationParameters getGOParameters() {
|
||||
return this.optimizationParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will generate a Plot Frame and a main Editing Frame
|
||||
*/
|
||||
public void initFrame() {
|
||||
this.progressBar = new JProgressBar();
|
||||
// initialize the main frame
|
||||
this.mainFrame = new JFrame();
|
||||
this.mainFrame.setTitle("Genetic Optimizing");
|
||||
this.mainFrame.setSize(500, 400);
|
||||
this.mainFrame.setLocation(530, 50);
|
||||
this.mainFrame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent ev) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
// build the main panel
|
||||
this.mainPanel = new JPanel();
|
||||
this.mainFrame.getContentPane().add(this.mainPanel);
|
||||
this.mainPanel.setLayout(new BorderLayout());
|
||||
// build the button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.runButton = new JButton("Run");
|
||||
this.runButton.addActionListener(this.runListener);
|
||||
this.runButton.setEnabled(true);
|
||||
this.runButton.setToolTipText("Run the optimization process with the current parameter settings.");
|
||||
this.stopButton = new JButton("Stop");
|
||||
this.stopButton.addActionListener(this.stopListener);
|
||||
this.stopButton.setEnabled(false);
|
||||
this.stopButton.setToolTipText("Stop the runnig the optimization process.");
|
||||
this.continueButton = new JButton("Continue");
|
||||
this.continueButton.addActionListener(this.continueListener);
|
||||
this.continueButton.setEnabled(false);
|
||||
this.continueButton.setToolTipText("Resume the previous optimization (check termination criteria and multiruns = 1!).");
|
||||
this.showSolutionButton = new JButton("Show Solution");
|
||||
this.showSolutionButton.addActionListener(this.showSolListener);
|
||||
this.showSolutionButton.setEnabled(true);
|
||||
this.showSolutionButton.setToolTipText("Show the current best solution.");
|
||||
this.buttonPanel.add(this.runButton);
|
||||
this.buttonPanel.add(this.continueButton);
|
||||
this.buttonPanel.add(this.stopButton);
|
||||
this.buttonPanel.add(this.showSolutionButton);
|
||||
this.mainPanel.add(this.buttonPanel, BorderLayout.NORTH);
|
||||
|
||||
// build the Options Panel
|
||||
JParaPanel paraPanel = new JParaPanel(this, "MyGUI");
|
||||
Class object = null, editor = null;
|
||||
String tmp = "eva2.optimization.tools.InterfaceTest";
|
||||
try {
|
||||
object = Class.forName(tmp);
|
||||
} catch (java.lang.ClassNotFoundException e) {
|
||||
System.out.println("No Class found for " + tmp);
|
||||
}
|
||||
tmp = "eva2.gui.editor.GenericObjectEditor";
|
||||
try {
|
||||
editor = Class.forName(tmp);
|
||||
} catch (java.lang.ClassNotFoundException e) {
|
||||
System.out.println("No Class found for " + tmp);
|
||||
}
|
||||
if ((object != null) && (editor != null)) {
|
||||
paraPanel.registerEditor(object, editor);
|
||||
}
|
||||
|
||||
// Tabs
|
||||
this.parameterPanel1 = (paraPanel.makePanel());
|
||||
this.optionsPanel = new JTabbedPane();
|
||||
JParaPanel paraPanel2 = new JParaPanel(this.optimizationParameters, "MyGUI");
|
||||
this.parameterPanel2 = (paraPanel2.makePanel());
|
||||
((JTabbedPane) this.optionsPanel).addTab("Optimization Parameters", this.parameterPanel2);
|
||||
((JTabbedPane) this.optionsPanel).addTab("Statistics", this.parameterPanel1);
|
||||
this.mainPanel.add(this.optionsPanel, BorderLayout.CENTER);
|
||||
|
||||
// build the Status Panel
|
||||
this.statusPanel = new JPanel();
|
||||
this.statusPanel.setLayout(new BorderLayout());
|
||||
this.statusField = new JLabel("Click Run to begin...");
|
||||
this.progressBar = new JProgressBar();
|
||||
this.statusPanel.add(this.statusField, BorderLayout.NORTH);
|
||||
this.statusPanel.add(this.progressBar, BorderLayout.SOUTH);
|
||||
this.mainPanel.add(this.statusPanel, BorderLayout.SOUTH);
|
||||
// The plot frame
|
||||
double[] tmpD = new double[2];
|
||||
tmpD[0] = 1;
|
||||
tmpD[1] = 1;
|
||||
this.plot = new Plot("EA Lecture Plot", "Function calls", "Fitness", true);
|
||||
// validate and show
|
||||
this.mainFrame.validate();
|
||||
this.mainFrame.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener, called by the "Run/Restart" button, will initialize the
|
||||
* problem and start the computation.
|
||||
*/
|
||||
ActionListener runListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
worker = new eva2.gui.SwingWorker() {
|
||||
@Override
|
||||
public Object construct() {
|
||||
return doWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished() {
|
||||
runButton.setEnabled(true);
|
||||
continueButton.setEnabled(true);
|
||||
stopButton.setEnabled(false);
|
||||
backupPopulation = (Population) optimizationParameters.getOptimizer().getPopulation().clone();
|
||||
}
|
||||
};
|
||||
worker.start();
|
||||
runButton.setEnabled(false);
|
||||
continueButton.setEnabled(false);
|
||||
stopButton.setEnabled(true);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This action listener, called by the "Cancel" button, interrupts the
|
||||
* worker thread which is running this.doWork(). Note that the doWork()
|
||||
* method handles InterruptedExceptions cleanly.
|
||||
*/
|
||||
ActionListener stopListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
runButton.setEnabled(true);
|
||||
continueButton.setEnabled(true);
|
||||
stopButton.setEnabled(false);
|
||||
worker.interrupt();
|
||||
for (int i = 0; i < multiRuns; i++) {
|
||||
plot.clearGraph(1000 + i);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This action listener, called by the "Cancel" button, interrupts the
|
||||
* worker thread which is running this.doWork(). Note that the doWork()
|
||||
* method handles InterruptedExceptions cleanly.
|
||||
*/
|
||||
ActionListener continueListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
// todo something need to be done here...
|
||||
worker = new eva2.gui.SwingWorker() {
|
||||
@Override
|
||||
public Object construct() {
|
||||
return doWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished() {
|
||||
runButton.setEnabled(true);
|
||||
continueButton.setEnabled(true);
|
||||
stopButton.setEnabled(false);
|
||||
backupPopulation = (Population) optimizationParameters.getOptimizer().getPopulation().clone();
|
||||
continueFlag = false;
|
||||
}
|
||||
};
|
||||
// also mal ganz anders ich gehe davon aus, dass der Benutzer das Ding parametrisiert hat
|
||||
// setze einfach die Backup population ein...
|
||||
continueFlag = true;
|
||||
multiRuns = 1; // multiruns machen bei continue einfach keinen Sinn...
|
||||
worker.start();
|
||||
runButton.setEnabled(false);
|
||||
continueButton.setEnabled(false);
|
||||
stopButton.setEnabled(true);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* This action listener, called by the "show" button will show the currently
|
||||
* best solution in a frame.
|
||||
*/
|
||||
ActionListener showSolListener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
JFrame frame = new JFrame();
|
||||
frame.setTitle("The current best solution for " + optimizationParameters.getProblem().getName());
|
||||
frame.setSize(400, 300);
|
||||
frame.setLocation(450, 250);
|
||||
Population pop = optimizationParameters.getOptimizer().getPopulation();
|
||||
frame.getContentPane().add(optimizationParameters.getProblem().drawIndividual(pop.getGeneration(), pop.getFunctionCalls(), pop.getBestEAIndividual()));
|
||||
frame.validate();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This method gives the experimental settings and starts the work.
|
||||
*/
|
||||
@Override
|
||||
public void startExperiment() {
|
||||
// This is for the CBN-TEST RUNS
|
||||
this.optimizationParameters.setOptimizer(new EvolutionStrategies());
|
||||
this.optimizationParameters.setProblem(new F1Problem());
|
||||
EvaluationTerminator terminator = new EvaluationTerminator();
|
||||
terminator.setFitnessCalls(50000);
|
||||
this.optimizationParameters.setTerminator(terminator);
|
||||
this.multiRuns = 10;
|
||||
int experimentType = 0;
|
||||
this.experimentName = "InferringGRN";
|
||||
this.outputFileName = "Result";
|
||||
this.outputPath = "results/";
|
||||
// These are some tmp Variables
|
||||
InterfaceDataTypeDouble tmpIndy = new ESIndividualDoubleData();
|
||||
InterfaceMutation tmpMut = new MutateESFixedStepSize();
|
||||
|
||||
switch (experimentType) {
|
||||
case 0: {
|
||||
// use the Struture Skeletalizing with GA
|
||||
this.outputFileName = "Prim4_StructSkelGATESTIT";
|
||||
GeneticAlgorithm ga = new GeneticAlgorithm();
|
||||
SelectTournament tour = new SelectTournament();
|
||||
tour.setTournamentSize(10);
|
||||
ga.setParentSelection(tour);
|
||||
ga.setPartnerSelection(tour);
|
||||
this.optimizationParameters.setOptimizer(ga);
|
||||
this.optimizationParameters.getOptimizer().getPopulation().setTargetSize(100);
|
||||
F1Problem problem = new F1Problem();
|
||||
tmpIndy = new GAIndividualDoubleData();
|
||||
((GAIndividualDoubleData) tmpIndy).setCrossoverOperator(new CrossoverGAGINPoint());
|
||||
((GAIndividualDoubleData) tmpIndy).setCrossoverProbability(1.0);
|
||||
((GAIndividualDoubleData) tmpIndy).setMutationProbability(1.0);
|
||||
problem.setEAIndividual(tmpIndy);
|
||||
//((FGRNInferringProblem)this.problem).setStructreSkelInterval(1);
|
||||
this.optimizationParameters.getOptimizer().setProblem(problem);
|
||||
this.optimizationParameters.getOptimizer().addPopulationChangedEventListener(this);
|
||||
this.doWork();
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
// use the simple ES Local
|
||||
this.outputFileName = "X360_StandardES";
|
||||
EvolutionStrategies es = new EvolutionStrategies();
|
||||
this.optimizationParameters.setOptimizer(es);
|
||||
this.optimizationParameters.getOptimizer().getPopulation().setTargetSize(50);
|
||||
F1Problem problem = new F1Problem();
|
||||
tmpIndy = new ESIndividualDoubleData();
|
||||
((AbstractEAIndividual) tmpIndy).setMutationOperator(new MutateESLocal());
|
||||
problem.setEAIndividual(tmpIndy);
|
||||
//((FGRNInferringProblem)this.problem).setUseHEigenMatrix(true);
|
||||
//((FGRNInferringProblem)this.problem).setUseOnlyPositiveNumbers(true);
|
||||
this.optimizationParameters.getOptimizer().setProblem(problem);
|
||||
this.optimizationParameters.getOptimizer().addPopulationChangedEventListener(this);
|
||||
this.doWork();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method represents the application code that we'd like to run on a
|
||||
* separate thread. It simulates slowly computing a value, in this case just
|
||||
* a string 'All Done'. It updates the progress bar every half second to
|
||||
* remind the user that we're still busy.
|
||||
*/
|
||||
public Object doWork() {
|
||||
try {
|
||||
this.optimizationParameters.saveInstance();
|
||||
if (this.show) {
|
||||
this.statusField.setText("Optimizing...");
|
||||
}
|
||||
|
||||
RNG.setRandomSeed(optimizationParameters.getRandomSeed());
|
||||
// opening output file...
|
||||
if (!this.outputFileName.equalsIgnoreCase("none")) {
|
||||
String name = "";
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_'HH.mm.ss");
|
||||
String startDate = formatter.format(new Date());
|
||||
name = this.outputPath + this.outputFileName + "_" + this.experimentName + "_" + startDate + ".dat";
|
||||
try {
|
||||
this.outputFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(name)));
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("Could not open output file! Filename: " + name);
|
||||
}
|
||||
} else {
|
||||
this.outputFile = null;
|
||||
}
|
||||
|
||||
// initialize problem
|
||||
this.optimizationParameters.getProblem().initializeProblem();
|
||||
this.optimizationParameters.getOptimizer().setProblem(this.optimizationParameters.getProblem());
|
||||
// int optimizer and population
|
||||
//this.optimizationParameters.getOptimizer().initialize();
|
||||
|
||||
// initialize the log data
|
||||
ArrayList tmpMultiRun = new ArrayList();
|
||||
this.performedRuns.add(tmpMultiRun);
|
||||
|
||||
// something to log file
|
||||
//if (outputFile != null) this.writeToFile(this.optimizationParameters.getOptimizer().getStringRepresentation());
|
||||
//this.writeToFile("Here i'll write something characterizing the algorithm.");
|
||||
|
||||
for (int j = 0; j < this.multiRuns; j++) {
|
||||
this.optimizationParameters.getProblem().initializeProblem(); // in the loop as well, dynamic probs may need that (MK)
|
||||
this.tmpData = new ArrayList<>();
|
||||
this.currentRun = j;
|
||||
if (this.show) {
|
||||
this.statusField.setText("Optimizing Run " + (j + 1) + " of " + this.multiRuns + " Multi Runs...");
|
||||
}
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
// write header to file
|
||||
this.writeToFile(" FitnessCalls\t Best\t Mean\t Worst \t" + BeanInspector.toString(this.optimizationParameters.getProblem().getAdditionalDataHeader(), '\t', false, ""));
|
||||
if ((this.continueFlag) && (this.backupPopulation != null)) {
|
||||
this.recentFunctionCalls += this.backupPopulation.getFunctionCalls();
|
||||
this.optimizationParameters.getOptimizer().getProblem().initializeProblem();
|
||||
this.optimizationParameters.getOptimizer().addPopulationChangedEventListener(null);
|
||||
this.optimizationParameters.getOptimizer().setPopulation(this.backupPopulation);
|
||||
this.optimizationParameters.getOptimizer().getProblem().evaluate(this.optimizationParameters.getOptimizer().getPopulation());
|
||||
this.optimizationParameters.getOptimizer().getProblem().evaluate(this.optimizationParameters.getOptimizer().getPopulation().getArchive());
|
||||
this.optimizationParameters.getOptimizer().initializeByPopulation(this.backupPopulation, false);
|
||||
this.optimizationParameters.getOptimizer().getPopulation().setFunctionCalls(0);
|
||||
this.optimizationParameters.addPopulationChangedEventListener(this);
|
||||
} else {
|
||||
this.recentFunctionCalls = 0;
|
||||
this.optimizationParameters.getOptimizer().initialize();
|
||||
}
|
||||
//while (this.optimizationParameters.getOptimizer().getPopulation().getFunctionCalls() < this.functionCalls) {
|
||||
while (!this.optimizationParameters.getTerminator().isTerminated(this.optimizationParameters.getOptimizer().getPopulation())) {
|
||||
//System.out.println("Simulated Function calls "+ this.optimizer.getPopulation().getFunctionCalls());
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
optimizationParameters.getOptimizer().optimize();
|
||||
}
|
||||
System.gc();
|
||||
// @TODO if you want the final report include this
|
||||
//this.writeToFile(this.optimizationParameters.getProblem().getStringRepresentationForProblem(this.optimizationParameters.getOptimizer()));
|
||||
tmpMultiRun.add(this.tmpData);
|
||||
}
|
||||
if (this.show) {
|
||||
this.plot.setInfoString(this.currentExperiment, this.experimentName, 0.5f);
|
||||
}
|
||||
if (this.show) {
|
||||
this.draw();
|
||||
}
|
||||
this.experimentName = this.optimizationParameters.getOptimizer().getName() + "-" + this.performedRuns.size();
|
||||
} catch (InterruptedException e) {
|
||||
updateStatus(0);
|
||||
if (this.show) {
|
||||
this.statusField.setText("Interrupted...");
|
||||
}
|
||||
return "Interrupted";
|
||||
}
|
||||
if (this.outputFile != null) {
|
||||
try {
|
||||
this.outputFile.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Failed to close output file!");
|
||||
}
|
||||
}
|
||||
if (this.show) {
|
||||
for (int i = 0; i < this.multiRuns; i++) {
|
||||
this.plot.clearGraph(1000 + i);
|
||||
}
|
||||
}
|
||||
updateStatus(0);
|
||||
if (this.show) {
|
||||
this.statusField.setText("Finished...");
|
||||
}
|
||||
return "All Done";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method refreshes the plot
|
||||
*/
|
||||
private void draw() {
|
||||
ArrayList multiRuns, singleRun;
|
||||
Double[] tmpD;
|
||||
double[][] data;
|
||||
// Color tmpColor;
|
||||
|
||||
for (int i = this.performedRuns.size() - 1; i < this.performedRuns.size(); i++) {
|
||||
multiRuns = (ArrayList) this.performedRuns.get(i);
|
||||
// determine minimum run length
|
||||
int minRunLen = Integer.MAX_VALUE;
|
||||
for (int j = 0; j < multiRuns.size(); j++) {
|
||||
singleRun = (ArrayList) multiRuns.get(j);
|
||||
// tmpD = (Double[])singleRun.get(singleRun.size()-1);
|
||||
minRunLen = Math.min(minRunLen, singleRun.size());
|
||||
}
|
||||
|
||||
data = new double[minRunLen][3];
|
||||
// First run to determine mean
|
||||
for (int j = 0; j < multiRuns.size(); j++) {
|
||||
singleRun = (ArrayList) multiRuns.get(j);
|
||||
for (int p = 0; p < data.length; p++) {
|
||||
tmpD = (Double[]) singleRun.get(p);
|
||||
data[p][0] = tmpD[0];
|
||||
data[p][1] += tmpD[1] / multiRuns.size();
|
||||
}
|
||||
}
|
||||
// Second run to determine variance
|
||||
for (int j = 0; j < multiRuns.size(); j++) {
|
||||
singleRun = (ArrayList) multiRuns.get(j);
|
||||
for (int p = 0; p < data.length; p++) {
|
||||
tmpD = (Double[]) singleRun.get(p);
|
||||
data[p][2] += Math.pow(data[p][1] - tmpD[1], 2) / multiRuns.size();
|
||||
}
|
||||
}
|
||||
// Now enter this stuff into the graph
|
||||
this.plot.clearGraph(this.currentExperiment);
|
||||
|
||||
for (int j = 0; j < data.length; j++) {
|
||||
if (this.continueFlag) {
|
||||
this.plot.setConnectedPoint(data[j][0] + this.recentFunctionCalls, data[j][1], this.currentExperiment);
|
||||
} else {
|
||||
this.plot.setConnectedPoint(data[j][0], data[j][1], this.currentExperiment);
|
||||
}
|
||||
}
|
||||
this.currentExperiment++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the worker needs to update the GUI we do so by queuing a Runnable
|
||||
* for the event dispatching thread with SwingUtilities.invokeLater(). In
|
||||
* this case we're just changing the progress bars value.
|
||||
*/
|
||||
void updateStatus(final int i) {
|
||||
if (this.progressBar != null) {
|
||||
Runnable doSetProgressBarValue = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressBar.setValue(i);
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(doSetProgressBarValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will create a new instance of LectureGUI and will call show()
|
||||
* to create the necessary frames. This method will ignore all arguments.
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
StandaloneOptimization program = new StandaloneOptimization();
|
||||
RNG.setRandomSeed(1);
|
||||
program.initFrame();
|
||||
program.setShow(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShow(boolean t) {
|
||||
this.show = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows an optimizer to register a change in the optimizer.
|
||||
*
|
||||
* @param source The source of the event.
|
||||
* @param name Could be used to indicate the nature of the event.
|
||||
*/
|
||||
@Override
|
||||
public void registerPopulationStateChanged(Object source, String name) {
|
||||
if (name.equals(Population.NEXT_GENERATION_PERFORMED)) {
|
||||
Population population = ((InterfaceOptimizer) source).getPopulation();
|
||||
double x = 100 / this.multiRuns;
|
||||
if (this.optimizationParameters.getTerminator() instanceof EvaluationTerminator) {
|
||||
double y = x / (double) ((EvaluationTerminator) this.optimizationParameters.getTerminator()).getFitnessCalls();
|
||||
currentProgress = (int) (this.currentRun * x + population.getFunctionCalls() * y);
|
||||
} else {
|
||||
currentProgress = (int) (this.currentRun * x);
|
||||
}
|
||||
updateStatus(currentProgress);
|
||||
|
||||
// data to be stored in file
|
||||
double tmpd = 0;
|
||||
StringBuilder tmpLine = new StringBuilder("");
|
||||
tmpLine.append(population.getFunctionCalls());
|
||||
tmpLine.append("\t");
|
||||
tmpLine.append(population.getBestEAIndividual().getFitness(0));
|
||||
tmpLine.append("\t");
|
||||
for (int i = 0; i < population.size(); i++) {
|
||||
tmpd += population.get(i).getFitness(0) / (double) population.size();
|
||||
}
|
||||
tmpLine.append("\t");
|
||||
tmpLine.append(tmpd);
|
||||
tmpLine.append("\t");
|
||||
tmpLine.append(population.getWorstEAIndividual().getFitness(0));
|
||||
//tmpLine.append("\t");
|
||||
//tmpLine.append(this.optimizationParameters.getProblem().getAdditionalDataValue(population));
|
||||
this.writeToFile(tmpLine.toString());
|
||||
|
||||
Double[] tmpData = new Double[2];
|
||||
tmpData[0] = (double) population.getFunctionCalls();
|
||||
// instead of adding simply the best fitness value i'll ask the problem what to show
|
||||
tmpData[1] = this.optimizationParameters.getProblem().getDoublePlotValue(population);
|
||||
if (this.plot != null) {
|
||||
if (this.continueFlag) {
|
||||
this.plot.setConnectedPoint(tmpData[0] + this.recentFunctionCalls, tmpData[1].doubleValue(), 1000 + this.currentRun);
|
||||
} else {
|
||||
this.plot.setConnectedPoint(tmpData[0].doubleValue(), tmpData[1].doubleValue(), 1000 + this.currentRun);
|
||||
}
|
||||
}
|
||||
this.tmpData.add(tmpData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method writes Data to file.
|
||||
*
|
||||
* @param line The line that is to be added to the file
|
||||
*/
|
||||
private void writeToFile(String line) {
|
||||
String write = line + "\n";
|
||||
if (this.outputFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.outputFile.write(write, 0, write.length());
|
||||
this.outputFile.flush();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Problems writing to output file!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the CommonJavaObjectEditorPanel to read the name to
|
||||
* the current object.
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return "EA Lecture GUI";
|
||||
}
|
||||
|
||||
/**
|
||||
* ********************************************************************************************************************
|
||||
* These are for GUI
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method allows you to set the number of mulitruns that are to be
|
||||
* performed, necessary for stochastic optimizers to ensure reliable
|
||||
* results.
|
||||
*
|
||||
* @param multiruns The number of multiruns that are to be performed
|
||||
*/
|
||||
public void setMultiRuns(int multiruns) {
|
||||
this.multiRuns = multiruns;
|
||||
}
|
||||
|
||||
public int getMultiRuns() {
|
||||
return this.multiRuns;
|
||||
}
|
||||
|
||||
public String multiRunsTipText() {
|
||||
return "Multiple runs may be necessary to produce reliable results for stochastic optimizing algorithms.";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to set the seed for the random number generator.
|
||||
*
|
||||
* @param seed The seed for the random number generator
|
||||
*/
|
||||
// MK: These methods have nothing to do with the seed parameter from the optimizationParameters object which is actually used, so I comment them out
|
||||
// public void setRandomSeed(long seed) {
|
||||
// RNG.setseed(seed);
|
||||
// }
|
||||
// public long getRandomSeed() {
|
||||
// return RNG.getRandomSeed();
|
||||
// }
|
||||
// public String seedTipText() {
|
||||
// return "Choose the seed for the random number generator.";
|
||||
// }
|
||||
|
||||
/**
|
||||
* This method sets the name of the current experiment as it will occur in
|
||||
* the plot legend.
|
||||
*
|
||||
* @param experimentName The experiment name
|
||||
*/
|
||||
public void setExpName(String experimentName) {
|
||||
this.experimentName = experimentName;
|
||||
}
|
||||
|
||||
public String getExpName() {
|
||||
return this.experimentName;
|
||||
}
|
||||
|
||||
public String expNameTipText() {
|
||||
return "Set the name of the experiment as it will occur in the legend.";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the output filename
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setOutputFileName(String name) {
|
||||
this.outputFileName = name;
|
||||
}
|
||||
|
||||
public String getOutputFileName() {
|
||||
return this.outputFileName;
|
||||
}
|
||||
|
||||
public String outputFileNameTipText() {
|
||||
return "Set the name for the output file, if 'none' no output file will be created.";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the output filename
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setList(List name) {
|
||||
this.list = name;
|
||||
}
|
||||
|
||||
public List getList() {
|
||||
return this.list;
|
||||
}
|
||||
|
||||
public String listTipText() {
|
||||
return "Set the name for the output file, if 'none' no output file will be created.";
|
||||
}
|
||||
}
|
||||
145
src/main/java/eva2/gui/SwingWorker.java
Normal file
145
src/main/java/eva2/gui/SwingWorker.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* This is the 3rd version of SwingWorker (also known as
|
||||
* SwingWorker 3), an abstract class that you subclass to
|
||||
* perform GUI-related work in a dedicated thread. For
|
||||
* instructions on using this class, see:
|
||||
* <p>
|
||||
* http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html
|
||||
* or
|
||||
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
|
||||
* <p>
|
||||
* Note that the API changed slightly in the 3rd version:
|
||||
* You must now invoke start() on the SwingWorker after
|
||||
* creating it.
|
||||
*/
|
||||
|
||||
public abstract class SwingWorker {
|
||||
private Object value; // see getValue(), setValue()
|
||||
private Thread thread;
|
||||
|
||||
/**
|
||||
* Class to maintain reference to current worker thread
|
||||
* under separate synchronization control.
|
||||
*/
|
||||
private static class ThreadVar {
|
||||
private Thread thread;
|
||||
|
||||
ThreadVar(Thread t) {
|
||||
thread = t;
|
||||
}
|
||||
|
||||
synchronized Thread get() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
synchronized void clear() {
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadVar threadVar;
|
||||
|
||||
/**
|
||||
* Get the value produced by the worker thread, or null if it
|
||||
* hasn't been constructed yet.
|
||||
*/
|
||||
protected synchronized Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value produced by worker thread
|
||||
*/
|
||||
private synchronized void setValue(Object x) {
|
||||
value = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the value to be returned by the <code>get</code> method.
|
||||
*/
|
||||
public abstract Object construct();
|
||||
|
||||
/**
|
||||
* Called on the event dispatching thread (not on the worker thread)
|
||||
* after the <code>construct</code> method has returned.
|
||||
*/
|
||||
public void finished() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value created by the <code>construct</code> method.
|
||||
* Returns null if either the constructing thread or the current
|
||||
* thread was interrupted before a value was produced.
|
||||
*
|
||||
* @return the value created by the <code>construct</code> method
|
||||
*/
|
||||
public Object get() {
|
||||
while (true) {
|
||||
Thread t = threadVar.get();
|
||||
if (t == null) {
|
||||
return getValue();
|
||||
}
|
||||
try {
|
||||
t.join();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt(); // propagate
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a thread that will call the <code>construct</code> method
|
||||
* and then exit.
|
||||
*/
|
||||
public SwingWorker() {
|
||||
final Runnable doFinished = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finished();
|
||||
}
|
||||
};
|
||||
|
||||
Runnable doConstruct = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setValue(construct());
|
||||
} finally {
|
||||
threadVar.clear();
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(doFinished);
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(doConstruct);
|
||||
threadVar = new ThreadVar(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the worker thread.
|
||||
*/
|
||||
public void start() {
|
||||
Thread t = threadVar.get();
|
||||
if (t != null) {
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A new method that interrupts the worker thread. Call this method
|
||||
* to force the worker to stop what it's doing.
|
||||
*/
|
||||
public void interrupt() {
|
||||
Thread t = threadVar.get();
|
||||
if (t != null) {
|
||||
t.interrupt();
|
||||
}
|
||||
threadVar.clear();
|
||||
}
|
||||
}
|
||||
295
src/main/java/eva2/gui/TabbedFrameMaker.java
Normal file
295
src/main/java/eva2/gui/TabbedFrameMaker.java
Normal file
@@ -0,0 +1,295 @@
|
||||
package eva2.gui;
|
||||
|
||||
import eva2.optimization.InterfaceNotifyOnInformers;
|
||||
import eva2.problems.InterfaceAdditionalPopulationInformer;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Produces the main EvA2 frame and a tool bar instance.
|
||||
*/
|
||||
public class TabbedFrameMaker implements Serializable, PanelMaker, InterfaceNotifyOnInformers {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(TabbedFrameMaker.class.getName());
|
||||
private static final long serialVersionUID = 2637376545826821423L;
|
||||
private ArrayList<PanelMaker> pmContainer = null;
|
||||
private JExtToolBar extToolBar;
|
||||
ModuleButtonPanelMaker butPanelMkr = null;
|
||||
private JTabbedPane tabbedPane;
|
||||
|
||||
public TabbedFrameMaker() {
|
||||
pmContainer = null;
|
||||
}
|
||||
|
||||
public void addPanelMaker(PanelMaker pm) {
|
||||
if (pmContainer == null) {
|
||||
pmContainer = new ArrayList<>(2);
|
||||
}
|
||||
pmContainer.add(pm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPanel makePanel() {
|
||||
JPanel tabControlPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
gbConstraints.gridy = 0;
|
||||
|
||||
tabbedPane = new JTabbedPane();
|
||||
tabbedPane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
|
||||
//tabbedPane.setUI(new eva2.gui.utils.CustomTabbedPaneUI());
|
||||
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
|
||||
|
||||
/* This toolbar will hold the closed tabs */
|
||||
JToolBar tabToolBar = new JToolBar(JToolBar.VERTICAL);
|
||||
tabToolBar.setFloatable(false);
|
||||
|
||||
/* ToDo: The control buttons shouldn't be added here.. */
|
||||
extToolBar = new JExtToolBar();
|
||||
extToolBar.setFloatable(false);
|
||||
|
||||
for (PanelMaker element : pmContainer) {
|
||||
JComponent panel = element.makePanel();
|
||||
if (element instanceof ModuleButtonPanelMaker) {
|
||||
extToolBar.add(panel);
|
||||
butPanelMkr = (ModuleButtonPanelMaker) element;
|
||||
} else if (element instanceof JParaPanel) {
|
||||
tabbedPane.addTab(((JParaPanel) element).getName(), panel);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
|
||||
tabbedPane.setTabComponentAt(i, new ClosableTabComponent(tabbedPane, tabToolBar));
|
||||
}
|
||||
|
||||
gbConstraints.weighty = 1.0;
|
||||
gbConstraints.gridx = 0;
|
||||
tabControlPanel.add(tabToolBar, gbConstraints);
|
||||
gbConstraints.gridx = 1;
|
||||
tabControlPanel.add(tabbedPane, gbConstraints);
|
||||
tabbedPane.validate();
|
||||
return tabControlPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The toolbar with control buttons
|
||||
* @deprecated
|
||||
*/
|
||||
public JExtToolBar getToolBar() {
|
||||
return extToolBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulate pressing the start button.
|
||||
*/
|
||||
public void onUserStart() {
|
||||
if (butPanelMkr != null) {
|
||||
butPanelMkr.onUserStart();
|
||||
} else {
|
||||
System.err.println("Error: button panel was null (TabbedFrameMaker)");
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshPanels() {
|
||||
for (PanelMaker jpp : pmContainer) {
|
||||
if (jpp instanceof JParaPanel) {
|
||||
((JParaPanel) jpp).propertyEditor.setValue(((JParaPanel) jpp).propertyEditor.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInformers(List<InterfaceAdditionalPopulationInformer> informers) {
|
||||
// if the informers have changed, update the GUI element which displays them
|
||||
try {
|
||||
JParaPanel statsPan = getStatsPanel();
|
||||
if (statsPan.propertyEditor != null) {
|
||||
// really update the contents of the stats panel
|
||||
statsPan.propertyEditor.setValue(statsPan.propertyEditor.getValue());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to update statistics panel from " + this.getClass());
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public JParaPanel getOptimizationParametersPanel() {
|
||||
try {
|
||||
JParaPanel sP = (JParaPanel) pmContainer.get(1);
|
||||
return sP;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to get OptimizationParameters panel from " + this.getClass());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public JParaPanel getStatsPanel() {
|
||||
try {
|
||||
JParaPanel sP = (JParaPanel) pmContainer.get(2);
|
||||
return sP;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to get statistics panel from " + this.getClass());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to be used as tabComponent;
|
||||
* Contains a JLabel to show the text and
|
||||
* a JButton to close the tab it belongs to
|
||||
*/
|
||||
class ClosableTabComponent extends JPanel {
|
||||
private final JTabbedPane pane;
|
||||
private final JToolBar toolBar;
|
||||
|
||||
public ClosableTabComponent(final JTabbedPane pane, final JToolBar toolBar) {
|
||||
super(new FlowLayout(FlowLayout.LEADING, 0, 0));
|
||||
|
||||
if (pane == null) {
|
||||
throw new NullPointerException("TabbedPane is null");
|
||||
}
|
||||
this.pane = pane;
|
||||
this.toolBar = toolBar;
|
||||
this.toolBar.setVisible(false);
|
||||
setOpaque(false);
|
||||
|
||||
//make JLabel read titles from JTabbedPane
|
||||
JLabel label = new JLabel() {
|
||||
@Override
|
||||
public String getText() {
|
||||
int index = pane.indexOfTabComponent(ClosableTabComponent.this);
|
||||
if (index != -1) {
|
||||
return pane.getTitleAt(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
add(label);
|
||||
//add more space between the label and the button
|
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
//tab button
|
||||
JButton button = new TabButton();
|
||||
|
||||
add(button);
|
||||
//add more space to the top of the component
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
|
||||
}
|
||||
|
||||
private class TabButton extends JButton implements ActionListener {
|
||||
public TabButton() {
|
||||
int size = 17;
|
||||
setPreferredSize(new Dimension(size, size));
|
||||
setToolTipText("Hide this Tab");
|
||||
//Make the button looks the same for all Laf's
|
||||
setUI(new BasicButtonUI());
|
||||
//Make it transparent
|
||||
setContentAreaFilled(false);
|
||||
//No need to be focusable
|
||||
setFocusable(false);
|
||||
setBorder(BorderFactory.createEtchedBorder());
|
||||
setBorderPainted(false);
|
||||
//Making nice rollover effect
|
||||
//we use the same listener for all buttons
|
||||
addMouseListener(buttonMouseListener);
|
||||
setRolloverEnabled(true);
|
||||
//Close the proper tab by clicking the button
|
||||
addActionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int i = pane.indexOfTabComponent(ClosableTabComponent.this);
|
||||
if (i != -1) {
|
||||
final String tabTitle = pane.getTitleAt(i);
|
||||
final Component tabPane = pane.getComponentAt(i);
|
||||
final int tabPosition = i;
|
||||
|
||||
pane.remove(i);
|
||||
if (pane.getTabCount() == 0) {
|
||||
pane.setVisible(false);
|
||||
}
|
||||
/* Create a button to be shown in the ToolBar */
|
||||
JButton tabButton = new JButton(tabTitle);
|
||||
/* Rotate it by -90° */
|
||||
tabButton.setUI(new eva2.gui.utils.VerticalButtonUI(-90));
|
||||
tabButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
/* Add the Tab Panel again */
|
||||
// ToDo: Fix indexing problem
|
||||
pane.insertTab(tabTitle, null, tabPane, "", tabPosition);
|
||||
/* Set the tab component (closable) */
|
||||
pane.setTabComponentAt(tabPosition, ClosableTabComponent.this);
|
||||
pane.setVisible(true);
|
||||
/* Remove the Button */
|
||||
toolBar.remove((Component) e.getSource());
|
||||
/* If the Button was the last one, hide ToolBar again */
|
||||
if (toolBar.getComponentCount() == 0) {
|
||||
toolBar.setVisible(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
/* Add it to the ToolBar */
|
||||
if (!toolBar.isVisible()) {
|
||||
toolBar.setVisible(true);
|
||||
}
|
||||
toolBar.add(tabButton);
|
||||
}
|
||||
}
|
||||
|
||||
//we don't want to update UI for this button
|
||||
@Override
|
||||
public void updateUI() {
|
||||
}
|
||||
|
||||
//paint the cross
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
//shift the image for pressed buttons
|
||||
if (getModel().isPressed()) {
|
||||
g2.translate(1, 1);
|
||||
}
|
||||
g2.setStroke(new BasicStroke(2));
|
||||
g2.setColor(Color.BLACK);
|
||||
int delta = 6;
|
||||
g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
|
||||
g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private final static MouseListener buttonMouseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
Component component = e.getComponent();
|
||||
if (component instanceof AbstractButton) {
|
||||
AbstractButton button = (AbstractButton) component;
|
||||
button.setBorderPainted(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
90
src/main/java/eva2/gui/TreeNode.java
Normal file
90
src/main/java/eva2/gui/TreeNode.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
|
||||
/**
|
||||
* The node class for the EvA2 tree view panel. Each node contains a parameter object.
|
||||
* Typically, the tree hierarchy starts with a
|
||||
* OptimizationParameters object, however this is not necessary.
|
||||
* The tree is constructed using the reflection functionality of PropertySheetPanel
|
||||
* which is also used to generate the nested panels for parameter configuration.
|
||||
*
|
||||
* @author mkron
|
||||
* @see PropertySheetPanel
|
||||
* @see eva2.optimization.OptimizationParameters
|
||||
*/
|
||||
public class TreeNode extends DefaultMutableTreeNode {
|
||||
private String[] childrenNames = null;
|
||||
private Object[] childrenValues = null;
|
||||
private String myName = "TreeNode";
|
||||
private boolean doListPrimitives = false;
|
||||
|
||||
/**
|
||||
* A default constructor setting the name and target object of
|
||||
* the tree. The children are generated immediately.
|
||||
* The node label is constructed from the name String and the
|
||||
* information retrieved from the target object if it implements the getName method.
|
||||
*
|
||||
* @param name title of the node
|
||||
* @param target
|
||||
*/
|
||||
public TreeNode(String name, Object target) {
|
||||
super(target);
|
||||
myName = name;
|
||||
setObject(target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the target object of the tree. Note that the name is not automatically
|
||||
* updated and may be out of date if the new target object is incompatible to the
|
||||
* old name.
|
||||
*
|
||||
* @param target the new target object
|
||||
* @param expand should be true to generate child nodes immediately
|
||||
*/
|
||||
public void setObject(Object target, boolean expand) {
|
||||
super.setUserObject(target);
|
||||
childrenNames = PropertySheetPanel.getPropertyNames(target);
|
||||
childrenValues = PropertySheetPanel.getPropertyValues(target, true, true, true);
|
||||
super.removeAllChildren();
|
||||
if (expand) {
|
||||
initChildren();
|
||||
}
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually create child nodes.
|
||||
*/
|
||||
private void initChildren() {
|
||||
for (int i = 0; i < childrenValues.length; i++) {
|
||||
if (childrenValues[i] != null) {
|
||||
if (doListPrimitives || !(BeanInspector.isJavaPrimitive(childrenValues[i].getClass()))) {
|
||||
super.add(new TreeNode(childrenNames[i], childrenValues[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String extendedInfo = null;
|
||||
try {
|
||||
extendedInfo = (String) BeanInspector.callIfAvailable(this.getUserObject(), "getName", new Object[]{});
|
||||
} catch (Exception e) {
|
||||
extendedInfo = null;
|
||||
}
|
||||
if (extendedInfo != null) {
|
||||
return myName + " - " + extendedInfo;
|
||||
} else {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/main/java/eva2/gui/TreeSelectionListener.java
Normal file
67
src/main/java/eva2/gui/TreeSelectionListener.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package eva2.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
* Listener for use with the TreeNode class. It implements both the tree selection listener
|
||||
* to react to selection changes in the tree view (and update the parameter panel),
|
||||
* and the property change listener to
|
||||
* react to changes in the parameters (and update the tree).
|
||||
*
|
||||
* @author mkron
|
||||
*/
|
||||
public class TreeSelectionListener implements javax.swing.event.TreeSelectionListener, PropertyChangeListener {
|
||||
private PropertyEditor goe = null;
|
||||
private TreeNode root = null;
|
||||
private JTree jtree = null;
|
||||
|
||||
/**
|
||||
* Create a tree listener and hook it up in the editor to listen to parameter changes
|
||||
* and in the JTree to update it.
|
||||
*
|
||||
* @param rootNode the root node of the tree
|
||||
* @param goEditor the editor containing the parameter panel
|
||||
* @param jt the GUI view of the tree
|
||||
*/
|
||||
public TreeSelectionListener(TreeNode rootNode, PropertyEditor goEditor, JTree jt) {
|
||||
goe = goEditor;
|
||||
root = rootNode;
|
||||
jtree = jt;
|
||||
|
||||
if (jtree != null) {
|
||||
jtree.addTreeSelectionListener(this);
|
||||
} // listen to tree selection changes
|
||||
if (goEditor != null) {
|
||||
goEditor.addPropertyChangeListener(this);
|
||||
} // listen to changes to the parameters
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
TreePath tp = e.getPath();
|
||||
|
||||
TreeNode leafNode = (TreeNode) tp.getLastPathComponent();
|
||||
Component editComp = goe.getCustomEditor();
|
||||
if (editComp instanceof OptimizationEditorPanel) {
|
||||
// update the object in the main OptimizationEditorPanel
|
||||
((OptimizationEditorPanel) editComp).setTarget(leafNode.getUserObject());
|
||||
} else {
|
||||
System.err.println("Error, unable to notify custom editor of type " + editComp.getClass() + ", expected OptimizationEditorPanel (TreeSelectionListener)");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
root.setObject(evt.getNewValue(), true);
|
||||
if (jtree != null) {
|
||||
jtree.setModel(new DefaultTreeModel(root));
|
||||
} // TODO this should be done differently so that the tree is not collapsed on each change!
|
||||
}
|
||||
}
|
||||
226
src/main/java/eva2/gui/editor/AbstractListSelectionEditor.java
Normal file
226
src/main/java/eva2/gui/editor/AbstractListSelectionEditor.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*/
|
||||
public abstract class AbstractListSelectionEditor extends JPanel implements PropertyEditor, PropertyChangeListener {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
protected JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
|
||||
/**
|
||||
* The graphics stuff
|
||||
*/
|
||||
private JPanel customEditor, nodePanel;
|
||||
protected JCheckBox[] blackCheck;
|
||||
|
||||
|
||||
public AbstractListSelectionEditor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
this.customEditor.add(new JLabel("Choose:"), BorderLayout.NORTH);
|
||||
this.nodePanel = new JPanel();
|
||||
this.customEditor.add(new JScrollPane(this.nodePanel), BorderLayout.CENTER);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of elements in the list.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract int getElementCount();
|
||||
|
||||
/**
|
||||
* Get the display name of an element.
|
||||
*
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
protected abstract String getElementName(int i);
|
||||
|
||||
/**
|
||||
* Get the tool tip of an element or null if none is available.
|
||||
*
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
protected String getElementToolTip(int i) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selection state of an element.
|
||||
*
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean isElementSelected(int i);
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor. This notifies change listeners automatically.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.nodePanel != null) {
|
||||
this.nodePanel.removeAll();
|
||||
this.nodePanel.setLayout(new GridLayout(getElementCount(), 1));
|
||||
this.blackCheck = new JCheckBox[getElementCount()];
|
||||
for (int i = 0; i < getElementCount(); i++) {
|
||||
this.blackCheck[i] = new JCheckBox(getElementName(i), isElementSelected(i));
|
||||
this.blackCheck[i].setToolTipText(getElementToolTip(i));
|
||||
this.blackCheck[i].addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
if (actionOnSelect()) {
|
||||
propertyChangeSupport.firePropertyChange("AbstractListSelectionEditor", null, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.nodePanel.add(this.blackCheck[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions when the selection state changes. Return true if there was an actual change.
|
||||
*/
|
||||
protected abstract boolean actionOnSelect();
|
||||
|
||||
/**
|
||||
* Set the base object, return true on success. Make sure that the editor instance is
|
||||
* added as a listener to the object (if supported).
|
||||
*
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
protected abstract boolean setObject(Object o);
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (setObject(o)) {
|
||||
updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public abstract Object getValue();
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Select from list";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
propertyChangeSupport.firePropertyChange("AbstractListSelectionEditor", null, this);
|
||||
}
|
||||
}
|
||||
62
src/main/java/eva2/gui/editor/AreaEditor.java
Normal file
62
src/main/java/eva2/gui/editor/AreaEditor.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.optimization.individuals.codings.gp.AbstractGPNode;
|
||||
import eva2.optimization.individuals.codings.gp.GPArea;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class AreaEditor extends AbstractListSelectionEditor {
|
||||
/**
|
||||
* The GPArea that is to be edited
|
||||
*/
|
||||
private GPArea areaObject;
|
||||
|
||||
public AreaEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getElementCount() {
|
||||
return areaObject.getCompleteList().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementName(int i) {
|
||||
AbstractGPNode an = areaObject.getCompleteList().get(i);
|
||||
return an.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isElementSelected(int i) {
|
||||
return areaObject.getBlackList().get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean actionOnSelect() {
|
||||
/** This method checks the current BlackList and compiles it
|
||||
* to a new ReducedList.
|
||||
*/
|
||||
for (int i = 0; i < this.blackCheck.length; i++) {
|
||||
this.areaObject.setBlackListElement(i, this.blackCheck[i].isSelected());
|
||||
}
|
||||
this.areaObject.compileReducedList();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setObject(Object o) {
|
||||
if (o instanceof GPArea) {
|
||||
this.areaObject = (GPArea) o;
|
||||
areaObject.addPropertyChangeListener(this);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.areaObject;
|
||||
}
|
||||
}
|
||||
789
src/main/java/eva2/gui/editor/ArrayEditor.java
Normal file
789
src/main/java/eva2/gui/editor/ArrayEditor.java
Normal file
@@ -0,0 +1,789 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.*;
|
||||
import eva2.tools.SerializedObject;
|
||||
import eva2.tools.StringTools;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ArrayEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(ArrayEditor.class.getName());
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel cantEditLabel = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The list component displaying current values
|
||||
*/
|
||||
private JList elementList = new JList();
|
||||
/**
|
||||
* The class of objects allowed in the array
|
||||
*/
|
||||
private Class elementClass = String.class;
|
||||
/**
|
||||
* The defaultlistmodel holding our data
|
||||
*/
|
||||
private DefaultListModel listModel;
|
||||
/**
|
||||
* The property editor for the class we are editing
|
||||
*/
|
||||
private PropertyEditor elementEditor;
|
||||
/**
|
||||
* Cheat to handle selectable lists as well
|
||||
*/
|
||||
private PropertySelectableList selectableList = null;
|
||||
/**
|
||||
* Click this to delete the selected array values
|
||||
*/
|
||||
private JButton deleteButton = new JButton("Delete");
|
||||
/**
|
||||
* list of additional buttons above the list
|
||||
*/
|
||||
private List<JButton> upperButtonList = new LinkedList<>();
|
||||
/**
|
||||
* list of additional buttons below the list
|
||||
*/
|
||||
private List<JButton> lowerButtonList = new LinkedList<>();
|
||||
private JComponent additionalCenterComp = null;
|
||||
private List<JMenuItem> popupItemList = new LinkedList<>();
|
||||
private JButton addButton = new JButton("Add");
|
||||
private JButton setButton = new JButton("Set");
|
||||
private JButton setAllButton = new JButton("Set all");
|
||||
private boolean withAddButton = true;
|
||||
private boolean withSetButton = true;
|
||||
private boolean withDeleteButton = true;
|
||||
private Component view = null;
|
||||
/**
|
||||
* Listens to buttons being pressed and taking the appropriate action
|
||||
*/
|
||||
private ActionListener innerActionListener = new ActionListener() {
|
||||
//
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
boolean consistentView = true; // be optimistic...
|
||||
if (view instanceof PropertyText) { // check consistency!
|
||||
consistentView = ((PropertyText) view).checkConsistency();
|
||||
if (!consistentView) {
|
||||
((PropertyText) view).updateFromEditor();
|
||||
}
|
||||
}
|
||||
if (e.getSource() == deleteButton) {
|
||||
int[] selected = elementList.getSelectedIndices();
|
||||
if (selected != null) {
|
||||
for (int i = selected.length - 1; i >= 0; i--) {
|
||||
int current = selected[i];
|
||||
listModel.removeElementAt(current);
|
||||
if (listModel.size() > current) {
|
||||
elementList.setSelectedIndex(current);
|
||||
}
|
||||
elementList.setModel(listModel);
|
||||
}
|
||||
|
||||
if (selectableList != null) {
|
||||
selectableList.setObjects(modelToArray(selectableList.getObjects(), listModel));
|
||||
}
|
||||
propChangeSupport.firePropertyChange("", null, null);
|
||||
}
|
||||
if (elementList.getSelectedIndex() == -1) {
|
||||
deleteButton.setEnabled(false);
|
||||
}
|
||||
} else if (e.getSource() == addButton) {
|
||||
int selected = elementList.getSelectedIndex();
|
||||
Object addObj = elementEditor.getValue();
|
||||
|
||||
// Make a full copy of the object using serialization
|
||||
try {
|
||||
SerializedObject so = new SerializedObject(addObj);
|
||||
addObj = so.getObject();
|
||||
so = null;
|
||||
if (selected != -1) {
|
||||
listModel.insertElementAt(addObj, selected);
|
||||
} else {
|
||||
listModel.addElement(addObj);
|
||||
}
|
||||
elementList.setModel(listModel);
|
||||
if (selectableList != null) {
|
||||
selectableList.setObjects(modelToArray(selectableList.getObjects(), listModel));
|
||||
}
|
||||
propChangeSupport.firePropertyChange("", null, null);
|
||||
} catch (Exception ex) {
|
||||
JOptionPane.showMessageDialog(ArrayEditor.this, "Could not create an object copy", null, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} else if (e.getSource() == setAllButton) {
|
||||
Object addObj = elementEditor.getValue();
|
||||
for (int i = 0; i < listModel.size(); i++) {
|
||||
try {
|
||||
listModel.setElementAt(new SerializedObject(addObj).getObject(), i);
|
||||
} catch (Exception e1) {
|
||||
JOptionPane.showMessageDialog(ArrayEditor.this, "Could not create an object copy", null, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
propChangeSupport.firePropertyChange("", null, null);
|
||||
} else if (e.getSource() == setButton) {
|
||||
int selected = elementList.getSelectedIndex();
|
||||
Object addObj = elementEditor.getValue();
|
||||
if (selected >= 0 && (selected < listModel.size())) {
|
||||
try {
|
||||
listModel.setElementAt(new SerializedObject(addObj).getObject(), selected);
|
||||
} catch (Exception e1) {
|
||||
JOptionPane.showMessageDialog(ArrayEditor.this, "Could not create an object copy", null, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
propChangeSupport.firePropertyChange("", null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void setAdditionalCenterPane(JComponent component) {
|
||||
this.additionalCenterComp = component;
|
||||
}
|
||||
|
||||
private Object[] modelToArray(Object[] origArray, DefaultListModel listModel) {
|
||||
Class objClass = origArray.getClass().getComponentType();
|
||||
Object[] os = (Object[]) java.lang.reflect.Array.newInstance(objClass, listModel.size());
|
||||
|
||||
for (int i = 0; i < listModel.size(); i++) {
|
||||
os[i] = listModel.get(i);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to list items being selected and takes appropriate action
|
||||
*/
|
||||
private ListSelectionListener innerSelectionListener =
|
||||
new ListSelectionListener() {
|
||||
//
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
|
||||
if (e.getSource() == elementList) {
|
||||
// Enable the delete button
|
||||
if (elementList.getSelectedIndex() != -1) {
|
||||
deleteButton.setEnabled(true);
|
||||
elementEditor.setValue(elementList.getSelectedValue());
|
||||
if (view instanceof PropertyText) {
|
||||
((PropertyText) view).updateFromEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up the array editor.
|
||||
*/
|
||||
public ArrayEditor() {
|
||||
setLayout(new BorderLayout());
|
||||
add(cantEditLabel, BorderLayout.CENTER);
|
||||
deleteButton.addActionListener(innerActionListener);
|
||||
addButton.addActionListener(innerActionListener);
|
||||
setAllButton.addActionListener(innerActionListener);
|
||||
setButton.addActionListener(innerActionListener);
|
||||
elementList.addListSelectionListener(innerSelectionListener);
|
||||
addButton.setToolTipText("Add the current item to the list");
|
||||
deleteButton.setToolTipText("Delete the selected list item");
|
||||
elementList.addMouseListener(new ActionJList(elementList, this));
|
||||
}
|
||||
|
||||
public int[] getSelectedIndices() {
|
||||
return elementList.getSelectedIndices();
|
||||
}
|
||||
|
||||
private class ActionJList extends MouseAdapter {
|
||||
|
||||
protected JList list;
|
||||
ArrayEditor gae = null;
|
||||
|
||||
public ActionJList(JList l, ArrayEditor genAE) {
|
||||
list = l;
|
||||
gae = genAE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
int index = list.locationToIndex(e.getPoint());
|
||||
// Check if the index is valid and if the indexed cell really contains the clicked point
|
||||
if (index >= 0 && (list.getCellBounds(index, index).contains(e.getPoint()))) {
|
||||
PropertyPanel propPanel = null;
|
||||
Component comp = gae.view;
|
||||
if (comp instanceof PropertyPanel) {
|
||||
propPanel = (PropertyPanel) comp;
|
||||
} else {
|
||||
System.err.println("Error, invalid property panel in " + this.getClass());
|
||||
}
|
||||
ListModel dlm = list.getModel();
|
||||
Object item = dlm.getElementAt(index);
|
||||
list.ensureIndexIsVisible(index);
|
||||
propPanel.getEditor().setValue(item);
|
||||
propPanel.showDialog();
|
||||
propPanel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This class handles the creation of list cell renderers from the property editors.
|
||||
*/
|
||||
|
||||
private class EditorListCellRenderer implements ListCellRenderer {
|
||||
|
||||
/**
|
||||
* The class of the property editor for array objects
|
||||
*/
|
||||
private Class editorClass;
|
||||
/**
|
||||
* The class of the array values
|
||||
*/
|
||||
private Class valueClass;
|
||||
|
||||
/**
|
||||
* Creates the list cell renderer.
|
||||
*
|
||||
* @param editorClass The class of the property editor for array objects
|
||||
* @param valueClass The class of the array values
|
||||
*/
|
||||
public EditorListCellRenderer(Class editorClass, Class valueClass) {
|
||||
this.editorClass = editorClass;
|
||||
this.valueClass = valueClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cell rendering component.
|
||||
*
|
||||
* @param list the list that will be rendered in
|
||||
* @param value the cell value
|
||||
* @param index which element of the list to render
|
||||
* @param isSelected true if the cell is selected
|
||||
* @param cellHasFocus true if the cell has the focus
|
||||
* @return the rendering component
|
||||
*/
|
||||
@Override
|
||||
public Component getListCellRendererComponent(final JList list,
|
||||
final Object value,
|
||||
final int index,
|
||||
final boolean isSelected,
|
||||
final boolean cellHasFocus) {
|
||||
try {
|
||||
final PropertyEditor e = (PropertyEditor) editorClass.newInstance();
|
||||
if (e instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) e).setClassType(valueClass);
|
||||
}
|
||||
e.setValue(value);
|
||||
JPanel cellPanel = new JPanel() {
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
Insets i = this.getInsets();
|
||||
Rectangle box = new Rectangle(i.left, i.top,
|
||||
this.getWidth(), //- i.right,
|
||||
this.getHeight());//- i.bottom +20);
|
||||
g.setColor(isSelected ? list.getSelectionBackground() : list.getBackground());
|
||||
g.fillRect(0, 0, this.getWidth(), this.getHeight());
|
||||
g.setColor(isSelected ? list.getSelectionForeground() : list.getForeground());
|
||||
e.paintValue(g, box);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Font f = this.getFont();
|
||||
FontMetrics fm = this.getFontMetrics(f);
|
||||
Dimension newPref = new Dimension(0, fm.getHeight());
|
||||
newPref.height = getFontMetrics(getFont()).getHeight() * 6 / 4; //6 / 4;
|
||||
newPref.width = newPref.height * 6; //5
|
||||
return newPref;
|
||||
}
|
||||
};
|
||||
return cellPanel;
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the type of object being edited, so attempts to find an appropriate propertyeditor.
|
||||
*
|
||||
* @param obj a value of type 'Object'
|
||||
*/
|
||||
private void updateEditorType(Object obj) {
|
||||
|
||||
// Determine if the current object is an array
|
||||
elementEditor = null;
|
||||
listModel = null;
|
||||
view = null;
|
||||
removeAll();
|
||||
|
||||
if ((obj != null) && (obj.getClass().isArray() || (obj instanceof PropertySelectableList))) {
|
||||
Object arrayInstance = obj;
|
||||
if (!(obj.getClass().isArray())) {
|
||||
arrayInstance = ((PropertySelectableList) obj).getObjects();
|
||||
selectableList = (PropertySelectableList) obj;
|
||||
} else {
|
||||
selectableList = null;
|
||||
}
|
||||
Class elementClass = arrayInstance.getClass().getComponentType();
|
||||
PropertyEditor editor = PropertyEditorProvider.findEditor(elementClass);
|
||||
if (editor instanceof EnumEditor) {
|
||||
editor.setValue(obj);
|
||||
}
|
||||
view = null;
|
||||
ListCellRenderer lcr = new DefaultListCellRenderer();
|
||||
if (editor != null) {
|
||||
if (editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) editor).setClassType(elementClass);
|
||||
}
|
||||
if (editor.isPaintable() && editor.supportsCustomEditor()) {
|
||||
view = new PropertyPanel(editor);
|
||||
lcr = new EditorListCellRenderer(editor.getClass(), elementClass);
|
||||
} else if (editor.getTags() != null) {
|
||||
view = new PropertyValueSelector(editor);
|
||||
} else if (editor.getAsText() != null) {
|
||||
view = new PropertyText(editor);
|
||||
} else if (view == null) {
|
||||
/* Dirty hack to view PropertyDoubleArray component */
|
||||
view = new PropertyText(editor);
|
||||
}
|
||||
}
|
||||
if (view == null) {
|
||||
LOGGER.log(Level.WARNING, "No property editor for class: {0}", elementClass.getName());
|
||||
} else {
|
||||
elementEditor = editor;
|
||||
|
||||
// Create the ListModel and populate it
|
||||
listModel = new DefaultListModel();
|
||||
this.elementClass = elementClass;
|
||||
for (int i = 0; i < Array.getLength(arrayInstance); i++) {
|
||||
listModel.addElement(Array.get(arrayInstance, i));
|
||||
}
|
||||
|
||||
elementList.setCellRenderer(lcr);
|
||||
elementList.setModel(listModel);
|
||||
|
||||
if (listModel.getSize() > 0) {
|
||||
elementList.setSelectedIndex(0);
|
||||
deleteButton.setEnabled(true);
|
||||
} else {
|
||||
deleteButton.setEnabled(false);
|
||||
}
|
||||
|
||||
try {
|
||||
if (listModel.getSize() > 0) {
|
||||
elementEditor.setValue(listModel.getElementAt(0));
|
||||
} else {
|
||||
if (elementEditor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) elementEditor).setDefaultValue();
|
||||
} else {
|
||||
if (elementEditor.getValue() != null) {
|
||||
elementEditor.setValue(elementClass.newInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//setPreferredSize(new Dimension(400,500));
|
||||
|
||||
if (withAddButton && !(upperButtonList.contains(addButton))) {
|
||||
upperButtonList.add(addButton);
|
||||
}
|
||||
if (withSetButton && !(upperButtonList.contains(setButton))) {
|
||||
upperButtonList.add(setButton);
|
||||
}
|
||||
if (withSetButton && !(upperButtonList.contains(setAllButton))) {
|
||||
upperButtonList.add(setAllButton);
|
||||
}
|
||||
|
||||
// Upper Button Panel
|
||||
JPanel combiUpperPanel = new JPanel(getButtonLayout(0, upperButtonList));
|
||||
// ToDo Figure out how to now show this on Job Pane
|
||||
combiUpperPanel.add(view);
|
||||
view.setVisible(withAddButton);
|
||||
|
||||
for (JButton but : upperButtonList) {
|
||||
combiUpperPanel.add(but);
|
||||
}
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
add(combiUpperPanel, gbConstraints);
|
||||
|
||||
// Job List
|
||||
gbConstraints.gridy++;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 1.0;
|
||||
add(new JScrollPane(elementList), gbConstraints);
|
||||
|
||||
// Lower Button Panel
|
||||
if (withDeleteButton && !lowerButtonList.contains(deleteButton)) {
|
||||
lowerButtonList.add(deleteButton);
|
||||
}
|
||||
JPanel combiLowerPanel = new JPanel(getButtonLayout(0, lowerButtonList));
|
||||
for (JButton but : lowerButtonList) {
|
||||
combiLowerPanel.add(but);
|
||||
}
|
||||
gbConstraints.gridy++;
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 0.0;
|
||||
add(combiLowerPanel, gbConstraints);
|
||||
|
||||
// Additional Center Panel (e.g. PropertySheetPanel)
|
||||
if (additionalCenterComp != null) {
|
||||
gbConstraints.weightx = 1.0;
|
||||
gbConstraints.weighty = 1.0;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
gbConstraints.gridy++;
|
||||
add(additionalCenterComp, gbConstraints);
|
||||
}
|
||||
|
||||
elementEditor.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
addPopupMenu();
|
||||
} catch (Exception ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
elementEditor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (elementEditor == null) {
|
||||
add(cantEditLabel, BorderLayout.CENTER);
|
||||
}
|
||||
propChangeSupport.firePropertyChange("", null, null);
|
||||
validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a fitting grid layout for a list of buttons. An additional offset may be given if
|
||||
* further components should be added besides the buttons.
|
||||
*
|
||||
* @param additionalOffset
|
||||
* @param bList
|
||||
* @return
|
||||
*/
|
||||
private LayoutManager getButtonLayout(int additionalOffset, List<JButton> bList) {
|
||||
int lines = 1 + ((bList.size() + additionalOffset - 1) / 3);
|
||||
int cols = 3;
|
||||
return new GridLayout(lines, cols);
|
||||
}
|
||||
|
||||
public void removeUpperActionButton(String text) {
|
||||
removeActionButton(upperButtonList, text);
|
||||
}
|
||||
|
||||
public void removeLowerActionButton(String text) {
|
||||
removeActionButton(lowerButtonList, text);
|
||||
}
|
||||
|
||||
protected void removeActionButton(List<JButton> bList, String text) {
|
||||
JButton but = null;
|
||||
for (JButton jb : bList) {
|
||||
if (text.equals(jb.getText())) {
|
||||
but = jb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (but != null) {
|
||||
bList.remove(but);
|
||||
}
|
||||
}
|
||||
|
||||
public void addUpperActionButton(String text, ActionListener al) {
|
||||
addActionButton(upperButtonList, text, al);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an action listener such that the selection state will always be up to date in the
|
||||
* selectableList (if it exists).
|
||||
*
|
||||
* @param al
|
||||
* @return
|
||||
*/
|
||||
private ActionListener makeSelectionKnownAL(final ActionListener al) {
|
||||
return new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (selectableList != null) {
|
||||
selectableList.setSelectionByIndices(elementList.getSelectedIndices());
|
||||
}
|
||||
al.actionPerformed(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addLowerActionButton(String text, ActionListener al) {
|
||||
addActionButton(lowerButtonList, text, al);
|
||||
}
|
||||
|
||||
public void addActionButton(List<JButton> bList, String text, ActionListener al) {
|
||||
JButton but = new JButton(text);
|
||||
but.addActionListener(makeSelectionKnownAL(al));
|
||||
bList.add(but);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current object array.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
// Create a new list model, put it in the list and resize?
|
||||
updateEditorType(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all items. If all are selected, then deselect all items.
|
||||
*/
|
||||
public void selectDeselectAll() {
|
||||
if (areAllSelected()) {
|
||||
elementList.getSelectionModel().clearSelection();
|
||||
} else {
|
||||
elementList.setSelectionInterval(0, elementList.getModel().getSize() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean areAllSelected() {
|
||||
for (int i = 0; i < elementList.getModel().getSize(); i++) {
|
||||
if (!elementList.isSelectedIndex(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current object array.
|
||||
*
|
||||
* @return the current object array
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
if (listModel == null) {
|
||||
return null;
|
||||
}
|
||||
if (selectableList != null) {
|
||||
return selectableList;
|
||||
} else {
|
||||
// Convert the listmodel to an array of strings and return it.
|
||||
int length = listModel.getSize();
|
||||
Object result = Array.newInstance(elementClass, length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Array.set(result, i, listModel.elementAt(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void addPopupItem(String text, ActionListener al) {
|
||||
JMenuItem item = createMenuItem(text, true, makeSelectionKnownAL(al));
|
||||
popupItemList.add(item);
|
||||
}
|
||||
|
||||
public void addPopupMenu() {
|
||||
if (popupItemList.size() > 0) {
|
||||
elementList.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (selectableList != null) {
|
||||
selectableList.setSelectionByIndices(elementList.getSelectedIndices());
|
||||
}
|
||||
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
|
||||
// do nothing
|
||||
} else { // right click released, so show popup
|
||||
JPopupMenu popupMenu = new JPopupMenu();
|
||||
for (JMenuItem item : popupItemList) {
|
||||
popupMenu.add(item);
|
||||
}
|
||||
popupMenu.show(ArrayEditor.this, e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a menu item with given title and listener, add it to the menu and return it. It may be
|
||||
* enabled or disabled.
|
||||
*
|
||||
* @param title
|
||||
* @param aListener
|
||||
* @param enabled
|
||||
* @return
|
||||
*/
|
||||
private JMenuItem createMenuItem(String title, boolean enabled,
|
||||
ActionListener aListener) {
|
||||
JMenuItem item = new JMenuItem(title);
|
||||
// if (bgColor!=null) item.setForeground(bgColor);
|
||||
item.addActionListener(aListener);
|
||||
item.setEnabled(enabled);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supposedly returns an initialization string to create a classifier identical to the current
|
||||
* one, including it's state, but this doesn't appear possible given that the initialization
|
||||
* string isn't supposed to contain multiple statements.
|
||||
*
|
||||
* @return the java source code initialisation string
|
||||
*/
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "null";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true to indicate that we can paint a representation of the string array
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep;
|
||||
if (listModel.getSize() == 0) {
|
||||
rep = "Empty";
|
||||
} else {
|
||||
rep = listModel.getSize() + " of " + StringTools.cutClassName(elementClass.getName());
|
||||
Object maybeName = BeanInspector.callIfAvailable(listModel.get(0), "getName", new Object[]{});
|
||||
if (maybeName != null) {
|
||||
rep = rep + " (" + maybeName + "...)";
|
||||
}
|
||||
}
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propChangeSupport == null) {
|
||||
propChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propChangeSupport == null) {
|
||||
propChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public boolean isWithAddButton() {
|
||||
return withAddButton;
|
||||
}
|
||||
|
||||
public void setWithAddButton(boolean withAddButton) {
|
||||
this.withAddButton = withAddButton;
|
||||
// Hide/Show view based on whether we show the add button
|
||||
if (this.view != null) {
|
||||
this.view.setVisible(withAddButton);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWithSetButton() {
|
||||
return withSetButton;
|
||||
}
|
||||
|
||||
public void setWithSetButton(boolean withSetButton) {
|
||||
this.withSetButton = withSetButton;
|
||||
}
|
||||
|
||||
public boolean isWithDeleteButton() {
|
||||
return withDeleteButton;
|
||||
}
|
||||
|
||||
public void setWithDeleteButton(boolean wB) {
|
||||
this.withDeleteButton = wB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
}
|
||||
}
|
||||
183
src/main/java/eva2/gui/editor/BigStringEditor.java
Normal file
183
src/main/java/eva2/gui/editor/BigStringEditor.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyDialog;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
public class BigStringEditor implements PropertyEditor {
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private PropertyEditor elementEditor;
|
||||
private JTextArea textArea;
|
||||
private JScrollPane scrollPane;
|
||||
private JPanel panel;
|
||||
private JButton setButton;
|
||||
static private boolean isFinished = false;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void editSource(String file) {
|
||||
|
||||
try {
|
||||
isFinished = false;
|
||||
BigStringEditor editor = new BigStringEditor();
|
||||
|
||||
PropertyDialog dialog = new PropertyDialog(null, editor, file);
|
||||
|
||||
while (isFinished == false) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
System.out.println("e+" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public BigStringEditor() {
|
||||
super();
|
||||
// textArea = new JEditTextArea();
|
||||
// textArea.setTokenMarker(new JavaTokenMarker());
|
||||
textArea = new JTextArea(60, 60);
|
||||
textArea.setEditable(true);
|
||||
textArea.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
|
||||
scrollPane = new JScrollPane(textArea);
|
||||
panel = new JPanel();
|
||||
panel.setBorder(BorderFactory.createTitledBorder("Sourcecode"));
|
||||
panel.setLayout(new BorderLayout());
|
||||
setButton = new JButton("SET");
|
||||
setButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setValue(textArea.getText());
|
||||
}
|
||||
});
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
panel.add(setButton, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object value) {
|
||||
elementEditor = null;
|
||||
if (value instanceof String) {
|
||||
textArea.setText((String) value);
|
||||
}
|
||||
propertyChangeSupport.firePropertyChange("", null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "null";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true to indicate that we can paint a representation of the
|
||||
* string array
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
gfx.drawString("BigStringEditor", 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
src/main/java/eva2/gui/editor/ComponentFilter.java
Normal file
8
src/main/java/eva2/gui/editor/ComponentFilter.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
public interface ComponentFilter {
|
||||
boolean accept(java.awt.Component component);
|
||||
}
|
||||
363
src/main/java/eva2/gui/editor/DoubleArrayEditor.java
Normal file
363
src/main/java/eva2/gui/editor/DoubleArrayEditor.java
Normal file
@@ -0,0 +1,363 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyDoubleArray;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
* A simple focus listener with an object ID and callback.
|
||||
*
|
||||
* @author mkron
|
||||
*/
|
||||
class MyFocusListener implements FocusListener {
|
||||
private int myID = -1;
|
||||
private DoubleArrayEditor arrEditor = null;
|
||||
|
||||
public MyFocusListener(int id, DoubleArrayEditor gdae) {
|
||||
myID = id;
|
||||
this.arrEditor = gdae;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
|
||||
*/
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
|
||||
*/
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
arrEditor.notifyFocusID(myID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A generic editor for PropertyDoubleArray.
|
||||
*/
|
||||
public class DoubleArrayEditor extends JPanel implements PropertyEditor {
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport support = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyDoubleArray doubleArray;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JPanel customEditor, dataPanel, buttonPanel;
|
||||
private JTextField[][] inputTextFields;
|
||||
private JButton okButton, addButton, deleteButton, normalizeButton;
|
||||
|
||||
/**
|
||||
* Which columns has the focus? *
|
||||
*/
|
||||
private int lastFocussedRow = -1;
|
||||
|
||||
public DoubleArrayEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
|
||||
this.customEditor.add(new JLabel("Current Double Array:"), BorderLayout.NORTH);
|
||||
|
||||
// initialize data panel
|
||||
this.dataPanel = new JPanel();
|
||||
this.updateDataPanel();
|
||||
this.customEditor.add(this.dataPanel, BorderLayout.CENTER);
|
||||
|
||||
// initialize button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.addButton = new JButton("Add");
|
||||
this.addButton.addActionListener(this.addAction);
|
||||
this.deleteButton = new JButton("Delete");
|
||||
this.deleteButton.addActionListener(this.deleteAction);
|
||||
this.normalizeButton = new JButton("Normalize");
|
||||
this.normalizeButton.addActionListener(this.normalizeAction);
|
||||
this.okButton = new JButton("OK");
|
||||
this.okButton.setEnabled(true);
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//backupObject = copyObject(object);
|
||||
if ((customEditor.getTopLevelAncestor() != null) && (customEditor.getTopLevelAncestor() instanceof Window)) {
|
||||
Window w = (Window) customEditor.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.buttonPanel.add(this.addButton);
|
||||
this.buttonPanel.add(this.deleteButton);
|
||||
this.buttonPanel.add(this.normalizeButton);
|
||||
this.buttonPanel.add(this.okButton);
|
||||
this.customEditor.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener adds an element to DoubleArray
|
||||
*/
|
||||
ActionListener addAction = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
doubleArray.addRowCopy(lastFocussedRow); // copy the last focussed row
|
||||
updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener removes an element from the DoubleArray.
|
||||
*/
|
||||
ActionListener deleteAction = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (!doubleArray.isValidRow(lastFocussedRow)) {
|
||||
doubleArray.deleteRow(doubleArray.getNumRows() - 1);
|
||||
} else {
|
||||
doubleArray.deleteRow(lastFocussedRow);
|
||||
}
|
||||
updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener nomalizes each columng of the values of the DoubleArray.
|
||||
*/
|
||||
ActionListener normalizeAction = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
doubleArray.normalizeColumns();
|
||||
updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
double[][] tmpDD = new double[inputTextFields.length][inputTextFields[0].length];
|
||||
|
||||
for (int i = 0; i < tmpDD.length; i++) {
|
||||
for (int j = 0; j < tmpDD[0].length; j++) {
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(inputTextFields[i][j].getText());
|
||||
tmpDD[i][j] = d;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doubleArray.setDoubleArray(tmpDD);
|
||||
//updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.customEditor != null) {
|
||||
this.updateDataPanel();
|
||||
this.customEditor.validate();
|
||||
this.customEditor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method updates the data panel
|
||||
*/
|
||||
private void updateDataPanel() {
|
||||
int numRows = doubleArray.getNumRows();
|
||||
int numCols = doubleArray.getNumCols();
|
||||
this.dataPanel.removeAll();
|
||||
this.dataPanel.setLayout(new GridLayout(numRows, numCols + 1));
|
||||
this.inputTextFields = new JTextField[numRows][numCols];
|
||||
for (int i = 0; i < numRows; i++) {
|
||||
JLabel label = new JLabel("Value X" + i + ": ");
|
||||
this.dataPanel.add(label);
|
||||
for (int j = 0; j < numCols; j++) {
|
||||
this.inputTextFields[i][j] = new JTextField();
|
||||
this.inputTextFields[i][j].setText("" + doubleArray.getValue(i, j));
|
||||
this.inputTextFields[i][j].addKeyListener(this.readDoubleArrayAction);
|
||||
this.inputTextFields[i][j].addFocusListener(new MyFocusListener(i, this));
|
||||
this.dataPanel.add(this.inputTextFields[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyFocusID(int id) {
|
||||
// notification of which column has the focus
|
||||
lastFocussedRow = id;
|
||||
// System.out.println("Focus now on " + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyDoubleArray) {
|
||||
this.doubleArray = (PropertyDoubleArray) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.doubleArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (support == null) {
|
||||
support = new PropertyChangeSupport(this);
|
||||
}
|
||||
support.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (support == null) {
|
||||
support = new PropertyChangeSupport(this);
|
||||
}
|
||||
support.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Edit double array...";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
}
|
||||
95
src/main/java/eva2/gui/editor/EnumEditor.java
Normal file
95
src/main/java/eva2/gui/editor/EnumEditor.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyValueSelector;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EnumEditor extends PropertyEditorSupport {
|
||||
/**
|
||||
* The Enum values that may be chosen
|
||||
*/
|
||||
private Enum[] enumConstants;
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return getValue().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value) {
|
||||
if (value instanceof Enum) {
|
||||
enumConstants = ((Enum) value).getClass().getEnumConstants();
|
||||
super.setValue(value);
|
||||
} else if (value.getClass().isArray() && value.getClass().getComponentType().isEnum()) {
|
||||
Enum<?>[] e = (Enum[]) (value);
|
||||
enumConstants = (Enum[]) e.getClass().getComponentType().getEnumConstants();
|
||||
super.setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
for (int i = 0; i < enumConstants.length; i++) {
|
||||
if (text.equals(enumConstants[i].toString())) {
|
||||
setValue(enumConstants[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid text for enum");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
if (getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
String[] tags = new String[enumConstants.length];
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
tags[i] = enumConstants[i].toString();
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the editor.
|
||||
*
|
||||
* @param args ignored
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Enum<?> initial = TestEnum.asdf;
|
||||
EnumEditor ed = new EnumEditor();
|
||||
ed.setValue(initial);
|
||||
PropertyValueSelector ps = new PropertyValueSelector(ed);
|
||||
JFrame f = new JFrame();
|
||||
f.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
f.getContentPane().setLayout(new BorderLayout());
|
||||
f.getContentPane().add(ps, BorderLayout.CENTER);
|
||||
f.pack();
|
||||
f.setVisible(true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.err.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TestEnum {
|
||||
asdf, sdf, asdfa;
|
||||
|
||||
public String toString() {
|
||||
return "Foo" + name();
|
||||
}
|
||||
}
|
||||
294
src/main/java/eva2/gui/editor/EpsilonConstraintEditor.java
Normal file
294
src/main/java/eva2/gui/editor/EpsilonConstraintEditor.java
Normal file
@@ -0,0 +1,294 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyEpsilonConstraint;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EpsilonConstraintEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyEpsilonConstraint epsilonConstraint;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JPanel customEditor, dataPanel, buttonPanel, targetPanel;
|
||||
private JTextField[] targetTextField;
|
||||
private JComboBox objectiveComboBox;
|
||||
private JButton okButton;
|
||||
|
||||
public EpsilonConstraintEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
|
||||
// target panel
|
||||
this.targetPanel = new JPanel();
|
||||
this.targetPanel.setLayout(new GridLayout(1, 2));
|
||||
this.targetPanel.add(new JLabel("Optimize:"));
|
||||
this.objectiveComboBox = new JComboBox();
|
||||
for (int i = 0; i < this.epsilonConstraint.targetValue.length; i++) {
|
||||
this.objectiveComboBox.addItem("Objective " + i);
|
||||
}
|
||||
this.targetPanel.add(this.objectiveComboBox);
|
||||
this.objectiveComboBox.addItemListener(this.objectiveAction);
|
||||
this.customEditor.add(this.targetPanel, BorderLayout.NORTH);
|
||||
|
||||
// initialize data panel
|
||||
this.dataPanel = new JPanel();
|
||||
this.updateDataPanel();
|
||||
this.customEditor.add(this.dataPanel, BorderLayout.CENTER);
|
||||
|
||||
// initialize button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.okButton = new JButton("OK");
|
||||
this.okButton.setEnabled(true);
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//backupObject = copyObject(object);
|
||||
if ((customEditor.getTopLevelAncestor() != null) && (customEditor.getTopLevelAncestor() instanceof Window)) {
|
||||
Window w = (Window) customEditor.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.buttonPanel.add(this.okButton);
|
||||
this.customEditor.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener adds an element to DoubleArray
|
||||
*/
|
||||
ItemListener objectiveAction = new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent event) {
|
||||
epsilonConstraint.optimizeObjective = objectiveComboBox.getSelectedIndex();
|
||||
updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
double[] tmpT = epsilonConstraint.targetValue;
|
||||
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(targetTextField[i].getText());
|
||||
tmpT[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
epsilonConstraint.targetValue = tmpT;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.customEditor != null) {
|
||||
this.updateDataPanel();
|
||||
this.customEditor.validate();
|
||||
this.customEditor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the data panel
|
||||
*/
|
||||
private void updateDataPanel() {
|
||||
double[] tmpT = this.epsilonConstraint.targetValue;
|
||||
int obj = this.epsilonConstraint.optimizeObjective;
|
||||
|
||||
this.dataPanel.removeAll();
|
||||
this.dataPanel.setLayout(new GridLayout(tmpT.length + 1, 2));
|
||||
this.dataPanel.add(new JLabel());
|
||||
this.dataPanel.add(new JLabel("Target Value"));
|
||||
this.targetTextField = new JTextField[tmpT.length];
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
JLabel label = new JLabel("Objective " + i + ": ");
|
||||
this.dataPanel.add(label);
|
||||
this.targetTextField[i] = new JTextField();
|
||||
this.targetTextField[i].setText("" + tmpT[i]);
|
||||
this.targetTextField[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.dataPanel.add(this.targetTextField[i]);
|
||||
}
|
||||
this.targetTextField[obj].setEditable(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyEpsilonConstraint) {
|
||||
this.epsilonConstraint = (PropertyEpsilonConstraint) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.epsilonConstraint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Edit Epsilon Constraint";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
}
|
||||
307
src/main/java/eva2/gui/editor/EpsilonThresholdEditor.java
Normal file
307
src/main/java/eva2/gui/editor/EpsilonThresholdEditor.java
Normal file
@@ -0,0 +1,307 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyEpsilonThreshold;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EpsilonThresholdEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyEpsilonThreshold epsilonThreshhold;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JPanel customEditor, dataPanel, buttonPanel, targetPanel;
|
||||
private JTextField[] targetTextField, punishTextField;
|
||||
private JComboBox objectiveComboBox;
|
||||
private JButton okButton;
|
||||
|
||||
public EpsilonThresholdEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
|
||||
// target panel
|
||||
this.targetPanel = new JPanel();
|
||||
this.targetPanel.setLayout(new GridLayout(1, 2));
|
||||
this.targetPanel.add(new JLabel("Optimize:"));
|
||||
this.objectiveComboBox = new JComboBox();
|
||||
for (int i = 0; i < this.epsilonThreshhold.targetValue.length; i++) {
|
||||
this.objectiveComboBox.addItem("Objective " + i);
|
||||
}
|
||||
this.targetPanel.add(this.objectiveComboBox);
|
||||
this.objectiveComboBox.addItemListener(this.objectiveAction);
|
||||
this.customEditor.add(this.targetPanel, BorderLayout.NORTH);
|
||||
|
||||
// initialize data panel
|
||||
this.dataPanel = new JPanel();
|
||||
this.updateDataPanel();
|
||||
this.customEditor.add(this.dataPanel, BorderLayout.CENTER);
|
||||
|
||||
// initialize button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.okButton = new JButton("OK");
|
||||
this.okButton.setEnabled(true);
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//backupObject = copyObject(object);
|
||||
if ((customEditor.getTopLevelAncestor() != null) && (customEditor.getTopLevelAncestor() instanceof Window)) {
|
||||
Window w = (Window) customEditor.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.buttonPanel.add(this.okButton);
|
||||
this.customEditor.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener adds an element to DoubleArray
|
||||
*/
|
||||
ItemListener objectiveAction = new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent event) {
|
||||
epsilonThreshhold.optimizeObjective = objectiveComboBox.getSelectedIndex();
|
||||
updateEditor();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
double[] tmpT = epsilonThreshhold.targetValue;
|
||||
double[] tmpP = epsilonThreshhold.punishment;
|
||||
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(targetTextField[i].getText());
|
||||
tmpT[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(punishTextField[i].getText());
|
||||
tmpP[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
epsilonThreshhold.targetValue = tmpT;
|
||||
epsilonThreshhold.punishment = tmpP;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.customEditor != null) {
|
||||
this.updateDataPanel();
|
||||
this.customEditor.validate();
|
||||
this.customEditor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the data panel
|
||||
*/
|
||||
private void updateDataPanel() {
|
||||
double[] tmpT = this.epsilonThreshhold.targetValue;
|
||||
double[] tmpP = this.epsilonThreshhold.punishment;
|
||||
int obj = this.epsilonThreshhold.optimizeObjective;
|
||||
|
||||
this.dataPanel.removeAll();
|
||||
this.dataPanel.setLayout(new GridLayout(tmpT.length + 1, 3));
|
||||
this.dataPanel.add(new JLabel());
|
||||
this.dataPanel.add(new JLabel("Target Value"));
|
||||
this.dataPanel.add(new JLabel("Punishment"));
|
||||
this.targetTextField = new JTextField[tmpT.length];
|
||||
this.punishTextField = new JTextField[tmpT.length];
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
JLabel label = new JLabel("Objective " + i + ": ");
|
||||
this.dataPanel.add(label);
|
||||
this.targetTextField[i] = new JTextField();
|
||||
this.targetTextField[i].setText("" + tmpT[i]);
|
||||
this.targetTextField[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.dataPanel.add(this.targetTextField[i]);
|
||||
this.punishTextField[i] = new JTextField();
|
||||
this.punishTextField[i].setText("" + tmpP[i]);
|
||||
this.punishTextField[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.dataPanel.add(this.punishTextField[i]);
|
||||
}
|
||||
this.targetTextField[obj].setEditable(false);
|
||||
this.punishTextField[obj].setEditable(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyEpsilonThreshold) {
|
||||
this.epsilonThreshhold = (PropertyEpsilonThreshold) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.epsilonThreshhold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Edit Epsilon Threshhold";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
}
|
||||
181
src/main/java/eva2/gui/editor/FilePathEditor.java
Normal file
181
src/main/java/eva2/gui/editor/FilePathEditor.java
Normal file
@@ -0,0 +1,181 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyFilePath;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class FilePathEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyFilePath filePath;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JFileChooser fileChooser;
|
||||
private JPanel panel;
|
||||
|
||||
public FilePathEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyFilePath) {
|
||||
this.filePath = (PropertyFilePath) o;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.filePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = this.filePath.fileName;
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
this.panel = new JPanel();
|
||||
this.fileChooser = new JFileChooser();
|
||||
File file = new File(this.filePath.getCompleteFilePath());
|
||||
this.fileChooser.setSelectedFile(file);
|
||||
this.fileChooser.setMultiSelectionEnabled(false);
|
||||
this.panel.add(this.fileChooser);
|
||||
this.fileChooser.addActionListener(this.fileChooserAction);
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener, called by the "train" button, causes
|
||||
* the SOM to recalculate the mapping.
|
||||
*/
|
||||
ActionListener fileChooserAction = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (event.getActionCommand().equals("ApproveSelection")) {
|
||||
filePath.setCompleteFilePath(fileChooser.getSelectedFile().getAbsolutePath());
|
||||
propertyChangeSupport.firePropertyChange("", filePath, null);
|
||||
Window w = (Window) fileChooser.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
panel = null;
|
||||
}
|
||||
if (event.getActionCommand().equals("CancelSelection")) {
|
||||
filePath.setCompleteFilePath(fileChooser.getSelectedFile().getAbsolutePath());
|
||||
propertyChangeSupport.firePropertyChange("", filePath, null);
|
||||
Window w = (Window) fileChooser.getTopLevelAncestor();
|
||||
if (w != null) {
|
||||
w.dispose();
|
||||
}
|
||||
panel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
488
src/main/java/eva2/gui/editor/GenericObjectEditor.java
Normal file
488
src/main/java/eva2/gui/editor/GenericObjectEditor.java
Normal file
@@ -0,0 +1,488 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.gui.OptimizationEditorPanel;
|
||||
import eva2.tools.ReflectPackage;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class GenericObjectEditor implements PropertyEditor {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(GenericObjectEditor.class.getName());
|
||||
private Object object;
|
||||
private Object backupObject;
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private Class<?> classType;
|
||||
private OptimizationEditorPanel editorComponent;
|
||||
private boolean isEnabled = true;
|
||||
|
||||
/**
|
||||
* Read the classes available for user selection from the properties or the classpath
|
||||
* respectively
|
||||
*/
|
||||
public static ArrayList<String> getClassesFromProperties(String className, ArrayList<Class<?>> instances) {
|
||||
LOGGER.log(Level.FINEST, "Requesting className: {0}", className);
|
||||
|
||||
// Try to read the predefined classes from the props file.
|
||||
String typeOptions = EvAInfo.getProperty(className);
|
||||
if (typeOptions == null) {
|
||||
// If none are defined, all assignable classes are searched the hard way, using the ReflectPackage
|
||||
return getClassesFromClassPath(className, instances);
|
||||
} else {
|
||||
StringTokenizer st = new StringTokenizer(typeOptions, ", ");
|
||||
ArrayList<String> classes = new ArrayList<>();
|
||||
while (st.hasMoreTokens()) {
|
||||
String current = st.nextToken().trim();
|
||||
try {
|
||||
Class<?> clz = Class.forName(current); // test for instantiability
|
||||
if (instances != null) {
|
||||
instances.add(clz);
|
||||
}
|
||||
classes.add(current);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
LOGGER.log(Level.WARNING, String.format("Requesting className: %1$s, Couldn't load: %2$s", className, current), ex);
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names of all classes in the same package that are assignable from the named class,
|
||||
* and that can be loaded through the classpath. If a class has a declared field called
|
||||
* "hideFromGOE" this method will skip it. Abstract classes and interfaces will be skipped as
|
||||
* well.
|
||||
*
|
||||
* @param className
|
||||
* @return
|
||||
* @see ReflectPackage#getAssignableClassesInPackage
|
||||
*/
|
||||
public static ArrayList<String> getClassesFromClassPath(String className, ArrayList<Class<?>> instances) {
|
||||
ArrayList<String> classes = new ArrayList<>();
|
||||
Class<?>[] classArray;
|
||||
classArray = ReflectPackage.getAssignableClasses(className, true, true);
|
||||
if (classArray == null) {
|
||||
LOGGER.log(Level.WARNING, String.format("No assignable classes found in property file or on classpath: %1$s for %2$s", EvAInfo.propertyFile, className));
|
||||
classes.add(className);
|
||||
} else {
|
||||
for (Class<?> clazz : classArray) {
|
||||
int m = clazz.getModifiers();
|
||||
try {
|
||||
// a field allowing a class to indicate it doesnt want to be displayed
|
||||
Field f = clazz.getDeclaredField("hideFromGOE");
|
||||
if (f.getBoolean(clazz)) {
|
||||
LOGGER.log(Level.FINEST, "Class {0} wants to be hidden from GOE.", clazz);
|
||||
continue;
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
/*
|
||||
* We are just logging this exception here. It is expected that most classes do
|
||||
* not have this field.
|
||||
*/
|
||||
LOGGER.log(Level.FINER, String.format("%1$s does not have a hideFromGOE field", clazz.toString()), e);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
LOGGER.log(Level.FINER, e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
if (!Modifier.isAbstract(m) && !clazz.isInterface()) { // dont take abstract classes or interfaces
|
||||
try {
|
||||
Class<?>[] params = new Class[0];
|
||||
clazz.getConstructor(params);
|
||||
if (instances != null) {
|
||||
instances.add(clazz);
|
||||
}
|
||||
classes.add(clazz.getName());
|
||||
} catch (NoSuchMethodException e) {
|
||||
LOGGER.log(Level.WARNING, String.format("GOE warning: Class %1$s has no default constructor", clazz.getName()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide or show the editable property of a class, this makes sense for classes which are
|
||||
* represented visually using the GenericObjectEditor. Returns false, if an error occurs, else
|
||||
* true. An instance may call this statically on itself by means of this.getClass(). Actually
|
||||
* this only sets the hidden property of the java bean which is checked in the wasModified
|
||||
* method of PropertySheetPanel.
|
||||
*
|
||||
* @param cls class the property belongs to
|
||||
* @param property string name of the property
|
||||
* @param expertValue desired value to set, true for hidden, false for visible
|
||||
* @return false, if an error occurs, else true
|
||||
*/
|
||||
public static boolean setExpertProperty(Class<?> cls, String property, boolean expertValue) {
|
||||
try {
|
||||
BeanInfo bi = Introspector.getBeanInfo(cls);
|
||||
PropertyDescriptor[] props = bi.getPropertyDescriptors();
|
||||
for (PropertyDescriptor prop : props) {
|
||||
if ((prop.getName().equals(property))) {
|
||||
if (expertValue != prop.isExpert()) {
|
||||
prop.setExpert(expertValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.WARNING, String.format("Couldn't set expert property for %1$s/%2$s", cls.getName(), property), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide or show the editable property of a class, this makes sense for classes which are
|
||||
* represented visually using the GenericObjectEditor. Returns false, if an error occurs, else
|
||||
* true. An instance may call this statically on itself by means of this.getClass(). Actually
|
||||
* this only sets the hidden property of the java bean which is checked in the wasModified
|
||||
* method of PropertySheetPanel.
|
||||
*
|
||||
* @param cls class the property belongs to
|
||||
* @param property string name of the property
|
||||
* @param hide desired value to set, true for hidden, false for visible
|
||||
* @return false, if an error occurs, else true
|
||||
*/
|
||||
public static boolean setHideProperty(Class<?> cls, String property, boolean hide) {
|
||||
try {
|
||||
BeanInfo bi = Introspector.getBeanInfo(cls);
|
||||
PropertyDescriptor[] props = bi.getPropertyDescriptors();
|
||||
for (PropertyDescriptor prop : props) {
|
||||
if ((prop.getName().equals(property))) {
|
||||
if (hide != prop.isHidden()) {
|
||||
prop.setHidden(hide);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.log(Level.WARNING, "Property {0} not found", property);
|
||||
return false;
|
||||
} catch (IntrospectionException e) {
|
||||
LOGGER.log(Level.WARNING, String.format("Couldn't set hide property for %1$s/%2$s", cls.getName(), property), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide or unhide all properties of a given class. Added to avoid the problem with hidden
|
||||
* properties of inherited classes hide the property for all classes within the same inheritance
|
||||
* tree.
|
||||
*
|
||||
* @param cls
|
||||
* @param hide
|
||||
* @return the original hidden states or null if an error occurred.
|
||||
*/
|
||||
public static boolean[] setHideAllProperties(Class<?> cls, boolean hide) {
|
||||
try {
|
||||
BeanInfo bi = Introspector.getBeanInfo(cls);
|
||||
PropertyDescriptor[] props = bi.getPropertyDescriptors();
|
||||
boolean[] orig = new boolean[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
orig[i] = props[i].isHidden();
|
||||
props[i].setHidden(hide);
|
||||
}
|
||||
return orig;
|
||||
} catch (IntrospectionException e) {
|
||||
LOGGER.log(Level.WARNING, String.format("Couldn't hide all properties for %1$s/all", cls.getName()), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setHideProperties(Class<?> cls, boolean[] hideStates) {
|
||||
if (hideStates != null) {
|
||||
BeanInfo bi;
|
||||
try {
|
||||
bi = Introspector.getBeanInfo(cls);
|
||||
} catch (IntrospectionException e) {
|
||||
LOGGER.log(Level.WARNING, String.format("Error on introspection of %1$s", cls.getName()), e);
|
||||
return;
|
||||
}
|
||||
PropertyDescriptor[] props = bi.getPropertyDescriptors();
|
||||
if (hideStates.length == props.length) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
props[i].setHidden(hideStates[i]);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Error, mismatching length of hide state array in GenericObjectEditor.setHideProperites");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience-method. See setHideProperty.
|
||||
*
|
||||
* @param cls
|
||||
* @param property
|
||||
* @param show
|
||||
* @return
|
||||
*/
|
||||
public static boolean setShowProperty(Class<?> cls, String property, boolean show) {
|
||||
return GenericObjectEditor.setHideProperty(cls, property, !show);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the editor is "enabled", meaning that the current values will be painted.
|
||||
*
|
||||
* @param newVal a value of type 'boolean'
|
||||
*/
|
||||
public void setEnabled(boolean newVal) {
|
||||
if (newVal != isEnabled) {
|
||||
isEnabled = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the class of values that can be edited.
|
||||
*
|
||||
* @param type a value of type 'Class'
|
||||
*/
|
||||
public void setClassType(Class<?> type) {
|
||||
classType = type;
|
||||
if (editorComponent != null) {
|
||||
editorComponent.updateClassType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Class<?> getClassType() {
|
||||
return classType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current object to be the default, taken as the first item in the chooser
|
||||
*/
|
||||
public void setDefaultValue() {
|
||||
if (classType == null) {
|
||||
LOGGER.log(Level.WARNING, "No ClassType set up for GenericObjectEditor!");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<String> v = new Vector<>(getClassesFromProperties(classType.getName(), null));
|
||||
|
||||
try {
|
||||
if (v.size() > 0) {
|
||||
setObject(Class.forName((String) v.get(0)).newInstance());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Exception in setDefaultValue !!!" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Object. If the Object is in the Object chooser, this becomes the selected
|
||||
* item (and added to the chooser if necessary).
|
||||
*
|
||||
* @param o an object that must be a Object.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
|
||||
if (o == null || classType == null) {
|
||||
LOGGER.log(Level.WARNING, "No ClassType set up for GenericObjectEditor!");
|
||||
return;
|
||||
}
|
||||
if (!classType.isAssignableFrom(o.getClass())) {
|
||||
if (classType.isPrimitive()) {
|
||||
System.err.println("setValue object not of correct type! Expected " + classType.getName() + ", got " + o.getClass().getName());
|
||||
System.err.println("setting primitive type");
|
||||
setObject(o);
|
||||
} else {
|
||||
System.err.println("setValue object not of correct type! Expected " + classType.getName() + ", got " + o.getClass().getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setObject(o);
|
||||
if (editorComponent != null) {
|
||||
editorComponent.updateChooser();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Object, but doesn't worry about updating the state of the Object chooser.
|
||||
*
|
||||
* @param c a value of type 'Object'
|
||||
*/
|
||||
private void setObject(Object c) {
|
||||
// This should really call equals() for comparison.
|
||||
boolean trueChange = (c != getValue());
|
||||
|
||||
backupObject = object;
|
||||
object = c;
|
||||
|
||||
if (editorComponent != null) {
|
||||
editorComponent.updateChildPropertySheet();
|
||||
if (trueChange) {
|
||||
propertyChangeSupport.firePropertyChange("", backupObject, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current Object.
|
||||
*
|
||||
* @return the current Object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supposedly returns an initialization string to create a Object identical to the current one,
|
||||
* including it's state, but this doesn't appear possible given that the initialization string
|
||||
* isn't supposed to contain multiple statements.
|
||||
*
|
||||
* @return the java source code initialization string
|
||||
*/
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "new " + object.getClass().getName() + "()";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true to indicate that we can paint a representation of the Object.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current Object.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
if (isEnabled && object != null) {
|
||||
int getNameMethod = -1;
|
||||
MethodDescriptor[] methods;
|
||||
String rep = "";
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
|
||||
methods = beanInfo.getMethodDescriptors();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
if (methods[i].getName().equalsIgnoreCase("getName")) {
|
||||
getNameMethod = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IntrospectionException ex) {
|
||||
LOGGER.log(Level.WARNING, "Could not introspect PropertySheetPanel", ex);
|
||||
return;
|
||||
}
|
||||
if (getNameMethod >= 0) {
|
||||
try {
|
||||
rep = (String) methods[getNameMethod].getMethod().invoke(object, (Object[]) null);
|
||||
} catch (IllegalAccessException | java.lang.reflect.InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
if (rep.length() <= 0) {
|
||||
rep = object.getClass().getName();
|
||||
int dotPos = rep.lastIndexOf('.');
|
||||
if (dotPos != -1) {
|
||||
rep = rep.substring(dotPos + 1);
|
||||
}
|
||||
}
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getHeight()) / 2;
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null as we don't support getting/setting values as text.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null as we don't support getting/setting values as text.
|
||||
*
|
||||
* @param text the text value
|
||||
* @throws IllegalArgumentException as we don't support getting/setting values as text.
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null as we don't support getting values as tags.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (editorComponent == null) {
|
||||
editorComponent = new OptimizationEditorPanel(object, backupObject, propertyChangeSupport, this);
|
||||
}
|
||||
return editorComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void disableOKCancel() {
|
||||
if (editorComponent == null) {
|
||||
editorComponent = new OptimizationEditorPanel(object, backupObject,
|
||||
propertyChangeSupport, this);
|
||||
}
|
||||
editorComponent.setEnabledOkCancelButtons(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
}
|
||||
265
src/main/java/eva2/gui/editor/IntArrayEditor.java
Normal file
265
src/main/java/eva2/gui/editor/IntArrayEditor.java
Normal file
@@ -0,0 +1,265 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyIntArray;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class IntArrayEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyIntArray intArray;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JPanel customEditor, dataPanel, buttonPanel;
|
||||
private JTextField[] inputTextField;
|
||||
private JButton okButton;
|
||||
|
||||
public IntArrayEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
|
||||
this.customEditor.add(new JLabel("Current Int Array:"), BorderLayout.NORTH);
|
||||
|
||||
// initialize data panel
|
||||
this.dataPanel = new JPanel();
|
||||
this.updateDataPanel();
|
||||
this.customEditor.add(this.dataPanel, BorderLayout.CENTER);
|
||||
|
||||
// initialize button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.okButton = new JButton("OK");
|
||||
this.okButton.setEnabled(true);
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//backupObject = copyObject(object);
|
||||
if ((customEditor.getTopLevelAncestor() != null) && (customEditor.getTopLevelAncestor() instanceof Window)) {
|
||||
Window w = (Window) customEditor.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.buttonPanel.add(this.okButton);
|
||||
this.customEditor.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readIntArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
int[] tmpD = new int[inputTextField.length];
|
||||
|
||||
for (int i = 0; i < tmpD.length; i++) {
|
||||
try {
|
||||
int d = 0;
|
||||
d = Integer.parseInt(inputTextField[i].getText());
|
||||
tmpD[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
intArray.setIntArray(tmpD);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.customEditor != null) {
|
||||
this.updateDataPanel();
|
||||
this.customEditor.validate();
|
||||
this.customEditor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the data panel
|
||||
*/
|
||||
private void updateDataPanel() {
|
||||
int[] tmpD = this.intArray.getIntArray();
|
||||
|
||||
this.dataPanel.removeAll();
|
||||
this.dataPanel.setLayout(new GridLayout(tmpD.length, 2));
|
||||
this.inputTextField = new JTextField[tmpD.length];
|
||||
for (int i = 0; i < tmpD.length; i++) {
|
||||
JLabel label = new JLabel("Value X" + i + ": ");
|
||||
this.dataPanel.add(label);
|
||||
this.inputTextField[i] = new JTextField();
|
||||
this.inputTextField[i].setText("" + tmpD[i]);
|
||||
this.inputTextField[i].addKeyListener(this.readIntArrayAction);
|
||||
this.dataPanel.add(this.inputTextField[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyIntArray) {
|
||||
this.intArray = (PropertyIntArray) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.intArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Edit int[]";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
}
|
||||
27
src/main/java/eva2/gui/editor/MultiLineString.java
Normal file
27
src/main/java/eva2/gui/editor/MultiLineString.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
/**
|
||||
* @author not attributable
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class MultiLineString {
|
||||
|
||||
public String string = "";
|
||||
|
||||
public MultiLineString() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
MultiLineString multiLineString1 = new MultiLineString();
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
public void setString(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
}
|
||||
108
src/main/java/eva2/gui/editor/MultiLineStringEditor.java
Normal file
108
src/main/java/eva2/gui/editor/MultiLineStringEditor.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.MultiLineString;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.TextEvent;
|
||||
import java.awt.event.TextListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class MultiLineStringEditor implements PropertyEditor {
|
||||
protected MultiLineString value; // The value we will be editing.
|
||||
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
value = (MultiLineString) o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsText(String s) {
|
||||
value.setString(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return value.getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
} // not enumerated; no tags
|
||||
|
||||
// Say that we allow custom editing.
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return the custom editor. This just creates and returns a TextArea
|
||||
// to edit the multi-line text. But it also registers a listener on the
|
||||
// text area to update the value as the user types and to fire the
|
||||
// property change events that property editors are required to fire.
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
final TextArea t = new TextArea(value.string);
|
||||
t.setSize(300, 150); // TextArea doesn't have a preferred size, so set one
|
||||
t.addTextListener(new TextListener() {
|
||||
@Override
|
||||
public void textValueChanged(TextEvent e) {
|
||||
value.setString(t.getText());
|
||||
listeners.firePropertyChange(null, null, null);
|
||||
}
|
||||
});
|
||||
return t;
|
||||
}
|
||||
|
||||
// Visual display of the value, for use with the custom editor.
|
||||
// Just print some instructions and hope they fit in the in the box.
|
||||
// This could be more sophisticated.
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintValue(Graphics g, Rectangle r) {
|
||||
g.setClip(r);
|
||||
g.drawString("Click to edit...", r.x + 5, r.y + 15);
|
||||
}
|
||||
|
||||
// Important method for code generators. Note that it
|
||||
// ought to add any necessary escape sequences.
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "\"" + value + "\"";
|
||||
}
|
||||
|
||||
// This code uses the PropertyChangeSupport class to maintain a list of
|
||||
// listeners interested in the edits we make to the value.
|
||||
protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (listeners == null) {
|
||||
listeners = new PropertyChangeSupport(this);
|
||||
}
|
||||
listeners.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (listeners == null) {
|
||||
listeners = new PropertyChangeSupport(this);
|
||||
}
|
||||
listeners.removePropertyChangeListener(l);
|
||||
}
|
||||
}
|
||||
61
src/main/java/eva2/gui/editor/ObjectListSelectionEditor.java
Normal file
61
src/main/java/eva2/gui/editor/ObjectListSelectionEditor.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertySelectableList;
|
||||
|
||||
/**
|
||||
* An editor for a selectable List.
|
||||
*/
|
||||
public class ObjectListSelectionEditor extends AbstractListSelectionEditor {
|
||||
private PropertySelectableList objList;
|
||||
|
||||
public ObjectListSelectionEditor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getElementCount() {
|
||||
return objList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementName(int i) {
|
||||
return objList.get(i).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isElementSelected(int i) {
|
||||
return objList.isSelected(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean actionOnSelect() {
|
||||
boolean changed = false;
|
||||
for (int i = 0; i < this.blackCheck.length; i++) {
|
||||
if (objList.isSelected(i) != this.blackCheck[i].isSelected()) {
|
||||
objList.setSelectionForElement(i, this.blackCheck[i].isSelected());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setObject(Object o) {
|
||||
if (o instanceof PropertySelectableList) {
|
||||
this.objList = (PropertySelectableList) o;
|
||||
objList.addPropertyChangeListener(this);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retruns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return objList;
|
||||
}
|
||||
}
|
||||
455
src/main/java/eva2/gui/editor/OptimizationObjectivesEditor.java
Normal file
455
src/main/java/eva2/gui/editor/OptimizationObjectivesEditor.java
Normal file
@@ -0,0 +1,455 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
|
||||
import eva2.gui.PropertyEditorProvider;
|
||||
import eva2.gui.PropertyOptimizationObjectives;
|
||||
import eva2.optimization.tools.AbstractObjectEditor;
|
||||
import eva2.optimization.tools.GeneralOptimizationEditorProperty;
|
||||
import eva2.problems.InterfaceOptimizationObjective;
|
||||
import eva2.problems.InterfaceOptimizationTarget;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class OptimizationObjectivesEditor extends JPanel implements PropertyEditor, java.beans.PropertyChangeListener {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyOptimizationObjectives optimizationObjectives;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JComponent editor;
|
||||
private JPanel targetList;
|
||||
private JComponent[] targets;
|
||||
private JButton[] deleteButton;
|
||||
private JScrollPane scrollTargets;
|
||||
private GeneralOptimizationEditorProperty[] editors;
|
||||
private PropertyChangeListener self;
|
||||
|
||||
public OptimizationObjectivesEditor() {
|
||||
self = this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
self = this;
|
||||
this.editor = new JPanel();
|
||||
this.editor.setPreferredSize(new Dimension(400, 200));
|
||||
this.editor.setMinimumSize(new Dimension(400, 200));
|
||||
|
||||
// initialize the editors
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectives.getSelectedTargets();
|
||||
this.editors = new GeneralOptimizationEditorProperty[list.length];
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
this.editors[i] = new GeneralOptimizationEditorProperty();
|
||||
this.editors[i].name = list[i].getName();
|
||||
try {
|
||||
this.editors[i].value = list[i];
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(this.editors[i].value.getClass());
|
||||
if (this.editors[i].editor == null) {
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (this.editors[i].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) this.editors[i].editor).setClassType(InterfaceOptimizationTarget.class);
|
||||
}
|
||||
this.editors[i].editor.setValue(this.editors[i].value);
|
||||
this.editors[i].editor.addPropertyChangeListener(this);
|
||||
AbstractObjectEditor.findViewFor(this.editors[i]);
|
||||
if (this.editors[i].view != null) {
|
||||
this.editors[i].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
}
|
||||
this.targetList = new JPanel();
|
||||
this.updateTargetList();
|
||||
this.scrollTargets = new JScrollPane(this.targetList);
|
||||
|
||||
this.editor.setLayout(new BorderLayout());
|
||||
this.editor.add(this.scrollTargets, BorderLayout.CENTER);
|
||||
|
||||
// the add button
|
||||
JButton addButton = new JButton("Add Opt. Target");
|
||||
addButton.addActionListener(addTarget);
|
||||
this.editor.add(addButton, BorderLayout.SOUTH);
|
||||
|
||||
// Some description would be nice
|
||||
JTextArea jt = new JTextArea();
|
||||
jt.setFont(new Font("SansSerif", Font.PLAIN, 12));
|
||||
jt.setEditable(false);
|
||||
jt.setLineWrap(true);
|
||||
jt.setWrapStyleWord(true);
|
||||
jt.setText("Choose and parameterize optimization objectives.");
|
||||
jt.setBackground(getBackground());
|
||||
JPanel jp = new JPanel();
|
||||
jp.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createTitledBorder("Info"),
|
||||
BorderFactory.createEmptyBorder(0, 5, 5, 5)
|
||||
));
|
||||
jp.setLayout(new BorderLayout());
|
||||
jp.add(jt, BorderLayout.CENTER);
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
JButton help = new JButton("Help");
|
||||
help.setEnabled(false);
|
||||
p2.add(help, BorderLayout.NORTH);
|
||||
jp.add(p2, BorderLayout.EAST);
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
this.editor.add(jp, BorderLayout.NORTH);
|
||||
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the server list
|
||||
*/
|
||||
private void updateTargetList() {
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes;
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectives.getSelectedTargets();
|
||||
|
||||
this.targetList.removeAll();
|
||||
this.targetList.setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
this.targets = new JComponent[list.length];
|
||||
this.deleteButton = new JButton[list.length];
|
||||
String[] cups = new String[8];
|
||||
for (int i = 0; i < cups.length; i++) {
|
||||
cups[i] = "" + (i + 1);
|
||||
}
|
||||
// The head title
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 0;
|
||||
gbc.weightx = 10;
|
||||
this.targetList.add(new JLabel("Target"), gbc);
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.REMAINDER;
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1;
|
||||
this.targetList.add(new JLabel("Remove"), gbc);
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
// the status indicator
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 0;
|
||||
gbc.weightx = 10;
|
||||
// this.targets[i] = new JButton(""+list[i].getName());
|
||||
// this.targets[i].setEnabled(false);
|
||||
this.targets[i] = this.editors[i].view;
|
||||
this.targetList.add(this.targets[i], gbc);
|
||||
// The delete button
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.REMAINDER;
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 1;
|
||||
bytes = loader.getBytesFromResourceLocation("images/Sub24.gif", true);
|
||||
this.deleteButton[i] = new JButton("", new ImageIcon(Toolkit.getDefaultToolkit().createImage(bytes)));
|
||||
this.deleteButton[i].addActionListener(deleteTarget);
|
||||
this.targetList.add(this.deleteButton[i], gbc);
|
||||
}
|
||||
this.targetList.repaint();
|
||||
this.targetList.validate();
|
||||
if (this.scrollTargets != null) {
|
||||
this.scrollTargets.validate();
|
||||
this.scrollTargets.repaint();
|
||||
}
|
||||
if (this.editor != null) {
|
||||
this.editor.validate();
|
||||
this.editor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener updateTargets = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener addTarget = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
optimizationObjectives.addTarget((InterfaceOptimizationObjective) optimizationObjectives.getAvailableTargets()[0].clone());
|
||||
int l = optimizationObjectives.getSelectedTargets().length;
|
||||
GeneralOptimizationEditorProperty[] newEdit = new GeneralOptimizationEditorProperty[l];
|
||||
System.arraycopy(editors, 0, newEdit, 0, editors.length);
|
||||
InterfaceOptimizationObjective[] list = optimizationObjectives.getSelectedTargets();
|
||||
l--;
|
||||
newEdit[l] = new GeneralOptimizationEditorProperty();
|
||||
newEdit[l].name = list[l].getName();
|
||||
try {
|
||||
newEdit[l].value = list[l];
|
||||
newEdit[l].editor = PropertyEditorProvider.findEditor(newEdit[l].value.getClass());
|
||||
if (newEdit[l].editor == null) {
|
||||
newEdit[l].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (newEdit[l].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) newEdit[l].editor).setClassType(InterfaceOptimizationTarget.class);
|
||||
}
|
||||
newEdit[l].editor.setValue(newEdit[l].value);
|
||||
newEdit[l].editor.addPropertyChangeListener(self);
|
||||
AbstractObjectEditor.findViewFor(newEdit[l]);
|
||||
if (newEdit[l].view != null) {
|
||||
newEdit[l].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
editors = newEdit;
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener deleteTarget = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
int l = optimizationObjectives.getSelectedTargets().length, j = 0;
|
||||
GeneralOptimizationEditorProperty[] newEdit = new GeneralOptimizationEditorProperty[l - 1];
|
||||
for (int i = 0; i < deleteButton.length; i++) {
|
||||
if (event.getSource().equals(deleteButton[i])) {
|
||||
optimizationObjectives.removeTarget(i);
|
||||
} else {
|
||||
newEdit[j] = editors[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
editors = newEdit;
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.editor != null) {
|
||||
this.targetList.validate();
|
||||
this.targetList.repaint();
|
||||
this.scrollTargets.validate();
|
||||
this.scrollTargets.repaint();
|
||||
this.editor.validate();
|
||||
this.editor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyOptimizationObjectives) {
|
||||
this.optimizationObjectives = (PropertyOptimizationObjectives) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.optimizationObjectives;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Optimization Targets";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.editor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will udate the status of the object taking the values from all
|
||||
* supsequent editors and setting them to my object.
|
||||
*/
|
||||
public void updateCenterComponent(PropertyChangeEvent evt) {
|
||||
//this.updateTargetList();
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* ****************************** java.beans.PropertyChangeListener ************************
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will wait for the GenericObjectEditor to finish
|
||||
* editing an object.
|
||||
*
|
||||
* @param evt
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Object newVal = evt.getNewValue();
|
||||
Object oldVal = evt.getOldValue();
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectives.getSelectedTargets();
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (oldVal.equals(list[i])) {
|
||||
list[i] = (InterfaceOptimizationObjective) newVal;
|
||||
this.editors[i].name = list[i].getName();
|
||||
try {
|
||||
this.editors[i].value = list[i];
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(this.editors[i].value.getClass());
|
||||
if (this.editors[i].editor == null) {
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (this.editors[i].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) this.editors[i].editor).setClassType(InterfaceOptimizationTarget.class);
|
||||
}
|
||||
this.editors[i].editor.setValue(this.editors[i].value);
|
||||
this.editors[i].editor.addPropertyChangeListener(this);
|
||||
AbstractObjectEditor.findViewFor(this.editors[i]);
|
||||
if (this.editors[i].view != null) {
|
||||
this.editors[i].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
this.targets[i] = this.editors[i].view;
|
||||
}
|
||||
}
|
||||
this.updateCenterComponent(evt); // Let our panel update before guys downstream
|
||||
propertyChangeSupport.firePropertyChange("", optimizationObjectives, optimizationObjectives);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
|
||||
import eva2.gui.PropertyEditorProvider;
|
||||
import eva2.gui.PropertyOptimizationObjectivesWithParam;
|
||||
import eva2.optimization.tools.AbstractObjectEditor;
|
||||
import eva2.optimization.tools.GeneralOptimizationEditorProperty;
|
||||
import eva2.problems.InterfaceOptimizationObjective;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class OptimizationObjectivesWithParamEditor extends JPanel implements PropertyEditor, java.beans.PropertyChangeListener {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyOptimizationObjectivesWithParam optimizationObjectivesWithWeights;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JComponent editor;
|
||||
private JPanel targetList;
|
||||
private JTextField[] weights;
|
||||
private JComponent[] targets;
|
||||
private JButton[] deleteButton;
|
||||
private JScrollPane scrollTargets;
|
||||
private GeneralOptimizationEditorProperty[] editors;
|
||||
private PropertyChangeListener self;
|
||||
|
||||
public OptimizationObjectivesWithParamEditor() {
|
||||
self = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
self = this;
|
||||
this.editor = new JPanel();
|
||||
this.editor.setPreferredSize(new Dimension(450, 200));
|
||||
this.editor.setMinimumSize(new Dimension(450, 200));
|
||||
|
||||
// initialize the editors
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectivesWithWeights.getSelectedTargets();
|
||||
this.editors = new GeneralOptimizationEditorProperty[list.length];
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
this.editors[i] = new GeneralOptimizationEditorProperty();
|
||||
this.editors[i].name = list[i].getName();
|
||||
try {
|
||||
this.editors[i].value = list[i];
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(this.editors[i].value.getClass());
|
||||
if (this.editors[i].editor == null) {
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (this.editors[i].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) this.editors[i].editor).setClassType(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
this.editors[i].editor.setValue(this.editors[i].value);
|
||||
this.editors[i].editor.addPropertyChangeListener(this);
|
||||
AbstractObjectEditor.findViewFor(this.editors[i]);
|
||||
if (this.editors[i].view != null) {
|
||||
this.editors[i].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
}
|
||||
this.targetList = new JPanel();
|
||||
this.updateTargetList();
|
||||
this.scrollTargets = new JScrollPane(this.targetList);
|
||||
|
||||
this.editor.setLayout(new BorderLayout());
|
||||
this.editor.add(this.scrollTargets, BorderLayout.CENTER);
|
||||
|
||||
// The Button Panel
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setLayout(new GridLayout(1, 2));
|
||||
JButton addButton = new JButton("Add Opt. Target");
|
||||
JButton normButton = new JButton("Normalize Weights");
|
||||
normButton.setEnabled(this.optimizationObjectivesWithWeights.isNormalizationEnabled());
|
||||
normButton.addActionListener(normalizeWeights);
|
||||
addButton.addActionListener(addTarget);
|
||||
buttonPanel.add(normButton);
|
||||
buttonPanel.add(addButton);
|
||||
|
||||
this.editor.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Some description would be nice
|
||||
JTextArea jt = new JTextArea();
|
||||
jt.setFont(new Font("SansSerif", Font.PLAIN, 12));
|
||||
jt.setEditable(false);
|
||||
jt.setLineWrap(true);
|
||||
jt.setWrapStyleWord(true);
|
||||
jt.setText(this.optimizationObjectivesWithWeights.getDescriptiveString());
|
||||
jt.setBackground(getBackground());
|
||||
JPanel jp = new JPanel();
|
||||
jp.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createTitledBorder("Info"),
|
||||
BorderFactory.createEmptyBorder(0, 5, 5, 5)
|
||||
));
|
||||
jp.setLayout(new BorderLayout());
|
||||
jp.add(jt, BorderLayout.CENTER);
|
||||
JPanel p2 = new JPanel();
|
||||
p2.setLayout(new BorderLayout());
|
||||
JButton help = new JButton("Help");
|
||||
help.setEnabled(false);
|
||||
p2.add(help, BorderLayout.NORTH);
|
||||
jp.add(p2, BorderLayout.EAST);
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
|
||||
this.editor.add(jp, BorderLayout.NORTH);
|
||||
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the server list
|
||||
*/
|
||||
private void updateTargetList() {
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes;
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectivesWithWeights.getSelectedTargets();
|
||||
double[] weights = this.optimizationObjectivesWithWeights.getWeights();
|
||||
|
||||
this.targetList.removeAll();
|
||||
this.targetList.setLayout(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
this.weights = new JTextField[list.length];
|
||||
this.targets = new JComponent[list.length];
|
||||
this.deleteButton = new JButton[list.length];
|
||||
String[] cups = new String[8];
|
||||
for (int i = 0; i < cups.length; i++) {
|
||||
cups[i] = "" + (i + 1);
|
||||
}
|
||||
// The head title
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 0;
|
||||
gbc.weightx = 2;
|
||||
this.targetList.add(new JLabel(this.optimizationObjectivesWithWeights.getWeigthsLabel()), gbc);
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 10;
|
||||
this.targetList.add(new JLabel("Target"), gbc);
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.REMAINDER;
|
||||
gbc.gridx = 2;
|
||||
gbc.weightx = 1;
|
||||
this.targetList.add(new JLabel("Remove"), gbc);
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
// the weight
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 0;
|
||||
gbc.weightx = 2;
|
||||
this.weights[i] = new JTextField("" + weights[i]);
|
||||
this.weights[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.targetList.add(this.weights[i], gbc);
|
||||
// the status indicator
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridx = 1;
|
||||
gbc.weightx = 10;
|
||||
this.targets[i] = this.editors[i].view;
|
||||
this.targetList.add(this.targets[i], gbc);
|
||||
// The delete button
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
gbc.fill = GridBagConstraints.REMAINDER;
|
||||
gbc.gridx = 2;
|
||||
gbc.weightx = 1;
|
||||
bytes = loader.getBytesFromResourceLocation("images/Sub24.gif", true);
|
||||
this.deleteButton[i] = new JButton("", new ImageIcon(Toolkit.getDefaultToolkit().createImage(bytes)));
|
||||
this.deleteButton[i].addActionListener(deleteTarget);
|
||||
this.targetList.add(this.deleteButton[i], gbc);
|
||||
}
|
||||
this.targetList.repaint();
|
||||
this.targetList.validate();
|
||||
if (this.scrollTargets != null) {
|
||||
this.scrollTargets.validate();
|
||||
this.scrollTargets.repaint();
|
||||
}
|
||||
if (this.editor != null) {
|
||||
this.editor.validate();
|
||||
this.editor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener updateTargets = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener addTarget = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
optimizationObjectivesWithWeights.addTarget((InterfaceOptimizationObjective) optimizationObjectivesWithWeights.getAvailableTargets()[0].clone());
|
||||
int l = optimizationObjectivesWithWeights.getSelectedTargets().length;
|
||||
GeneralOptimizationEditorProperty[] newEdit = new GeneralOptimizationEditorProperty[l];
|
||||
System.arraycopy(editors, 0, newEdit, 0, editors.length);
|
||||
InterfaceOptimizationObjective[] list = optimizationObjectivesWithWeights.getSelectedTargets();
|
||||
l--;
|
||||
newEdit[l] = new GeneralOptimizationEditorProperty();
|
||||
newEdit[l].name = list[l].getName();
|
||||
try {
|
||||
newEdit[l].value = list[l];
|
||||
newEdit[l].editor = PropertyEditorProvider.findEditor(newEdit[l].value.getClass());
|
||||
if (newEdit[l].editor == null) {
|
||||
newEdit[l].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (newEdit[l].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) newEdit[l].editor).setClassType(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
newEdit[l].editor.setValue(newEdit[l].value);
|
||||
newEdit[l].editor.addPropertyChangeListener(self);
|
||||
AbstractObjectEditor.findViewFor(newEdit[l]);
|
||||
if (newEdit[l].view != null) {
|
||||
newEdit[l].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
editors = newEdit;
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener deleteTarget = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
int l = optimizationObjectivesWithWeights.getSelectedTargets().length, j = 0;
|
||||
GeneralOptimizationEditorProperty[] newEdit = new GeneralOptimizationEditorProperty[l - 1];
|
||||
for (int i = 0; i < deleteButton.length; i++) {
|
||||
if (event.getSource().equals(deleteButton[i])) {
|
||||
optimizationObjectivesWithWeights.removeTarget(i);
|
||||
} else {
|
||||
newEdit[j] = editors[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
editors = newEdit;
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener,...
|
||||
*/
|
||||
ActionListener normalizeWeights = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
double[] newW = optimizationObjectivesWithWeights.getWeights();
|
||||
double sum = 0;
|
||||
for (int i = 0; i < newW.length; i++) {
|
||||
sum += newW[i];
|
||||
}
|
||||
if (sum != 0) {
|
||||
for (int i = 0; i < newW.length; i++) {
|
||||
newW[i] /= sum;
|
||||
}
|
||||
optimizationObjectivesWithWeights.setWeights(newW);
|
||||
}
|
||||
updateTargetList();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
double[] newW = optimizationObjectivesWithWeights.getWeights();
|
||||
|
||||
for (int i = 0; i < newW.length; i++) {
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(weights[i].getText());
|
||||
newW[i] = d;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
optimizationObjectivesWithWeights.setWeights(newW);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.editor != null) {
|
||||
this.targetList.validate();
|
||||
this.targetList.repaint();
|
||||
this.scrollTargets.validate();
|
||||
this.scrollTargets.repaint();
|
||||
this.editor.validate();
|
||||
this.editor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyOptimizationObjectivesWithParam) {
|
||||
this.optimizationObjectivesWithWeights = (PropertyOptimizationObjectivesWithParam) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.optimizationObjectivesWithWeights;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Optimization Targets With Weights";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.editor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will udate the status of the object taking the values from all
|
||||
* supsequent editors and setting them to my object.
|
||||
*/
|
||||
public void updateCenterComponent(PropertyChangeEvent evt) {
|
||||
//this.updateTargetList();
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* ****************************** java.beans.PropertyChangeListener ************************
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (propertyChangeSupport == null) {
|
||||
propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
}
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will wait for the GenericObjectEditor to finish
|
||||
* editing an object.
|
||||
*
|
||||
* @param evt
|
||||
*/
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Object newVal = evt.getNewValue();
|
||||
Object oldVal = evt.getOldValue();
|
||||
InterfaceOptimizationObjective[] list = this.optimizationObjectivesWithWeights.getSelectedTargets();
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (oldVal.equals(list[i])) {
|
||||
list[i] = (InterfaceOptimizationObjective) newVal;
|
||||
this.editors[i].name = list[i].getName();
|
||||
try {
|
||||
this.editors[i].value = list[i];
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(this.editors[i].value.getClass());
|
||||
if (this.editors[i].editor == null) {
|
||||
this.editors[i].editor = PropertyEditorProvider.findEditor(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
if (this.editors[i].editor instanceof GenericObjectEditor) {
|
||||
((GenericObjectEditor) this.editors[i].editor).setClassType(InterfaceOptimizationObjective.class);
|
||||
}
|
||||
this.editors[i].editor.setValue(this.editors[i].value);
|
||||
this.editors[i].editor.addPropertyChangeListener(this);
|
||||
AbstractObjectEditor.findViewFor(this.editors[i]);
|
||||
if (this.editors[i].view != null) {
|
||||
this.editors[i].view.repaint();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Darn can't read the value...");
|
||||
}
|
||||
this.targets[i] = this.editors[i].view;
|
||||
}
|
||||
}
|
||||
this.updateCenterComponent(evt); // Let our panel update before guys downstream
|
||||
propertyChangeSupport.firePropertyChange("", optimizationObjectivesWithWeights, optimizationObjectivesWithWeights);
|
||||
}
|
||||
}
|
||||
85
src/main/java/eva2/gui/editor/StringSelectionEditor.java
Normal file
85
src/main/java/eva2/gui/editor/StringSelectionEditor.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.tools.StringSelection;
|
||||
import eva2.tools.StringTools;
|
||||
|
||||
public class StringSelectionEditor extends AbstractListSelectionEditor {
|
||||
StringSelection strs;
|
||||
|
||||
public StringSelectionEditor() {
|
||||
strs = new StringSelection(new String[]{}, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean actionOnSelect() {
|
||||
for (int i = 0; i < this.blackCheck.length; i++) {
|
||||
strs.setSelected(i, this.blackCheck[i].isSelected());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getElementCount() {
|
||||
return strs.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementName(int i) {
|
||||
return StringTools.humaniseCamelCase(strs.getElement(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getElementToolTip(int i) {
|
||||
return strs.getElementInfo(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return strs;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isElementSelected(int i) {
|
||||
return strs.isSelected(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setObject(Object o) {
|
||||
if (o instanceof StringSelection) {
|
||||
strs = (StringSelection) o;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "StringSelection";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
StringBuilder sbuf = new StringBuilder("{");
|
||||
boolean first = true;
|
||||
for (int i = 0; i < getElementCount(); i++) {
|
||||
if (isElementSelected(i)) {
|
||||
if (!first) {
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(getElementName(i));
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
sbuf.append("}");
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
for (int i = 0; i < getElementCount(); i++) {
|
||||
strs.setSelected(i, text.contains(getElementName(i)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
136
src/main/java/eva2/gui/editor/TagEditor.java
Normal file
136
src/main/java/eva2/gui/editor/TagEditor.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.EvAInfo;
|
||||
import eva2.gui.PropertyValueSelector;
|
||||
import eva2.tools.BasicResourceLoader;
|
||||
import eva2.tools.SelectedTag;
|
||||
import eva2.tools.Tag;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyEditorManager;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TagEditor extends PropertyEditorSupport {
|
||||
/**
|
||||
* Returns a description of the property value as java source.
|
||||
*
|
||||
* @return a value of type 'String'
|
||||
*/
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
|
||||
SelectedTag s = (SelectedTag) getValue();
|
||||
Tag[] tags = s.getTags();
|
||||
String result = "new SelectedTag("
|
||||
+ s.getSelectedTag().getID()
|
||||
+ ", {\n";
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
result += "new Tag(" + tags[i].getID()
|
||||
+ ",\"" + tags[i].getString()
|
||||
+ "\")";
|
||||
if (i < tags.length - 1) {
|
||||
result += ',';
|
||||
}
|
||||
result += '\n';
|
||||
}
|
||||
return result + "})";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value as text.
|
||||
*
|
||||
* @return a value of type 'String'
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
SelectedTag s = (SelectedTag) getValue();
|
||||
return s.getSelectedTag().getString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current property value as text.
|
||||
*
|
||||
* @param text the text of the selected tag.
|
||||
* @throws java.lang.IllegalArgumentException
|
||||
* if an error occurs
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws java.lang.IllegalArgumentException {
|
||||
SelectedTag s = (SelectedTag) getValue();
|
||||
Tag[] tags = s.getTags();
|
||||
try {
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
if (text.equals(tags[i].getString())) {
|
||||
setValue(new SelectedTag(tags[i].getID(), tags));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new java.lang.IllegalArgumentException(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of tags that can be selected from.
|
||||
*
|
||||
* @return an array of string tags.
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
|
||||
SelectedTag s = (SelectedTag) getValue();
|
||||
Tag[] tags = s.getTags();
|
||||
String[] result = new String[tags.length];
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
result[i] = tags[i].getString
|
||||
();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests out the selectedtag editor from the command line.
|
||||
*
|
||||
* @param args ignored
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
PropertyEditorManager.registerEditor(SelectedTag.class, TagEditor.class);
|
||||
Tag[] tags = {
|
||||
new Tag(0, "First option"),
|
||||
new Tag(1, "Second option"),
|
||||
new Tag(2, "Third option"),
|
||||
new Tag(3, "Fourth option"),
|
||||
new Tag(4, "Fifth option"),
|
||||
};
|
||||
SelectedTag initial = new SelectedTag(1, tags);
|
||||
TagEditor ce = new TagEditor();
|
||||
ce.setValue(initial);
|
||||
PropertyValueSelector ps = new PropertyValueSelector(ce);
|
||||
JFrame f = new JFrame();
|
||||
BasicResourceLoader loader = BasicResourceLoader.getInstance();
|
||||
byte[] bytes = loader.getBytesFromResourceLocation(EvAInfo.iconLocation, true);
|
||||
f.setIconImage(Toolkit.getDefaultToolkit().createImage(bytes));
|
||||
f.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
f.getContentPane().setLayout(new BorderLayout());
|
||||
f.getContentPane().add(ps, BorderLayout.CENTER);
|
||||
f.pack();
|
||||
f.setVisible(true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.err.println(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
322
src/main/java/eva2/gui/editor/WeigthedLPTchebycheffEditor.java
Normal file
322
src/main/java/eva2/gui/editor/WeigthedLPTchebycheffEditor.java
Normal file
@@ -0,0 +1,322 @@
|
||||
package eva2.gui.editor;
|
||||
|
||||
import eva2.gui.PropertyWeightedLPTchebycheff;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class WeigthedLPTchebycheffEditor extends JPanel implements PropertyEditor {
|
||||
|
||||
/**
|
||||
* Handles property change notification
|
||||
*/
|
||||
private PropertyChangeSupport support = new PropertyChangeSupport(this);
|
||||
/**
|
||||
* The label for when we can't edit that type
|
||||
*/
|
||||
private JLabel label = new JLabel("Can't edit", SwingConstants.CENTER);
|
||||
/**
|
||||
* The filePath that is to be edited
|
||||
*/
|
||||
private PropertyWeightedLPTchebycheff propertyWeightedLPTchebycheff;
|
||||
|
||||
/**
|
||||
* The gaphix stuff
|
||||
*/
|
||||
private JPanel customEditor, dataPanel, buttonPanel, targetPanel;
|
||||
private JTextField[] idealTextField, weightTextField;
|
||||
private JTextField pvalueTextField;
|
||||
private JButton okButton;
|
||||
|
||||
public WeigthedLPTchebycheffEditor() {
|
||||
// compiled code
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will initialize the CustomEditor Panel
|
||||
*/
|
||||
private void initCustomEditor() {
|
||||
this.customEditor = new JPanel();
|
||||
this.customEditor.setLayout(new BorderLayout());
|
||||
|
||||
// target panel
|
||||
this.targetPanel = new JPanel();
|
||||
this.targetPanel.setLayout(new GridLayout(1, 2));
|
||||
this.targetPanel.add(new JLabel("Choose P:"));
|
||||
this.pvalueTextField = new JTextField("" + this.propertyWeightedLPTchebycheff.p);
|
||||
this.targetPanel.add(this.pvalueTextField);
|
||||
this.pvalueTextField.addKeyListener(this.readDoubleAction);
|
||||
this.customEditor.add(this.targetPanel, BorderLayout.NORTH);
|
||||
|
||||
// initialize data panel
|
||||
this.dataPanel = new JPanel();
|
||||
this.updateDataPanel();
|
||||
this.customEditor.add(this.dataPanel, BorderLayout.CENTER);
|
||||
|
||||
// initialize button panel
|
||||
this.buttonPanel = new JPanel();
|
||||
this.okButton = new JButton("OK");
|
||||
this.okButton.setEnabled(true);
|
||||
this.okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//backupObject = copyObject(object);
|
||||
if ((customEditor.getTopLevelAncestor() != null) && (customEditor.getTopLevelAncestor() instanceof Window)) {
|
||||
Window w = (Window) customEditor.getTopLevelAncestor();
|
||||
w.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.buttonPanel.add(this.okButton);
|
||||
this.customEditor.add(this.buttonPanel, BorderLayout.SOUTH);
|
||||
this.updateEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
try {
|
||||
int d = Integer.parseInt(pvalueTextField.getText());
|
||||
propertyWeightedLPTchebycheff.p = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This action listener reads all values
|
||||
*/
|
||||
KeyListener readDoubleArrayAction = new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
double[] tmpT = propertyWeightedLPTchebycheff.idealValue;
|
||||
double[] tmpP = propertyWeightedLPTchebycheff.weights;
|
||||
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(idealTextField[i].getText());
|
||||
tmpT[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
double d = 0;
|
||||
d = Double.parseDouble(weightTextField[i].getText());
|
||||
tmpP[i] = d;
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
propertyWeightedLPTchebycheff.idealValue = tmpT;
|
||||
propertyWeightedLPTchebycheff.weights = tmpP;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The object may have changed update the editor.
|
||||
*/
|
||||
private void updateEditor() {
|
||||
if (this.customEditor != null) {
|
||||
this.updateDataPanel();
|
||||
this.customEditor.validate();
|
||||
this.customEditor.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the data panel
|
||||
*/
|
||||
private void updateDataPanel() {
|
||||
double[] tmpT = this.propertyWeightedLPTchebycheff.idealValue;
|
||||
double[] tmpP = this.propertyWeightedLPTchebycheff.weights;
|
||||
int obj = this.propertyWeightedLPTchebycheff.p;
|
||||
|
||||
this.pvalueTextField.setText("" + obj);
|
||||
this.dataPanel.removeAll();
|
||||
this.dataPanel.setLayout(new GridLayout(tmpT.length + 1, 3));
|
||||
this.dataPanel.add(new JLabel());
|
||||
this.dataPanel.add(new JLabel("Ideal Value"));
|
||||
this.dataPanel.add(new JLabel("Weights"));
|
||||
this.idealTextField = new JTextField[tmpT.length];
|
||||
this.weightTextField = new JTextField[tmpT.length];
|
||||
for (int i = 0; i < tmpT.length; i++) {
|
||||
JLabel label = new JLabel("Objective " + i + ": ");
|
||||
this.dataPanel.add(label);
|
||||
this.idealTextField[i] = new JTextField();
|
||||
this.idealTextField[i].setText("" + tmpT[i]);
|
||||
this.idealTextField[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.dataPanel.add(this.idealTextField[i]);
|
||||
this.weightTextField[i] = new JTextField();
|
||||
this.weightTextField[i].setText("" + tmpP[i]);
|
||||
this.weightTextField[i].addKeyListener(this.readDoubleArrayAction);
|
||||
this.dataPanel.add(this.weightTextField[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will set the value of object that is to be edited.
|
||||
*
|
||||
* @param o an object that must be an array.
|
||||
*/
|
||||
@Override
|
||||
public void setValue(Object o) {
|
||||
if (o instanceof PropertyWeightedLPTchebycheff) {
|
||||
this.propertyWeightedLPTchebycheff = (PropertyWeightedLPTchebycheff) o;
|
||||
this.updateEditor();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current object.
|
||||
*
|
||||
* @return the current object
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return this.propertyWeightedLPTchebycheff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaInitializationString() {
|
||||
return "TEST";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String[] getTags() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
if (support == null) {
|
||||
support = new PropertyChangeSupport(this);
|
||||
}
|
||||
support.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
if (support == null) {
|
||||
support = new PropertyChangeSupport(this);
|
||||
}
|
||||
support.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to hook an action listener to the ok button
|
||||
*
|
||||
* @param a The action listener.
|
||||
*/
|
||||
public void addOkListener(ActionListener a) {
|
||||
okButton.addActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to remove an action listener from the ok button
|
||||
*
|
||||
* @param a The action listener
|
||||
*/
|
||||
public void removeOkListener(ActionListener a) {
|
||||
okButton.removeActionListener(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true since the Object can be shown
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean isPaintable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints a representation of the current classifier.
|
||||
*
|
||||
* @param gfx the graphics context to use
|
||||
* @param box the area we are allowed to paint into
|
||||
*/
|
||||
@Override
|
||||
public void paintValue(Graphics gfx, Rectangle box) {
|
||||
FontMetrics fm = gfx.getFontMetrics();
|
||||
int vpad = (box.height - fm.getAscent()) / 2;
|
||||
String rep = "Edit the ideal vector, p and ev. the weights.";
|
||||
gfx.drawString(rep, 2, fm.getHeight() + vpad - 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true because we do support a custom editor.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsCustomEditor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array editing component.
|
||||
*
|
||||
* @return a value of type 'java.awt.Component'
|
||||
*/
|
||||
@Override
|
||||
public Component getCustomEditor() {
|
||||
if (this.customEditor == null) {
|
||||
this.initCustomEditor();
|
||||
}
|
||||
return customEditor;
|
||||
}
|
||||
}
|
||||
1
src/main/java/eva2/gui/editor/package-info.java
Normal file
1
src/main/java/eva2/gui/editor/package-info.java
Normal file
@@ -0,0 +1 @@
|
||||
package eva2.gui.editor;
|
||||
4
src/main/java/eva2/gui/package-info.java
Normal file
4
src/main/java/eva2/gui/package-info.java
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Base package for the EvA2 GUI.
|
||||
*/
|
||||
package eva2.gui;
|
||||
414
src/main/java/eva2/gui/plot/DPointSetMultiIcon.java
Normal file
414
src/main/java/eva2/gui/plot/DPointSetMultiIcon.java
Normal file
@@ -0,0 +1,414 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
|
||||
import eva2.tools.chart2d.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DPointSetMultiIcon extends DComponent {
|
||||
|
||||
/**
|
||||
* this class stores the jump positions (see this.jump)
|
||||
*/
|
||||
class JumpManager {
|
||||
protected int index = -1;
|
||||
protected ArrayList<Integer> jumps = new ArrayList<>();
|
||||
|
||||
public void addJump() {
|
||||
jumps.add(getSize());
|
||||
}
|
||||
|
||||
public boolean hasMoreIntervals() {
|
||||
return index < jumps.size();
|
||||
}
|
||||
|
||||
public int[] nextInterval() {
|
||||
int no_jumps = jumps.size();
|
||||
|
||||
if (index >= no_jumps) {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
"No more intervals in JumpManager");
|
||||
}
|
||||
|
||||
int[] inter = new int[2];
|
||||
|
||||
if (index == -1) {
|
||||
inter[0] = 0;
|
||||
} else {
|
||||
inter[0] = jumps.get(index);
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (index < no_jumps) {
|
||||
inter[1] = jumps.get(index);
|
||||
} else {
|
||||
inter[1] = getSize();
|
||||
}
|
||||
|
||||
return inter;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
index = -1;
|
||||
jumps.clear();
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean connectedMI;
|
||||
protected DPointIcon iconMI = null;
|
||||
protected DPointSetMultiIcon.JumpManager jumperMI = new DPointSetMultiIcon.JumpManager();
|
||||
protected ArrayList<DPointIcon> iconsMI = new ArrayList<>();
|
||||
protected Stroke strokeMI = new BasicStroke();
|
||||
protected DIntDoubleMap xMI;
|
||||
|
||||
//~ Constructors ///////////////////////////////////////////////////////////
|
||||
|
||||
protected DIntDoubleMap yMI;
|
||||
|
||||
public DPointSetMultiIcon() {
|
||||
this(10, 2);
|
||||
}
|
||||
|
||||
public DPointSetMultiIcon(DIntDoubleMap x_values, DIntDoubleMap y_values) {
|
||||
if (x_values.getSize() != y_values.getSize()) {
|
||||
throw new IllegalArgumentException(
|
||||
"The number of x-values has to be the same than the number of y-values");
|
||||
}
|
||||
|
||||
xMI = x_values;
|
||||
yMI = y_values;
|
||||
restore();
|
||||
setDBorder(new DBorder(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
public DPointSetMultiIcon(int initial_capacity) {
|
||||
this(initial_capacity, 2);
|
||||
}
|
||||
|
||||
//~ Methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
public DPointSetMultiIcon(int initial_capacity, int length_multiplier) {
|
||||
this(new DArray(initial_capacity, length_multiplier),
|
||||
new DArray(initial_capacity, length_multiplier));
|
||||
}
|
||||
|
||||
public void addDPoint(double x, double y) {
|
||||
addDPoint(new DPoint(x, y));
|
||||
}
|
||||
|
||||
public void addDPoint(DPoint p) {
|
||||
xMI.addImage(p.x);
|
||||
yMI.addImage(p.y);
|
||||
iconsMI.add(p.getIcon());
|
||||
rectangle.insert(p);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* method returns the DPoint at the given index
|
||||
*
|
||||
* @param index the index of the DPoint
|
||||
* @return the DPoint at the given index
|
||||
*/
|
||||
public DPoint getDPoint(int index) {
|
||||
if (index >= xMI.getSize()) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
|
||||
DPoint p = new DPoint(xMI.getImage(index), yMI.getImage(index));
|
||||
p.setIcon(iconMI);
|
||||
p.setColor(color);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public DPointSet getDPointSet() {
|
||||
return new DPointSet(xMI, yMI);
|
||||
}
|
||||
|
||||
/**
|
||||
* method returns the current icon of the point set
|
||||
*
|
||||
* @return the DPointIcon
|
||||
*/
|
||||
public DPointIcon getIcon() {
|
||||
return iconMI;
|
||||
}
|
||||
|
||||
public ArrayList<DPointIcon> getIconsMI() {
|
||||
return this.iconsMI;
|
||||
}
|
||||
|
||||
/**
|
||||
* method returns the nearest <code>DPoint</code> in this <code>DPointSet</code>.
|
||||
*
|
||||
* @return the nearest <code>DPoint</code>
|
||||
*/
|
||||
public DPoint getNearestDPoint(DPoint point) {
|
||||
int minIndex = getNearestDPointIndex(point);
|
||||
|
||||
if (minIndex == -1) {
|
||||
return null;
|
||||
} else {
|
||||
DPoint result = new DPoint(xMI.getImage(minIndex),
|
||||
yMI.getImage(minIndex));
|
||||
result.setIcon(this.iconsMI.get(minIndex));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* method returns the index to the nearest <code>DPoint</code> in this <code>DPointSet</code>.
|
||||
*
|
||||
* @return the index to the nearest <code>DPoint</code>. -1 if no nearest <code>DPoint</code> was found.
|
||||
*/
|
||||
public int getNearestDPointIndex(DPoint point) {
|
||||
double minValue = Double.MAX_VALUE;
|
||||
int minIndex = -1;
|
||||
|
||||
for (int i = 0; i < xMI.getSize(); i++) {
|
||||
double dx = point.x - xMI.getImage(i);
|
||||
double dy = point.y - yMI.getImage(i);
|
||||
double dummy = (dx * dx) + (dy * dy);
|
||||
|
||||
if (dummy < minValue) {
|
||||
minValue = dummy;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
return minIndex;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return Math.min(xMI.getSize(), yMI.getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* method returns the current stroke of the line
|
||||
*
|
||||
* @return the stroke
|
||||
*/
|
||||
public Stroke getStroke() {
|
||||
return strokeMI;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method causes the DPointSet to interupt the connected painting at the
|
||||
* current position.
|
||||
*/
|
||||
public void jump() {
|
||||
jumperMI.addJump();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(DMeasures m) {
|
||||
try {
|
||||
Graphics2D g = (Graphics2D) m.getGraphics();
|
||||
g.setStroke(strokeMI);
|
||||
|
||||
if (color != null) {
|
||||
g.setColor(color);
|
||||
}
|
||||
|
||||
int size = getSize();
|
||||
|
||||
if (connectedMI && (size > 1)) {
|
||||
jumperMI.restore();
|
||||
|
||||
while (jumperMI.hasMoreIntervals()) {
|
||||
int[] interval = jumperMI.nextInterval();
|
||||
Point p1 = null;
|
||||
Point p2;
|
||||
|
||||
for (int i = interval[0]; i < interval[1]; i++) {
|
||||
p2 = m.getPoint(xMI.getImage(i), yMI.getImage(i));
|
||||
if (p1 != null) {
|
||||
if (p2 != null) {
|
||||
g.drawLine(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
}
|
||||
|
||||
if ((i < this.iconsMI.size()) && (this.iconsMI.get(i) != null)) {
|
||||
g.setStroke(new BasicStroke());
|
||||
g.translate(p2.x, p2.y);
|
||||
this.iconsMI.get(i).paint(g);
|
||||
g.translate(-p2.x, -p2.y);
|
||||
g.setStroke(strokeMI);
|
||||
} else {
|
||||
if (iconMI != null) {
|
||||
g.setStroke(new BasicStroke());
|
||||
g.translate(p2.x, p2.y);
|
||||
iconMI.paint(g);
|
||||
g.translate(-p2.x, -p2.y);
|
||||
g.setStroke(strokeMI);
|
||||
}
|
||||
}
|
||||
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Point p;
|
||||
|
||||
//for (int i = 0; i < size; i++)
|
||||
// @todo Streiche: Mal wieder eine index out of bounds exception, dass ist einfach mist...
|
||||
for (int i = 0; i < this.iconsMI.size(); i++) {
|
||||
try {
|
||||
p = m.getPoint(xMI.getImage(i), yMI.getImage(i));
|
||||
|
||||
if (p == null) {
|
||||
continue;
|
||||
}
|
||||
if (this.iconsMI.get(i) != null) {
|
||||
g.setStroke(new BasicStroke());
|
||||
g.translate(p.x, p.y);
|
||||
this.iconsMI.get(i).paint(g);
|
||||
g.translate(-p.x, -p.y);
|
||||
g.setStroke(strokeMI);
|
||||
} else {
|
||||
if (iconMI == null) {
|
||||
g.drawLine(p.x - 1, p.y - 1, p.x + 1, p.y + 1);
|
||||
g.drawLine(p.x + 1, p.y - 1, p.x - 1, p.y + 1);
|
||||
} else {
|
||||
g.setStroke(new BasicStroke());
|
||||
g.translate(p.x, p.y);
|
||||
iconMI.paint(g);
|
||||
g.translate(-p.x, -p.y);
|
||||
}
|
||||
}
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.out.println(
|
||||
"The rectangle lies not in the currently painted rectangle.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.setStroke(new BasicStroke());
|
||||
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
|
||||
// *pff*
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllPoints() {
|
||||
if (xMI.getSize() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
xMI.reset();
|
||||
yMI.reset();
|
||||
jumperMI.reset();
|
||||
repaint();
|
||||
rectangle = DRectangle.getEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* method removes all jump positions
|
||||
* if the DPointSet is connected, all points will be painted connected to
|
||||
* their following point
|
||||
*/
|
||||
public void removeJumps() {
|
||||
jumperMI.reset();
|
||||
}
|
||||
|
||||
protected void restore() {
|
||||
if (getSize() == 0) {
|
||||
rectangle = DRectangle.getEmpty();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
double min_x = xMI.getMinImageValue();
|
||||
double max_x = xMI.getMaxImageValue();
|
||||
double min_y = yMI.getMinImageValue();
|
||||
double max_y = yMI.getMaxImageValue();
|
||||
rectangle = new DRectangle(min_x, min_y, max_x - min_x, max_y - min_y);
|
||||
}
|
||||
|
||||
public void setConnected(boolean aFlag) {
|
||||
boolean changed = !(aFlag == connectedMI);
|
||||
connectedMI = aFlag;
|
||||
|
||||
if (changed) {
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* method puts the given DPoint at the given position in the set
|
||||
*
|
||||
* @param index the index of the point
|
||||
* @param p the point to insert
|
||||
*/
|
||||
public void setDPoint(int index, DPoint p) {
|
||||
if (index >= xMI.getSize()) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
|
||||
rectangle.insert(p);
|
||||
xMI.setImage(index, p.x);
|
||||
yMI.setImage(index, p.y);
|
||||
iconsMI.set(index, p.getIcon());
|
||||
restore();
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* method sets an icon for a better displaying of the point set
|
||||
*
|
||||
* @param icon the DPointIcon
|
||||
*/
|
||||
public void setIcon(DPointIcon icon) {
|
||||
this.iconMI = icon;
|
||||
|
||||
if (icon == null) {
|
||||
setDBorder(new DBorder(1, 1, 1, 1));
|
||||
} else {
|
||||
setDBorder(icon.getDBorder());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* method sets the stroke of the line
|
||||
* if the points were not connected, they now will be connected
|
||||
*
|
||||
* @param s the new stroke
|
||||
*/
|
||||
public void setStroke(Stroke s) {
|
||||
if (s == null) {
|
||||
s = new BasicStroke();
|
||||
}
|
||||
|
||||
strokeMI = s;
|
||||
repaint();
|
||||
}
|
||||
|
||||
//~ Inner Classes //////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String text = "eva2.tools.chart2d.DPointSet[size:" + getSize();
|
||||
|
||||
for (int i = 0; i < xMI.getSize(); i++) {
|
||||
text += (",(" + xMI.getImage(i) + "," + yMI.getImage(i) + ")");
|
||||
}
|
||||
|
||||
text += "]";
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// END OF FILE.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
65
src/main/java/eva2/gui/plot/Exp.java
Normal file
65
src/main/java/eva2/gui/plot/Exp.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
import eva2.tools.chart2d.DFunction;
|
||||
|
||||
/**
|
||||
* Represents an exponential scaling function.
|
||||
* MK: added a guard against undefined values: the smallest positive position can
|
||||
* be stored and used instead of invalid points.
|
||||
*/
|
||||
public class Exp extends DFunction {
|
||||
private double minValue = 1e-10; // think of a minimal value we want to show in case invalid (<=0) values are requested
|
||||
|
||||
public void setMinValue(double v) {
|
||||
if (v > 0) {
|
||||
minValue = v;
|
||||
} else {
|
||||
System.err.println("Error, minimal value for Exp must be positive!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see eva2.tools.chart2d.DFunction#isDefinedAt(double)
|
||||
*/
|
||||
@Override
|
||||
public boolean isDefinedAt(double source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see eva2.tools.chart2d.DFunction#isInvertibleAt(double)
|
||||
*/
|
||||
@Override
|
||||
public boolean isInvertibleAt(double image) {
|
||||
return image > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see eva2.tools.chart2d.DFunction#getImageOf(double)
|
||||
*/
|
||||
@Override
|
||||
public double getImageOf(double source) {
|
||||
return Math.exp(source);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see eva2.tools.chart2d.DFunction#getSourceOf(double)
|
||||
*/
|
||||
@Override
|
||||
public double getSourceOf(double target) {
|
||||
if (target <= 0) {
|
||||
return Math.log(minValue); // think of a minimal value we want to show in case invalid values are requested
|
||||
}
|
||||
return Math.log(target);
|
||||
}
|
||||
|
||||
public void updateMinValue(double y) {
|
||||
if (y < minValue && (y > 0)) {
|
||||
minValue = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
1115
src/main/java/eva2/gui/plot/FunctionArea.java
Normal file
1115
src/main/java/eva2/gui/plot/FunctionArea.java
Normal file
File diff suppressed because it is too large
Load Diff
103
src/main/java/eva2/gui/plot/Graph.java
Normal file
103
src/main/java/eva2/gui/plot/Graph.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Graph implements Serializable {
|
||||
|
||||
private PlotInterface plotter;
|
||||
private int graphLabel;
|
||||
private String infoString;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Graph(String info, PlotInterface plotter, int x) {
|
||||
infoString = info;
|
||||
this.plotter = plotter;
|
||||
graphLabel = x;
|
||||
if (plotter == null) {
|
||||
System.out.println("In constructor plotter == null");
|
||||
}
|
||||
plotter.setInfoString(graphLabel, info, (float) 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getInfo() {
|
||||
return infoString;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setInfoString(String info, float stroke) {
|
||||
plotter.setInfoString(graphLabel, info, stroke);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public int getGraphLabel() {
|
||||
return graphLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setConnectedPoint(double x, double y) {
|
||||
plotter.setConnectedPoint(x, y, graphLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void clear() {
|
||||
plotter.clearGraph(graphLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setUnconnectedPoint(double x, double y) {
|
||||
plotter.setUnconnectedPoint(x, y, graphLabel);
|
||||
}
|
||||
|
||||
public int getPointCount() {
|
||||
return plotter.getPointCount(graphLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a graph to this graph object. Uses "force" for mismatching point counts, but returns
|
||||
* false if force was used and points possibly have been lost.
|
||||
*
|
||||
* @return true if the graph could be added directly or false if the graph was added by force
|
||||
* losing some data points
|
||||
* @see PlotInterface#addGraph
|
||||
*/
|
||||
public boolean addGraph(Graph x) {
|
||||
boolean useForce = false;
|
||||
//System.out.println("adding graph " + x.getGraphLabel() + " to " + getGraphLabel());
|
||||
if ((getPointCount() != 0) && (getPointCount() != x.getPointCount())) {
|
||||
//System.err.println("mismatching graphs, point counts were " + getPointCount() + " " + x.getPointCount());
|
||||
useForce = true;
|
||||
}
|
||||
plotter.jump();
|
||||
plotter.addGraph(graphLabel, x.getGraphLabel(), useForce);
|
||||
return !useForce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the PlotInterface to interrupt the connected painting at the current position.
|
||||
*/
|
||||
public void jump() {
|
||||
plotter.jump();
|
||||
}
|
||||
|
||||
public void setColorByIndex(int j) {
|
||||
((Plot) plotter).setColorByIndex(graphLabel, j);
|
||||
}
|
||||
}
|
||||
447
src/main/java/eva2/gui/plot/GraphPointSet.java
Normal file
447
src/main/java/eva2/gui/plot/GraphPointSet.java
Normal file
@@ -0,0 +1,447 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
|
||||
import eva2.tools.chart2d.*;
|
||||
import eva2.tools.math.Mathematics;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class GraphPointSet {
|
||||
// Color sequence of the plot graphs
|
||||
public static Color[] colorSequence =
|
||||
new Color[]{
|
||||
Color.black, Color.red, Color.blue, Color.pink, Color.green,
|
||||
Color.gray, Color.magenta, Color.cyan, Color.orange,
|
||||
new Color(148, 0, 211), // dark violet,
|
||||
new Color(72, 209, 204), // turquoise
|
||||
new Color(128, 128, 0), // olive
|
||||
new Color(34, 139, 34), // forest green
|
||||
new Color(100, 149, 237) // cornflower
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PointSet implements Serializable {
|
||||
/**
|
||||
* Generated serial version identifier
|
||||
*/
|
||||
private static final long serialVersionUID = -5863595580492128866L;
|
||||
private Color color;
|
||||
private double[] x;
|
||||
private double[] y;
|
||||
|
||||
/**
|
||||
* @param pointset
|
||||
*/
|
||||
public PointSet(DPointSet pointset) {
|
||||
color = pointset.getColor();
|
||||
x = new double[pointset.getSize()];
|
||||
y = new double[pointset.getSize()];
|
||||
for (int i = 0; i < pointset.getSize(); i++) {
|
||||
DPoint point = pointset.getDPoint(i);
|
||||
x[i] = point.x;
|
||||
y[i] = point.y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public DPointSet getDPointSet() {
|
||||
DPointSet ret = new DPointSet(100);
|
||||
ret.setColor(color);
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
ret.addDPoint(x[i], y[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int getSize() {
|
||||
return x.length;
|
||||
}
|
||||
}
|
||||
|
||||
private int colorOffset = 0;
|
||||
private DArea area;
|
||||
private int cacheIndex = 0;
|
||||
private int cacheSize = 0;
|
||||
private double[] cachex;
|
||||
private double[] cachey;
|
||||
private Color color;
|
||||
private DPointSetMultiIcon connectedPointSet;
|
||||
private int graphLabel;
|
||||
private DPointIcon icon;
|
||||
private String infoString = "Incomplete_Run";
|
||||
private boolean isStatisticsGraph = false;
|
||||
private ArrayList<PointSet> pointSetContainer = new ArrayList<>();
|
||||
|
||||
private float stroke = (float) 1.0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public GraphPointSet(int GraphLabel, DArea Area) {
|
||||
cachex = new double[cacheSize];
|
||||
cachey = new double[cacheSize];
|
||||
area = Area;
|
||||
graphLabel = GraphLabel;
|
||||
connectedPointSet = new DPointSetMultiIcon(100);
|
||||
connectedPointSet.setStroke(new BasicStroke(stroke));
|
||||
connectedPointSet.setConnected(true);
|
||||
|
||||
setColor(indexToColor(GraphLabel));
|
||||
initGraph(Area);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size
|
||||
* @param GraphLabel
|
||||
*/
|
||||
private GraphPointSet(int size, int GraphLabel) {
|
||||
graphLabel = GraphLabel;
|
||||
cachex = new double[cacheSize];
|
||||
cachey = new double[cacheSize];
|
||||
connectedPointSet = new DPointSetMultiIcon(100);
|
||||
connectedPointSet.setStroke(new BasicStroke(stroke));
|
||||
|
||||
connectedPointSet.setConnected(true);
|
||||
color = Color.black;
|
||||
|
||||
color = indexToColor(GraphLabel);
|
||||
|
||||
connectedPointSet.setColor(color);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
public void addDPoint(double x, double y) {
|
||||
if (cacheIndex == cacheSize) {
|
||||
for (int i = 0; i < cacheSize; i++) {
|
||||
connectedPointSet.addDPoint(cachex[i], cachey[i]);
|
||||
}
|
||||
connectedPointSet.addDPoint(x, y);
|
||||
cacheIndex = 0;
|
||||
} else {
|
||||
cachex[cacheIndex] = x;
|
||||
cachey[cacheIndex] = y;
|
||||
cacheIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
*/
|
||||
public void addDPoint(DPoint p) {
|
||||
connectedPointSet.addDPoint(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a graph to another one forming a statistics graph if it isnt one
|
||||
* already.
|
||||
*
|
||||
* @param set
|
||||
* @param measures
|
||||
* @param useForce forces the add even if point counts mismatch, maybe losing
|
||||
* some data points
|
||||
*/
|
||||
public void addGraph(GraphPointSet set, DMeasures measures, boolean useForce) {
|
||||
if (set.connectedPointSet.getSize() != connectedPointSet.getSize()
|
||||
&& connectedPointSet.getSize() != 0 && !useForce) {
|
||||
System.err.println("WARNING addGraph not possible, lost last graph");
|
||||
System.err.println(" connectedPointSet.getSize() " + connectedPointSet.getSize());
|
||||
return;
|
||||
}
|
||||
if (set.getPointSet().getSize() == 0) {
|
||||
System.err.println("Refusing to add empty graph...");
|
||||
return;
|
||||
}
|
||||
isStatisticsGraph = true;
|
||||
removeAllPoints();
|
||||
connectedPointSet.setColor(set.getColor());
|
||||
|
||||
pointSetContainer.add(set.getPointSet());
|
||||
int[] index = new int[pointSetContainer.size()];
|
||||
int[] GraphSize = new int[pointSetContainer.size()];
|
||||
for (int i = 0; i < pointSetContainer.size(); i++) {
|
||||
GraphSize[i] = pointSetContainer.get(i).getSize();
|
||||
if (GraphSize[i] <= 0) {
|
||||
System.err.println("Warning: invalid graph size of "
|
||||
+ GraphSize[i] + " at " + i
|
||||
+ "! (GraphPointSet.addGraph)");
|
||||
}
|
||||
}
|
||||
if (Mathematics.sum(GraphSize) == 0) {
|
||||
System.err
|
||||
.println("Error: not adding empty graphs... (GraphPointSet.addGraph)");
|
||||
return;
|
||||
}
|
||||
boolean allSetsHaveMorePoints = true;
|
||||
double nextXValue;
|
||||
double[] y = new double[pointSetContainer.size()];
|
||||
while (allSetsHaveMorePoints) { // Loop over all point sets, add them up
|
||||
// and calc. mean
|
||||
// this is a bit more complicated because it is allowed that the
|
||||
// point sets are asynchronouos
|
||||
// in the sense that the x values do not have to match - y values
|
||||
// for any x value found are averaged
|
||||
// over all points. However curves may look strange if this happens,
|
||||
// since they consist of
|
||||
// heterogenous points.
|
||||
nextXValue = pointSetContainer.get(0).x[index[0]];
|
||||
// System.out.println("pointSetContainer.size()"+pointSetContainer.size());
|
||||
for (int i = 1; i < pointSetContainer.size(); i++) { // search for
|
||||
// smalles x
|
||||
// value at
|
||||
// next
|
||||
// index
|
||||
// System.out.println("i="+i);
|
||||
if (nextXValue > pointSetContainer.get(i).x[index[i]]) {
|
||||
nextXValue = pointSetContainer.get(i).x[index[i]];
|
||||
}
|
||||
}
|
||||
// Stelle nextXValue wird gezeichnet. jetzt alle y werte dazu finden
|
||||
int numberofpoints = 0;
|
||||
for (int i = 0; i < pointSetContainer.size(); i++) { // collect
|
||||
// all
|
||||
// points at
|
||||
// next
|
||||
// x-value
|
||||
if (nextXValue == pointSetContainer.get(i).x[index[i]]) {
|
||||
y[i] = pointSetContainer.get(i).y[index[i]];
|
||||
index[i]++;
|
||||
numberofpoints++;
|
||||
} else {
|
||||
y[i] = 0;
|
||||
}
|
||||
}
|
||||
double ymean = Mathematics.sum(y) / numberofpoints;
|
||||
// compute median double median = getMedian(y);
|
||||
addDPoint(nextXValue, ymean);// System.out.println("ymean "+ymean+" y.length "+
|
||||
// y.length);
|
||||
// addDPoint(minx,median);//
|
||||
// System.out.println("ymean "+ymean+" y.length "+ y.length);
|
||||
for (int i = 0; i < pointSetContainer.size(); i++) { // Stop if
|
||||
// one of
|
||||
// the point
|
||||
// sets has
|
||||
// no more
|
||||
// points
|
||||
if (GraphSize[i] <= index[i]) {
|
||||
allSetsHaveMorePoints = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Color getColor() {
|
||||
return connectedPointSet.getColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public DPointSet getConnectedPointSet() {
|
||||
return connectedPointSet.getDPointSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int getGraphLabel() {
|
||||
return graphLabel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getInfoString() {
|
||||
return infoString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
public DPoint getNearestDPoint(DPoint p) {
|
||||
return connectedPointSet.getNearestDPoint(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int getPointCount() {
|
||||
return connectedPointSet.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public PointSet getPointSet() {
|
||||
return new PointSet(this.connectedPointSet.getDPointSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public DPointSetMultiIcon getReference2ConnectedPointSet() {
|
||||
return connectedPointSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the color sequentially.
|
||||
*/
|
||||
public void incColor() {
|
||||
colorOffset++;
|
||||
setColor(indexToColor(graphLabel + colorOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Color indexToColor(int index) {
|
||||
int k = index % colorSequence.length;
|
||||
return colorSequence[k];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Area
|
||||
*/
|
||||
public void initGraph(DArea Area) {
|
||||
area = Area;
|
||||
area.addDElement(connectedPointSet);
|
||||
((FunctionArea) area).addGraphPointSet(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean isStatisticsGraph() {
|
||||
return isStatisticsGraph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the PointSet to interrupt the connected painting at the current
|
||||
* position.
|
||||
*/
|
||||
public void jump() {
|
||||
connectedPointSet.jump();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public DPointSet printPoints() {
|
||||
for (int i = 0; i < connectedPointSet.getSize(); i++) {
|
||||
DPoint p = connectedPointSet.getDPoint(i);
|
||||
double x = p.x;
|
||||
double y = p.y;
|
||||
System.out.println("point " + i + " x = " + x + "y = " + y);
|
||||
}
|
||||
return connectedPointSet.getDPointSet();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void removeAllPoints() {
|
||||
connectedPointSet.removeAllPoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
*/
|
||||
public void removePoint(DPoint x) {
|
||||
System.out.println("removePoint " + x.x + " " + x.y);
|
||||
DPoint[] buf = new DPoint[connectedPointSet.getSize()];
|
||||
for (int i = 0; i < connectedPointSet.getSize(); i++) {
|
||||
buf[i] = connectedPointSet.getDPoint(i);
|
||||
}
|
||||
connectedPointSet.removeAllPoints();
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
if (buf[i].x == x.x && buf[i].y == x.y) {
|
||||
System.out.println("point found");
|
||||
} else {
|
||||
connectedPointSet.addDPoint(buf[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param c
|
||||
*/
|
||||
public void setColor(Color c) {
|
||||
color = c;
|
||||
connectedPointSet.setColor(color);
|
||||
}
|
||||
|
||||
public void setColorByIndex(int i) {
|
||||
setColor(indexToColor(i));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
*/
|
||||
public void setConnectedMode(boolean p) {
|
||||
connectedPointSet.setConnected(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
*/
|
||||
public void setIcon(DPointIcon p) {
|
||||
this.icon = p;
|
||||
this.connectedPointSet.setIcon(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* @param stroke
|
||||
*/
|
||||
public void setInfoString(String x, float stroke) {
|
||||
infoString = x;
|
||||
this.stroke = stroke;
|
||||
// setStroke(new BasicStroke( stroke ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the info string without changing the stroke.
|
||||
*
|
||||
* @param x
|
||||
*/
|
||||
public void setInfoString(String x) {
|
||||
infoString = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the median point of this point set.
|
||||
*
|
||||
* @return the median point of this point set or null if it is empty
|
||||
*/
|
||||
public DPoint getMedPoint() {
|
||||
if (connectedPointSet == null) {
|
||||
return null;
|
||||
}
|
||||
int medX = connectedPointSet.getSize() / 2;
|
||||
return connectedPointSet.getDPoint(medX);
|
||||
}
|
||||
}
|
||||
190
src/main/java/eva2/gui/plot/GraphPointSetLegend.java
Normal file
190
src/main/java/eva2/gui/plot/GraphPointSetLegend.java
Normal file
@@ -0,0 +1,190 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
import eva2.tools.Pair;
|
||||
import eva2.tools.StringTools;
|
||||
import eva2.tools.chart2d.SlimRect;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class representing the legend of a plot. It is created from a list of
|
||||
* GraphPointSets as used in FunctionArea. Painting is done in FunctionArea. As
|
||||
* an alternative, an own frame could be created.
|
||||
*
|
||||
* @author mkron, draeger
|
||||
*/
|
||||
public class GraphPointSetLegend {
|
||||
SortedSet<Pair<String, Color>> legendEntries;
|
||||
|
||||
/**
|
||||
* @author draeger
|
||||
*/
|
||||
private static class PairComp implements Comparator<Pair<String, Color>> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compare(Pair<String, Color> o1, Pair<String, Color> o2) {
|
||||
int comp = o1.car().compareTo(o2.car());
|
||||
// Same text; let us see if the color is also identical.
|
||||
return comp == 0 ? comp = Integer.valueOf(o1.cdr().getRGB())
|
||||
.compareTo(o2.cdr().getRGB()) : comp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final PairComp comparator = new PairComp();
|
||||
|
||||
/**
|
||||
* A constructor which may enumerate the point sets.
|
||||
*
|
||||
* @param pointSetContainer the set of point sets to be shown.
|
||||
* @param appendIndex if true, the string entries are enumerated according to the index
|
||||
*/
|
||||
public GraphPointSetLegend(List<GraphPointSet> pointSetContainer, boolean appendIndex) {
|
||||
legendEntries = new TreeSet<>(comparator);
|
||||
for (int i = 0; i < pointSetContainer.size(); i++) {
|
||||
GraphPointSet pointset = pointSetContainer.get(i);
|
||||
if (pointset.getPointSet().getSize() > 0) {
|
||||
String entryStr;
|
||||
if (appendIndex) {
|
||||
entryStr = StringTools.expandPrefixZeros(i, pointSetContainer.size() - 1) + ": " + pointset.getInfoString();
|
||||
} else {
|
||||
entryStr = pointset.getInfoString();
|
||||
}
|
||||
legendEntries.add(new Pair<>(entryStr, pointset.getColor()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor without enumeration.
|
||||
*
|
||||
* @param pointSetContainer the set of point sets to be shown.
|
||||
*/
|
||||
public GraphPointSetLegend(List<GraphPointSet> pointSetContainer) {
|
||||
this(pointSetContainer, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the legend labels to a container.
|
||||
*
|
||||
* @param comp
|
||||
*/
|
||||
public void addToContainer(JComponent comp) {
|
||||
for (Pair<String, Color> legendEntry : legendEntries) {
|
||||
JLabel label = new JLabel(legendEntry.head);
|
||||
label.setForeground(legendEntry.tail);
|
||||
comp.add(label);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bgCol
|
||||
* @param pointSetContainer
|
||||
* @return
|
||||
*/
|
||||
public static JPanel makeLegendPanel(Color bgCol,
|
||||
ArrayList<GraphPointSet> pointSetContainer) {
|
||||
JPanel pan = new JPanel();
|
||||
pan.setBackground(bgCol);
|
||||
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
|
||||
GraphPointSetLegend lBox = new GraphPointSetLegend(pointSetContainer);
|
||||
lBox.addToContainer(pan);
|
||||
return pan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bgCol
|
||||
* @param pointSetContainer
|
||||
* @return
|
||||
*/
|
||||
public static JFrame makeLegendFrame(Color bgCol,
|
||||
ArrayList<GraphPointSet> pointSetContainer) {
|
||||
JFrame frame = new JFrame("Legend");
|
||||
// LegendBox lBox = new LegendBox(bgCol, pointSetContainer);
|
||||
frame.add(makeLegendPanel(bgCol, pointSetContainer));
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param component
|
||||
*/
|
||||
public void paintIn(JComponent component) {
|
||||
Graphics g = component.getGraphics();
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int yOffs = 5 + fm.getHeight();
|
||||
int xOffs = 0;
|
||||
Color origCol = g.getColor();
|
||||
|
||||
for (Pair<String, Color> legendEntry : legendEntries) {
|
||||
g.setColor(legendEntry.tail);
|
||||
Rectangle2D rect = fm.getStringBounds(legendEntry.head, g);
|
||||
xOffs = (int) (component.getWidth() - rect.getWidth() - 5);
|
||||
g.drawString(legendEntry.head, xOffs, yOffs);
|
||||
yOffs += (5 + rect.getHeight());
|
||||
}
|
||||
g.setColor(origCol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from FunctionArea
|
||||
* @see FunctionArea#paint
|
||||
*/
|
||||
public void paintIn(Graphics g, SlimRect rect) {
|
||||
paintIn(g, (int) rect.getX(), (int) rect.getY(), (int) rect.getX() + (int) rect.getWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param g
|
||||
* @param x
|
||||
* @param y
|
||||
* @param maxX
|
||||
*/
|
||||
private void paintIn(Graphics g, int x, int y, int maxX) {
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
double fontHeightSum = 0.0;
|
||||
// Padding is used for in-box padding and out-box positioning
|
||||
int padding = 5;
|
||||
// yOffs used as bottom-left position for text line
|
||||
double yOffs = padding + y + fm.getHeight();
|
||||
int minX = Integer.MAX_VALUE;
|
||||
Color origCol = g.getColor();
|
||||
|
||||
// Draw bounding box
|
||||
for (Pair<String, Color> legendEntry : legendEntries) {
|
||||
Rectangle2D stringBounds = fm.getStringBounds(legendEntry.head, g);
|
||||
minX = Math.min(minX, (int) (maxX - stringBounds.getWidth() - 20));
|
||||
// Compute the combined height + padding of each line
|
||||
fontHeightSum += stringBounds.getHeight() + padding;
|
||||
}
|
||||
|
||||
//
|
||||
int boxHeight = (int)(fontHeightSum + padding);
|
||||
int boxWidth = maxX - minX + 20 - padding;
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(minX - 20, padding + y, boxWidth, boxHeight);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawRect(minX - 20, padding + y, boxWidth, boxHeight);
|
||||
|
||||
// avoid that an entry with identical label and color occurs multiple
|
||||
// times.
|
||||
for (Pair<String, Color> legendEntry : legendEntries) {
|
||||
g.setColor(legendEntry.tail);
|
||||
Rectangle2D stringBounds = fm.getStringBounds(legendEntry.head, g);
|
||||
g.drawString(legendEntry.head, minX + 5, (int)yOffs);
|
||||
g.drawLine(minX - 15, (int)(yOffs - stringBounds.getHeight()/2) + 1, minX, (int)(yOffs - stringBounds.getHeight()/2) + 1);
|
||||
yOffs += (padding + stringBounds.getHeight());
|
||||
}
|
||||
g.setColor(origCol);
|
||||
}
|
||||
}
|
||||
134
src/main/java/eva2/gui/plot/GraphWindow.java
Normal file
134
src/main/java/eva2/gui/plot/GraphWindow.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* It represents one plot window in the client GUI.
|
||||
*/
|
||||
public class GraphWindow {
|
||||
private static final Logger LOGGER = Logger.getLogger(GraphWindow.class.getName());
|
||||
static private int graphCounter = -1;
|
||||
static private PlotContainer plotContainer;
|
||||
private PlotInterface plotter;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static GraphWindow getInstance(String graphWindowName,
|
||||
String strx, String stry) {
|
||||
if (plotContainer == null) {
|
||||
plotContainer = new PlotContainer();
|
||||
}
|
||||
GraphWindow ret = null;
|
||||
try {
|
||||
if (plotContainer.containsName(graphWindowName)) {
|
||||
ret = plotContainer.getPlot(graphWindowName);
|
||||
}
|
||||
if ((ret == null) || !(ret.isValid())) {
|
||||
if (ret != null) {
|
||||
plotContainer.remove(ret); // remove if not valid any more
|
||||
}
|
||||
ret = new GraphWindow(graphWindowName, strx, stry);
|
||||
plotContainer.add(ret);
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
System.out.println("GraphWindow ERROR : " + ee.getMessage());
|
||||
ee.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return (plotter != null) && (plotter.isValid());
|
||||
}
|
||||
|
||||
public PlotInterface getPlotter() {
|
||||
return plotter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private GraphWindow(String plotName, String strx, String stry) {
|
||||
name = plotName;
|
||||
plotter = new Plot(plotName, strx, stry, true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Graph getNewGraph(String infoString) {
|
||||
graphCounter++;
|
||||
LOGGER.log(Level.FINEST, "Graph.getNewGraph No:{0} - {1} created.", new Object[]{graphCounter, infoString});
|
||||
return new Graph(infoString, plotter, graphCounter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PlotContainer extends ArrayList<GraphWindow> {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4194675772084989958L;
|
||||
private GraphWindow actualPlot;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public PlotContainer() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public boolean containsName(String name) {
|
||||
GraphWindow temp;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
temp = get(i);
|
||||
if (name.equals(temp.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void remove(GraphWindow gw) {
|
||||
super.remove(gw);
|
||||
if (actualPlot == gw) {
|
||||
actualPlot = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public GraphWindow getPlot(String name) {
|
||||
if ((actualPlot != null) && actualPlot.isValid()) {
|
||||
if (actualPlot.getName().equals(name)) {
|
||||
return actualPlot;
|
||||
}
|
||||
}
|
||||
GraphWindow temp;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
temp = get(i);
|
||||
if (name.equals(temp.getName())) {
|
||||
actualPlot = temp;
|
||||
return actualPlot;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
27
src/main/java/eva2/gui/plot/InterfaceDPointWithContent.java
Normal file
27
src/main/java/eva2/gui/plot/InterfaceDPointWithContent.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package eva2.gui.plot;
|
||||
|
||||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||||
import eva2.problems.InterfaceOptimizationProblem;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface InterfaceDPointWithContent {
|
||||
void setEAIndividual(AbstractEAIndividual indy);
|
||||
|
||||
AbstractEAIndividual getEAIndividual();
|
||||
|
||||
/**
|
||||
* This method allows you to set the according optimization problem
|
||||
*
|
||||
* @param problem InterfaceOptimizationProblem
|
||||
*/
|
||||
void setProblem(InterfaceOptimizationProblem problem);
|
||||
|
||||
InterfaceOptimizationProblem getProblem();
|
||||
|
||||
/**
|
||||
* This method allows you to draw additional data of the individual
|
||||
*/
|
||||
void showIndividual();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user