/*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.script;
import org.sikuli.vnc.VNCScreen;
import org.sikuli.android.ADBScreen;
import org.sikuli.basics.*;
import org.sikuli.util.JythonHelper;
import org.sikuli.util.ScreenHighlighter;
import org.sikuli.util.SikulixFileChooser;
import org.sikuli.util.Tests;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.security.CodeSource;
/**
* INTERNAL USE ONLY --- NOT part of official API
*/
public class Sikulix {
private static int lvl = 3;
private static void log(int level, String message, Object... args) {
Debug.logx(level, "Sikulix: " + message, args);
}
private static void p(String msg, Object... args) {
System.out.println(String.format(msg, args));
}
private static void terminate(int retVal, String msg, Object... args) {
p(msg, args);
System.exit(retVal);
}
private static boolean runningFromJar;
private static String jarPath;
private static String jarParentPath;
private static final String prefNonSikuli = "nonSikuli_";
private static RunTime rt = null;
public static int testNumber = -1;
private static boolean shouldRunServer = false;
private static Point locPopAt = null;
static {
String jarName = "";
CodeSource codeSrc = Sikulix.class.getProtectionDomain().getCodeSource();
if (codeSrc != null && codeSrc.getLocation() != null) {
jarName = codeSrc.getLocation().getPath();
}
if (jarName.contains("sikulixsetupAPI")) {
JOptionPane.showMessageDialog(null, "Not useable!\nRun setup first!",
"sikulixsetupAPI", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
rt = RunTime.get();
if (Debug.getDebugLevel() == 0) {
Debug.setDebugLevel(1);
}
if (codeSrc != null && codeSrc.getLocation() != null) {
URL jarURL = codeSrc.getLocation();
jarPath = FileManager.slashify(new File(jarURL.getPath()).getAbsolutePath(), false);
jarParentPath = (new File(jarPath)).getParent();
if (jarPath.endsWith(".jar")) {
runningFromJar = true;
} else {
jarPath += "/";
}
}
}
/**
* checking parameter -d on commandline<br>
* 0 - list all available tests<br>
* 1 - run all available tests<br>
* n - run the test with that number if available
*
* @param args currently only -d is evaluated
*/
public static void main(String[] args) throws FindFailed {
if (args.length > 0 && args[0].toLowerCase().startsWith("-s")) {
shouldRunServer = true;
} else {
int dl = RunTime.checkArgs(args, RunTime.Type.API);
if (dl > -1 && dl < 999) {
testNumber = dl;
Debug.on(3);
} else {
testNumber = -1;
}
testNumber = rt.getOptionNumber("testing.test", testNumber);
if (dl == 999) {
int exitCode = Runner.runScripts(args);
cleanUp(exitCode);
System.exit(exitCode);
} else if (testNumber > -1) {
if (!rt.testing) {
rt.show();
rt.testing = true;
}
Tests.runTest(testNumber);
System.exit(1);
}
}
rt = RunTime.get();
if (rt.fSxBaseJar.getName().contains("setup")) {
Sikulix.popError("Not useable!\nRun setup first!");
System.exit(0);
}
if (shouldRunServer) {
if (RunServer.run(null)) {
System.exit(1);
}
}
boolean playing = false;
if (args.length > 0 && "play".equals(args[0])) {
playing = true;
//-------- playground
// -------- playground
}
if (playing) {
System.exit(1);
}
String version = String.format("(%s-%s)", rt.getVersionShort(), rt.sxBuildStamp);
File lastSession = new File(rt.fSikulixStore, "LastAPIJavaScript.js");
String runSomeJS = "";
if (lastSession.exists()) {
runSomeJS = FileManager.readFileToString(lastSession);
}
runSomeJS = inputText("enter some JavaScript (know what you do - may silently die ;-)"
+ "\nexample: run(\"git*\") will run the JavaScript showcase from GitHub"
+ "\nWhat you enter now will be shown the next time.",
"API::JavaScriptRunner " + version, 10, 60, runSomeJS);
if (runSomeJS == null || runSomeJS.isEmpty()) {
popup("Nothing to do!", version);
} else {
while (!runSomeJS.isEmpty()) {
FileManager.writeStringToFile(runSomeJS, lastSession);
Runner.runjs(null, null, runSomeJS, null);
runSomeJS = inputText("Edit the JavaScript and/or press OK to run it (again)\n"
+ "Press Cancel to terminate",
"API::JavaScriptRunner " + version, 10, 60, runSomeJS);
}
}
System.exit(0);
}
/**
* add a jar to the scripting environment<br>
* Jython: added to sys.path<br>
* JRuby: not yet supported<br>
* JavaScript: not yet supported<br>
* if no scripting active (API usage), jar is added to classpath if available
*
* @param fpJar absolute path to a jar (relative: searched according to Extension concept,
* but first on sys.path)
* @return the absolute path to the jar or null, if not available
*/
public static String load(String fpJar) {
return load(fpJar, null);
}
/**
* add a jar to the scripting environment or to classpath<br>
* Jython: added to sys.path<br>
* JRuby: only added to classpath<br>
* JavaScript: only added to classpath<br>
* if no scripting is active (API usage), jar is added to classpath if available<br>
* additionally: fpJar/fpJarImagePath is added to ImagePath (not checked)
*
* @param fpJar absolute path to a jar (relative: searched according to Extension concept,
* but first on sys.path)
* @param fpJarImagePath path relative to jar root inside jar
* @return the absolute path to the jar or null, if not available
*/
public static String load(String fpJar, String fpJarImagePath) {
JythonHelper jython = JythonHelper.get();
String fpJarFound = null;
if (jython != null) {
File aFile = jython.existsSysPathJar(fpJar);
if (aFile != null) {
fpJar = aFile.getAbsolutePath();
}
fpJarFound = jython.load(fpJar);
} else {
File fJarFound = rt.asExtension(fpJar);
if (fJarFound != null) {
fpJarFound = fJarFound.getAbsolutePath();
rt.addToClasspath(fpJarFound);
}
}
if (fpJarFound != null && fpJarImagePath != null) {
ImagePath.addJar(fpJarFound, fpJarImagePath);
}
return fpJarFound;
}
/**
* build a jar on the fly at runtime from a folder.<br>
* special for Jython: if the folder contains a __init__.py on first level,
* the folder will be copied to the jar root (hence preserving module folders)
*
* @param targetJar absolute path to the created jar (parent folder must exist, jar is overwritten)
* @param sourceFolder absolute path to a folder, the contained folder structure
* will be copied to the jar root level
* @return
*/
public static boolean buildJarFromFolder(String targetJar, String sourceFolder) {
log(lvl, "buildJarFromFolder: \nfrom Folder: %s\nto Jar: %s", sourceFolder, targetJar);
File fJar = new File(targetJar);
if (!fJar.getParentFile().exists()) {
log(-1, "buildJarFromFolder: parent folder of Jar not available");
return false;
}
File fSrc = new File(sourceFolder);
if (!fSrc.exists() || !fSrc.isDirectory()) {
log(-1, "buildJarFromFolder: source folder not available");
return false;
}
String prefix = null;
if (new File(fSrc, "__init__.py").exists() || new File(fSrc, "__init__$py.class").exists()) {
prefix = fSrc.getName();
if (prefix.endsWith("_")) {
prefix = prefix.substring(0, prefix.length() - 1);
}
}
return FileManager.buildJar(targetJar, new String[]{null},
new String[]{sourceFolder}, new String[]{prefix}, null);
}
/**
* the foo.py files in the given source folder are compiled to JVM-ByteCode-classfiles foo$py.class
* and stored in the target folder (thus securing your code against changes).<br>
* A folder structure is preserved. All files not ending as .py will be copied also.
* The target folder might then be packed to a jar using buildJarFromFolder.<br>
* Be aware: you will get no feedback about any compile problems,
* so make sure your code compiles error free. Currently there is no support for running such a jar,
* it can only be used with load()/import, but you might provide a simple script that does load()/import
* and then runs something based on available functions in the jar code.
*
* @param fpSource absolute path to a folder/folder-tree containing the stuff to be copied/compiled
* @param fpTarget the folder that will contain the copied/compiled stuff (folder is first deleted)
* @return false if anything goes wrong, true means should have worked
*/
public static boolean compileJythonFolder(String fpSource, String fpTarget) {
JythonHelper jython = JythonHelper.get();
if (jython != null) {
File fTarget = new File(fpTarget);
FileManager.deleteFileOrFolder(fTarget);
fTarget.mkdirs();
if (!fTarget.exists()) {
log(-1, "compileJythonFolder: target folder not available\n%", fTarget);
return false;
}
File fSource = new File(fpSource);
if (!fSource.exists()) {
log(-1, "compileJythonFolder: source folder not available\n", fSource);
return false;
}
if (fTarget.equals(fSource)) {
log(-1, "compileJythonFolder: target folder cannot be the same as the source folder");
return false;
}
FileManager.xcopy(fSource, fTarget);
if (!jython.exec("import compileall")) {
return false;
}
jython = doCompileJythonFolder(jython, fTarget);
FileManager.traverseFolder(fTarget, new CompileJythonFilter(jython));
}
return false;
}
private static class CompileJythonFilter implements FileManager.FileFilter {
JythonHelper jython = null;
public CompileJythonFilter(JythonHelper jython) {
this.jython = jython;
}
@Override
public boolean accept(File entry) {
if (jython != null && entry.isDirectory()) {
jython = doCompileJythonFolder(jython, entry);
}
return false;
}
}
private static JythonHelper doCompileJythonFolder(JythonHelper jython, File fSource) {
String fpSource = FileManager.slashify(fSource.getAbsolutePath(), false);
if (!jython.exec(String.format("compileall.compile_dir(\"%s\","
+ "maxlevels = 0, quiet = 1)", fpSource))) {
return null;
}
for (File aFile : fSource.listFiles()) {
if (aFile.getName().endsWith(".py")) {
aFile.delete();
}
}
return jython;
}
private static boolean addFromProject(String project, String aJar) {
File aFile = null;
if (rt.fSxProject == null) {
return false;
} else {
aFile = new File(rt.fSxProject, project);
}
aFile = new File(aFile, "target/" + aJar);
return rt.addToClasspath(aFile.getAbsolutePath());
}
public static boolean isRunningFromJar() {
return runningFromJar;
}
public static String getJarPath() {
return jarPath;
}
public static String getJarParentPath() {
return jarParentPath;
}
private static boolean runningSikulixapi = false;
/**
* Get the value of runningSikulixUtilapi
*
* @return the value of runningSikulixUtilapi
*/
public static boolean isRunningSikulixapi() {
return runningSikulixapi;
}
/**
* Set the value of runningSikulixUtilapi
*
* @param runningAPI new value of runningSikulixUtilapi
*/
public static void setRunningSikulixapi(boolean runningAPI) {
runningSikulixapi = runningAPI;
}
/**
* call this, to initialize Sikuli up to useability
*
* @return the primary screen object or null if headless
*/
public static Screen init() {
if (!canRun()) {
return null;
}
//TODO collect initializations here
Mouse.init();
return new Screen();
}
/**
* Can SikuliX be run on this machine?
*
* @return true if not running headless false otherwise
*/
public static boolean canRun() {
return !RunTime.get().isHeadless();
}
/**
* INTERNAL USE: convenience function: runs {@link #cleanUp(int)}, prints a message endNormal and terminates with
* returncode
*
* @param n
*/
public static void endNormal(int n) {
log(lvl, "endNormal: %d", n);
cleanUp(n);
System.exit(n);
}
/**
* INTERNAL USE: convenience function: runs {@link #cleanUp(int)}, prints a message endWarning and terminates with
* returncode
*
* @param n returncode
*/
public static void endWarning(int n) {
log(lvl, "endWarning: %d", n);
cleanUp(n);
System.exit(n);
}
/**
* INTERNAL USE: convenience function: runs {@link #cleanUp(int)}, prints a message endError and terminates with
* returncode
*
* @param n
*/
public static void endError(int n) {
log(lvl, "endError: %d", n);
cleanUp(n);
System.exit(n);
}
public static void terminate(int n) {
String msg = "***** Terminating SikuliX Setup after a fatal error"
+ (n == 0 ? "*****\n" : " %d *****\n")
+ "SikuliX is not useable!\n"
+ "Check the error log at " + Debug.logfile;
if (Settings.runningSetup) {
if (Settings.noPupUps) {
log(-1, msg, n);
} else {
popError(String.format(msg, n));
}
} else {
msg = "***** Terminating SikuliX after a fatal error"
+ (n == 0 ? "*****\n" : " %d *****\n")
+ "It makes no sense to continue!\n"
+ "If you do not have any idea about the error cause or solution, run again\n"
+ "with a Debug level of 3. You might paste the output to the Q&A board.";
log(-1, msg, n);
if (Settings.isRunningIDE) {
popError(String.format(msg, n));
}
cleanUp(n);
}
if (!Settings.isRunningIDE) {
System.exit(1);
} else {
throw new IllegalStateException("Aborting script due to an internal error - see log");
}
}
/**
* INTERNAL USE: resets stateful Sikuli X features: <br>
* ScreenHighlighter, Observing, Mouse, Key, Hotkeys <br>
* When in IDE: resets selected options to defaults (TODO)
*
* @param n returncode
*/
public static void cleanUp(int n) {
log(lvl, "cleanUp: %d", n);
VNCScreen.stopAll();
ADBScreen.stop();
ScreenHighlighter.closeAll();
Observing.cleanUp();
HotkeyManager.reset();
try {
new RobotDesktop().keyUp();
} catch (AWTException e) {
}
Mouse.reset();
}
/**
* INTERNAL USE: used in setup: tests basic SikulixUtil features
*
* @return success
*/
public static boolean testSetup() {
return doTestSetup("Java API", false);
}
/**
* INTERNAL USE: used in setup: tests basic SikulixUtil features
*
* @return success
*/
public static boolean testSetup(String src) {
return doTestSetup(src, false);
}
/**
* INTERNAL USE: used in setup: tests basic SikulixUtil features
*
* @return success
*/
public static boolean testSetupSilent() {
Settings.noPupUps = true;
return doTestSetup("Java API", true);
}
private static boolean doTestSetup(String testSetupSource, boolean silent) {
Region r = Region.create(0, 0, 100, 100);
Image img = new Image(r.getScreen().capture(r).getImage());
Pattern p = new Pattern(img);
Finder f = new Finder(img);
boolean success = (null != f.find(p));
log(lvl, "testSetup: Finder setup with image %s", (!success ? "did not work" : "worked"));
if (success &= f.hasNext()) {
success = (null != f.find(img.asFile()));
log(lvl, "testSetup: Finder setup with image file %s", (!success ? "did not work" : "worked"));
success &= f.hasNext();
String screenFind = "Screen.find(imagefile)";
try {
((Screen) r.getScreen()).find(img.asFile());
log(lvl, "testSetup: %s worked", screenFind);
screenFind = "repeated Screen.find(imagefile)";
((Screen) r.getScreen()).find(img.asFile());
log(lvl, "testSetup: %s worked", screenFind);
} catch (Exception ex) {
log(lvl, "testSetup: %s did not work", screenFind);
success = false;
}
}
if (success) {
if (!silent) {
popup("Hallo from Sikulix.testSetup: " + testSetupSource + "\n"
+ "SikuliX seems to be working!\n\nHave fun!");
log(lvl, "testSetup: Finder.find: worked");
} else {
System.out.println("[info] RunSetup: Sikulix.testSetup: Java Sikuli seems to be working!");
}
return true;
}
log(lvl, "testSetup: last Screen/Finder.find: did not work");
return false;
}
@Deprecated
public static boolean addToClasspath(String jar) {
return RunTime.get().addToClasspath(jar);
}
@Deprecated
public static boolean isOnClasspath(String artefact) {
return null != RunTime.get().isOnClasspath(artefact);
}
public static String run(String cmdline) {
return run(new String[]{cmdline});
}
public static String run(String[] cmd) {
return rt.runcmd(cmd);
}
public static void popError(String message) {
popError(message, "Sikuli");
}
public static void popError(String message, String title) {
JFrame anchor = popLocation();
JOptionPane.showMessageDialog(anchor, message, title, JOptionPane.ERROR_MESSAGE);
if (anchor != null) {
anchor.dispose();
}
}
/**
* request user's input as one line of text <br>
* with hidden = true: <br>
* the dialog works as password input (input text hidden as bullets) <br>
* take care to destroy the return value as soon as possible (internally the password is deleted on return)
*
* @param msg
* @param preset
* @param title
* @param hidden
* @return the text entered
*/
public static String input(String msg, String preset, String title, boolean hidden) {
JFrame anchor = popLocation();
String ret = "";
if (!hidden) {
if ("".equals(title)) {
title = "Sikuli input request";
}
ret = (String) JOptionPane.showInputDialog(anchor, msg, title,
JOptionPane.PLAIN_MESSAGE, null, null, preset);
} else {
preset = "";
JTextArea tm = new JTextArea(msg);
tm.setColumns(20);
tm.setLineWrap(true);
tm.setWrapStyleWord(true);
tm.setEditable(false);
tm.setBackground(new JLabel().getBackground());
JPasswordField pw = new JPasswordField(preset);
JPanel pnl = new JPanel();
pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));
pnl.add(pw);
pnl.add(Box.createVerticalStrut(10));
pnl.add(tm);
int retval = JOptionPane.showConfirmDialog(anchor, pnl, title, JOptionPane.OK_CANCEL_OPTION);
if (0 == retval) {
char[] pwc = pw.getPassword();
for (int i = 0; i < pwc.length; i++) {
ret = ret + pwc[i];
pwc[i] = 0;
}
}
}
if (anchor != null) {
anchor.dispose();
}
return ret;
}
public static String input(String msg, String title, boolean hidden) {
return input(msg, "", title, hidden);
}
public static String input(String msg, boolean hidden) {
return input(msg, "", "", hidden);
}
public static String input(String msg, String preset, String title) {
return input(msg, preset, title, false);
}
public static String input(String msg, String preset) {
return input(msg, preset, "", false);
}
public static String input(String msg) {
return input(msg, "", "", false);
}
public static boolean popAsk(String msg) {
return popAsk(msg, null);
}
public static boolean popAsk(String msg, String title) {
if (title == null) {
title = "... something to decide!";
}
JFrame anchor = popLocation();
int ret = JOptionPane.showConfirmDialog(anchor, msg, title, JOptionPane.YES_NO_OPTION);
if (anchor != null) {
anchor.dispose();
}
if (ret == JOptionPane.CLOSED_OPTION || ret == JOptionPane.NO_OPTION) {
return false;
}
return true;
}
public static void popup(String message) {
popup(message, "Sikuli");
}
public static void popup(String message, String title) {
JFrame anchor = popLocation();
JOptionPane.showMessageDialog(anchor, message, title, JOptionPane.PLAIN_MESSAGE);
if (anchor != null) {
anchor.dispose();
}
}
public static Location popat(Location at) {
locPopAt = new Point(at.x, at.y);
return new Location(locPopAt);
}
public static Location popat(Region at) {
locPopAt = new Point(at.getCenter().x, at.getCenter().y);
return new Location(locPopAt);
}
public static Location popat(int atx, int aty) {
locPopAt = new Point(atx, aty);
return new Location(locPopAt);
}
public static Location popat() {
locPopAt = getLocPopAt();
return new Location(locPopAt);
}
private static Point getLocPopAt() {
Rectangle screen0 = rt.getMonitor(0);
if (null == screen0) {
return null;
}
return new Point((int) screen0.getCenterX(), (int) screen0.getCenterY());
}
private static JFrame popLocation() {
if (null == locPopAt) {
locPopAt = getLocPopAt();
if (null == locPopAt) {
return null;
}
}
return popLocation(locPopAt.x, locPopAt.y);
}
private static JFrame popLocation(int x, int y) {
JFrame anchor = new JFrame();
anchor.setAlwaysOnTop(true);
anchor.setUndecorated(true);
anchor.setSize(1, 1);
anchor.setLocation(x, y);
anchor.setVisible(true);
return anchor;
}
public static String popSelect(String msg, String[] options, String preset) {
return popSelect(msg, null, options, preset);
}
public static String popSelect(String msg, String[] options) {
if (options.length == 0) {
return "";
}
return popSelect(msg, null, options, options[0]);
}
public static String popSelect(String msg, String title, String[] options) {
if (options.length == 0) {
return "";
}
return popSelect(msg, title, options, options[0]);
}
public static String popSelect(String msg, String title, String[] options, String preset) {
if (title == null || "".equals(title)) {
title = "... something to select!";
}
if (options.length == 0) {
return "";
}
if (preset == null) {
preset = options[0];
}
JFrame anchor = popLocation();
String ret = (String) JOptionPane.showInputDialog(anchor, msg, title,
JOptionPane.PLAIN_MESSAGE, null, options, preset);
if (anchor != null) {
anchor.dispose();
}
return ret;
}
public static String popFile(String title) {
popat(new Screen(0).getCenter());
JFrame anchor = popLocation();
SikulixFileChooser fc = new SikulixFileChooser(anchor);
File ret = fc.show(title);
fc = null;
if (anchor != null) {
anchor.dispose();
}
if (ret == null) {
return "";
}
return ret.getAbsolutePath();
}
public static String inputText(String msg) {
return inputText(msg, "", 0, 0, "");
}
public static String inputText(String msg, int lines, int width) {
return inputText(msg, "", lines, width, "");
}
public static String inputText(String msg, int lines, int width, String text) {
return inputText(msg, "", lines, width, text);
}
public static String inputText(String msg, String text) {
return inputText(msg, "", 0, 0, text);
}
/**
* Shows a dialog request to enter text in a multiline text field <br>
* it has line wrapping on word bounds and a vertical scrollbar if needed
*
* @param msg the message to display below the textfield
* @param title the title for the dialog (default: SikuliX input request)
* @param lines the maximum number of lines visible in the text field (default 9)
* @param width the maximum number of characters visible in one line (default 20 letters m)
* @param text a preset text to show
* @return The user's input including the line breaks.
*/
public static String inputText(String msg, String title, int lines, int width, String text) {
width = Math.max(20, width);
lines = Math.max(9, lines);
if ("".equals(title)) {
title = "SikuliX input request";
}
JTextArea ta = new JTextArea("");
String fontname = "Dialog";
int pluswidth = 1;
if (Settings.InputFontMono) {
fontname = "Monospaced";
pluswidth = 3;
}
ta.setFont(new Font(fontname, Font.PLAIN, Math.max(14, Settings.InputFontSize)));
int w = (width + pluswidth) * ta.getFontMetrics(ta.getFont()).charWidth('m');
int h = (lines + 1) * ta.getFontMetrics(ta.getFont()).getHeight();
ta.setText(text);
ta.setLineWrap(true);
ta.setWrapStyleWord(true);
JScrollPane sp = new JScrollPane();
sp.setViewportView(ta);
sp.setPreferredSize(new Dimension(w, h));
JTextArea tm = new JTextArea("");
tm.setFont(new Font(fontname, Font.PLAIN, Math.max(14, Settings.InputFontSize)));
tm.setColumns(width);
tm.setText(msg);
tm.setLineWrap(true);
tm.setWrapStyleWord(true);
tm.setEditable(false);
tm.setBackground(new JLabel().getBackground());
JPanel pnl = new JPanel();
pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));
pnl.add(sp);
pnl.add(Box.createVerticalStrut(10));
pnl.add(tm);
pnl.add(Box.createVerticalStrut(10));
JFrame anchor = popLocation();
int ret = JOptionPane.showConfirmDialog(anchor, pnl, title, JOptionPane.OK_CANCEL_OPTION);
if (anchor != null) {
anchor.dispose();
}
if (0 == ret) {
return ta.getText();
} else {
return null;
}
}
public static boolean importPrefs(String path) {
return true;
}
public static String arrayToString(String[] args) {
String ret = "";
for (String s : args) {
if (s.contains(" ")) {
s = "\"" + s + "\"";
}
ret += s + " ";
}
return ret;
}
public static boolean exportPrefs(String path) {
return true;
}
/**
* store a key-value-pair in Javas persistent preferences storage that is used by SikuliX to save settings and
* information between IDE sessions<br>
* this allows, to easily make some valuable information persistent
*
* @param key name of the item
* @param value item content
*/
public static void prefStore(String key, String value) {
PreferencesUser.getInstance().put(prefNonSikuli + key, value);
}
/**
* retrieve the value of a previously stored a key-value-pair from Javas persistent preferences storage that is used
* by SikuliX to save settings and information between IDE sessions<br>
*
* @param key name of the item
* @return the item content or empty string if not stored yet
*/
public static String prefLoad(String key) {
return PreferencesUser.getInstance().get(prefNonSikuli + key, "");
}
/**
* retrieve the value of a previously stored a key-value-pair from Javas persistent preferences storage that is used
* by SikuliX to save settings and information between IDE sessions<br>
*
* @param key name of the item
* @param value the item content or the given value if not stored yet (default)
* @return the item content or the given default
*/
public static String prefLoad(String key, String value) {
return PreferencesUser.getInstance().get(prefNonSikuli + key, value);
}
/**
* permanently remove the previously stored key-value-pair having the given key from Javas persistent preferences
* storage that is used by SikuliX to save settings and information between IDE sessions<br>
*
* @param key name of the item to permanently remove
* @return the item content that would be returned by prefLoad(key)
*/
public static String prefRemove(String key) {
String val = prefLoad(key);
PreferencesUser.getInstance().remove(prefNonSikuli + key);
return val;
}
/**
* permanently remove all previously stored key-value-pairs (by prefsStore()) from Javas persistent preferences
* storage that is used by SikuliX to save settings and information between IDE sessions<br>
*/
public static void prefRemove() {
PreferencesUser.getInstance().removeAll(prefNonSikuli);
}
/**
* convenience for a password protected VNCScreen connection
* (use theVNCScreen.stop() to stop the connection)
* active screens are auto-stopped at cleanup
*
* @param theIP the server IP
* @param thePort the port number
* @param password a needed password for the server in plain text
* @param cTimeout seconds to wait for a valid connection
* @param timeout value in milli-seconds during normal operation
* @return a VNCScreen object
*/
public static VNCScreen vncStart(String theIP, int thePort, String password, int cTimeout, int timeout) {
try {
return VNCScreen.start(theIP, thePort, password, cTimeout, timeout);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* convenience for a VNCScreen connection (use theVNCScreen.stop() to stop the connection)
* active screens are auto-stopped at cleanup
*
* @param theIP the server IP
* @param thePort the port number
* @param cTimeout seconds to wait for a valid connection
* @param timeout value in milli-seconds during normal operation
* @return a VNCScreen object
*/
public static VNCScreen vncStart(String theIP, int thePort, int cTimeout, int timeout) {
try {
return VNCScreen.start(theIP, thePort, cTimeout, timeout);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}