weka.gui.SimpleCLIPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-dev Show documentation
Show all versions of weka-dev Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This version represents the developer version, the
"bleeding edge" of development, you could say. New functionality gets added
to this version.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* SimpleCLIPanel.java
* Copyright (C) 2009-2018 University of Waikato, Hamilton, New Zealand
*/
package weka.gui;
import weka.core.ClassDiscovery;
import weka.core.Defaults;
import weka.core.Instances;
import weka.core.Trie;
import weka.core.Utils;
import weka.core.WekaPackageManager;
import weka.gui.knowledgeflow.StepVisual;
import weka.gui.scripting.ScriptingPanel;
import weka.gui.simplecli.AbstractCommand;
import weka.gui.simplecli.Help;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
/**
* Creates a very simple command line for invoking the main method of classes.
* System.out and System.err are redirected to an output area. Features a simple
* command history -- use up and down arrows to move through previous commmands.
* This gui uses only AWT (i.e. no Swing).
*
* @author Len Trigg ([email protected])
* @author FracPete (fracpete at waikato dot ac dot nz)
*/
@PerspectiveInfo(ID = "simplecli", title = "Simple CLI",
toolTipText = "Simple CLI for Weka",
iconPath = "weka/gui/weka_icon_new_small.png")
public class SimpleCLIPanel extends ScriptingPanel implements ActionListener,
Perspective {
/** for serialization. */
private static final long serialVersionUID = 1089039734615114942L;
/** The filename of the properties file. */
protected static String FILENAME = "SimpleCLI.props";
/** The default location of the properties file. */
protected static String PROPERTY_FILE = "weka/gui/" + FILENAME;
/** Contains the SimpleCLI properties. */
protected static Properties PROPERTIES;
/** Main application (if any) owning this perspective */
protected GUIApplication m_mainApp;
/** The Icon for this perspective */
protected Icon m_perspectiveIcon;
static {
// Allow a properties file in the current directory to override
try {
PROPERTIES = Utils.readProperties(PROPERTY_FILE);
java.util.Enumeration> keys = PROPERTIES.propertyNames();
if (!keys.hasMoreElements()) {
throw new Exception("Failed to read a property file for the SimpleCLI");
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Could not read a configuration file for the SimpleCLI.\n"
+ "An example file is included with the Weka distribution.\n"
+ "This file should be named \"" + PROPERTY_FILE + "\" and\n"
+ "should be placed either in your user home (which is set\n"
+ "to \"" + System.getProperties().getProperty("user.home") + "\")\n"
+ "or the directory that java was started from\n", "SimpleCLI",
JOptionPane.ERROR_MESSAGE);
}
}
/** The output area canvas added to the frame. */
protected JTextPane m_OutputArea;
/** The command input area. */
protected JTextField m_Input;
/** The history of commands entered interactively. */
protected Vector m_CommandHistory;
/** The current position in the command history. */
protected int m_HistoryPos;
/** The thread currently running a class main method. */
protected Thread m_RunThread;
/** The commandline completion. */
protected CommandlineCompletion m_Completion;
/** for storing variables. */
protected Map m_Variables;
@Override
public void instantiationComplete() {
}
@Override
public boolean okToBeActive() {
return true;
}
@Override
public void setActive(boolean active) {
}
@Override
public void setLoaded(boolean loaded) {
}
@Override
public void setMainApplication(GUIApplication main) {
m_mainApp = main;
}
@Override
public GUIApplication getMainApplication() {
return m_mainApp;
}
@Override
public String getPerspectiveID() {
return "simplecli";
}
@Override
public String getPerspectiveTitle() {
return "Simple CLI";
}
@Override
public Icon getPerspectiveIcon() {
if (m_perspectiveIcon != null) {
return m_perspectiveIcon;
}
PerspectiveInfo perspectiveA =
this.getClass().getAnnotation(PerspectiveInfo.class);
if (perspectiveA != null && perspectiveA.iconPath() != null
&& perspectiveA.iconPath().length() > 0) {
m_perspectiveIcon = StepVisual.loadIcon(perspectiveA.iconPath());
}
return m_perspectiveIcon;
}
@Override
public String getPerspectiveTipText() {
return "Simple CLI interface for Weka";
}
@Override
public List getMenus() {
return null;
}
@Override
public Defaults getDefaultSettings() {
return null;
}
@Override
public void settingsChanged() {
}
@Override
public boolean acceptsInstances() {
return false;
}
@Override
public void setInstances(Instances instances) {
}
@Override
public boolean requiresLog() {
return false;
}
@Override
public void setLog(Logger log) {
}
/**
* A class that handles running the main method of the class in a separate
* thread.
*
* @author Len Trigg ([email protected])
* @version $Revision: 14982 $
*/
public static class ClassRunner extends Thread {
/** the owner. */
protected SimpleCLIPanel m_Owner;
/** Stores the main method to call. */
protected Method m_MainMethod;
/** Stores the command line arguments to pass to the main method. */
String[] m_CommandArgs;
/** True if the class to be executed is weka.Run */
protected boolean m_classIsRun;
/**
* Sets up the class runner thread.
*
* @param theClass the Class to call the main method of
* @param commandArgs an array of Strings to use as command line args
* @throws Exception if an error occurs
*/
public ClassRunner(SimpleCLIPanel owner, Class> theClass, String[] commandArgs)
throws Exception {
m_Owner = owner;
m_classIsRun = (theClass.getClass().getName().equals("weka.Run"));
setDaemon(true);
Class>[] argTemplate = { String[].class };
m_CommandArgs = commandArgs;
if (m_classIsRun) {
if (!commandArgs[0].equalsIgnoreCase("-h")
&& !commandArgs[0].equalsIgnoreCase("-help")) {
m_CommandArgs = new String[commandArgs.length + 1];
System.arraycopy(commandArgs, 0, m_CommandArgs, 1, commandArgs.length);
m_CommandArgs[0] = "-do-not-prompt-if-multiple-matches";
}
}
m_MainMethod = theClass.getMethod("main", argTemplate);
if (((m_MainMethod.getModifiers() & Modifier.STATIC) == 0)
|| (m_MainMethod.getModifiers() & Modifier.PUBLIC) == 0) {
throw new NoSuchMethodException("main(String[]) method of "
+ theClass.getName() + " is not public and static.");
}
}
/**
* Starts running the main method.
*/
@Override
public void run() {
PrintStream outOld = null;
PrintStream outNew = null;
String outFilename = null;
// is the output redirected?
if (m_CommandArgs.length > 2) {
String action = m_CommandArgs[m_CommandArgs.length - 2];
if (action.equals(">")) {
outOld = System.out;
try {
outFilename = m_CommandArgs[m_CommandArgs.length - 1];
// since file may not yet exist, command-line completion doesn't
// work, hence replace "~" manually with home directory
if (outFilename.startsWith("~")) {
outFilename =
outFilename.replaceFirst("~", System.getProperty("user.home"));
}
outNew = new PrintStream(new File(outFilename));
System.setOut(outNew);
m_CommandArgs[m_CommandArgs.length - 2] = "";
m_CommandArgs[m_CommandArgs.length - 1] = "";
// some main methods check the length of the "args" array
// -> removed the two empty elements at the end
String[] newArgs = new String[m_CommandArgs.length - 2];
System.arraycopy(m_CommandArgs, 0, newArgs, 0,
m_CommandArgs.length - 2);
m_CommandArgs = newArgs;
} catch (Exception e) {
System.setOut(outOld);
outOld = null;
}
}
}
try {
Object[] args = { m_CommandArgs };
m_MainMethod.invoke(null, args);
if (isInterrupted()) {
System.err.println("[...Interrupted]");
}
} catch (Exception ex) {
if (ex.getMessage() == null) {
System.err.println("[...Killed]");
} else {
System.err.println("[Run exception] " + ex.getMessage());
}
} finally {
m_Owner.stopThread();
}
// restore old System.out stream
if (outOld != null) {
outNew.flush();
outNew.close();
System.setOut(outOld);
System.out.println("Finished redirecting output to '" + outFilename
+ "'.");
}
}
}
/**
* A class for commandline completion of classnames.
*
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 14982 $
*/
public static class CommandlineCompletion {
/** all the available packages. */
protected Vector m_Packages;
/** a trie for storing the packages. */
protected Trie m_Trie;
/** debug mode on/off. */
protected boolean m_Debug = false;
/**
* default constructor.
*/
public CommandlineCompletion() {
super();
// build incremental list of packages
if (m_Packages == null) {
// get all packages
Vector list = ClassDiscovery.findPackages();
// create incremental list
HashSet set = new HashSet();
for (int i = 0; i < list.size(); i++) {
String[] parts = list.get(i).split("\\.");
for (int n = 1; n < parts.length; n++) {
String pkg = "";
for (int m = 0; m <= n; m++) {
if (m > 0) {
pkg += ".";
}
pkg += parts[m];
}
set.add(pkg);
}
}
// init packages
m_Packages = new Vector();
m_Packages.addAll(set);
Collections.sort(m_Packages);
m_Trie = new Trie();
m_Trie.addAll(m_Packages);
}
}
/**
* returns whether debug mode is on.
*
* @return true if debug is on
*/
public boolean getDebug() {
return m_Debug;
}
/**
* sets debug mode on/off.
*
* @param value if true then debug mode is on
*/
public void setDebug(boolean value) {
m_Debug = value;
}
/**
* tests whether the given partial string is the name of a class with
* classpath - it basically tests, whether the string consists only of
* alphanumeric literals, underscores and dots.
*
* @param partial the string to test
* @return true if it looks like a classname
*/
public boolean isClassname(String partial) {
return (partial.replaceAll("[a-zA-Z0-9\\-\\.]*", "").length() == 0);
}
/**
* returns the packages part of the partial classname.
*
* @param partial the partial classname
* @return the package part of the partial classname
*/
public String getPackage(String partial) {
String result;
int i;
boolean wasDot;
char c;
result = "";
wasDot = false;
for (i = 0; i < partial.length(); i++) {
c = partial.charAt(i);
// start of classname?
if (wasDot && ((c >= 'A') && (c <= 'Z'))) {
break;
}
// package/class separator
else if (c == '.') {
wasDot = true;
result += "" + c;
}
// regular char
else {
wasDot = false;
result += "" + c;
}
}
// remove trailing "."
if (result.endsWith(".")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
/**
* returns the classname part of the partial classname.
*
* @param partial the partial classname
* @return the class part of the classname
*/
public String getClassname(String partial) {
String result;
String pkg;
pkg = getPackage(partial);
if (pkg.length() + 1 < partial.length()) {
result = partial.substring(pkg.length() + 1);
} else {
result = "";
}
return result;
}
/**
* returns all the file/dir matches with the partial search string.
*
* @param partial the partial search string
* @return all the matches
*/
public Vector getFileMatches(String partial) {
Vector result;
File file;
File dir;
File[] files;
int i;
String prefix;
boolean caseSensitive;
String name;
boolean match;
result = new Vector();
// is the OS case-sensitive?
caseSensitive = (File.separatorChar != '\\');
if (m_Debug) {
System.out.println("case-sensitive=" + caseSensitive);
}
// is "~" used for home directory? -> replace with actual home directory
if (partial.startsWith("~")) {
partial = System.getProperty("user.home") + partial.substring(1);
}
// determine dir and possible prefix
file = new File(partial);
dir = null;
prefix = null;
if (file.exists()) {
// determine dir to read
if (file.isDirectory()) {
dir = file;
prefix = null; // retrieve all
} else {
dir = file.getParentFile();
prefix = file.getName();
}
} else {
dir = file.getParentFile();
prefix = file.getName();
}
if (m_Debug) {
System.out.println("search in dir=" + dir + ", prefix=" + prefix);
}
// list all files in dir
if (dir != null) {
files = dir.listFiles();
if (files != null) {
for (i = 0; i < files.length; i++) {
name = files[i].getName();
// does the name match?
if ((prefix != null) && caseSensitive) {
match = name.startsWith(prefix);
} else if ((prefix != null) && !caseSensitive) {
match = name.toLowerCase().startsWith(prefix.toLowerCase());
} else {
match = true;
}
if (match) {
if (prefix != null) {
result.add(partial.substring(0,
partial.length() - prefix.length())
+ name);
} else {
if (partial.endsWith("\\") || partial.endsWith("/")) {
result.add(partial + name);
} else {
result.add(partial + File.separator + name);
}
}
}
}
} else {
System.err.println("Invalid path: " + partial);
}
}
// sort the result
if (result.size() > 1) {
Collections.sort(result);
}
// print results
if (m_Debug) {
System.out.println("file matches:");
for (i = 0; i < result.size(); i++) {
System.out.println(result.get(i));
}
}
return result;
}
/**
* returns all the class/package matches with the partial search string.
*
* @param partial the partial search string
* @return all the matches
*/
public Vector getClassMatches(String partial) {
String pkg;
String cls;
Vector result;
Vector list;
int i;
int index;
Trie tmpTrie;
HashSet set;
String tmpStr;
pkg = getPackage(partial);
cls = getClassname(partial);
if (getDebug()) {
System.out.println("\nsearch for: '" + partial + "' => package=" + pkg
+ ", class=" + cls);
}
result = new Vector();
// find all packages that start with that string
if (cls.length() == 0) {
list = m_Trie.getWithPrefix(pkg);
set = new HashSet();
for (i = 0; i < list.size(); i++) {
tmpStr = list.get(i);
if (tmpStr.length() < partial.length()) {
continue;
}
if (tmpStr.equals(partial)) {
continue;
}
index = tmpStr.indexOf('.', partial.length() + 1);
if (index > -1) {
set.add(tmpStr.substring(0, index));
} else {
set.add(tmpStr);
}
}
result.addAll(set);
if (result.size() > 1) {
Collections.sort(result);
}
}
// find all classes that start with that string
list = ClassDiscovery.find(Object.class, pkg);
tmpTrie = new Trie();
tmpTrie.addAll(list);
list = tmpTrie.getWithPrefix(partial);
result.addAll(list);
// sort the result
if (result.size() > 1) {
Collections.sort(result);
}
// print results
if (m_Debug) {
System.out.println("class/package matches:");
for (i = 0; i < result.size(); i++) {
System.out.println(result.get(i));
}
}
return result;
}
/**
* returns all the matches with the partial search string, files or classes.
*
* @param partial the partial search string
* @return all the matches
*/
public Vector getMatches(String partial) {
if (isClassname(partial)) {
return getClassMatches(partial);
} else {
return getFileMatches(partial);
}
}
/**
* returns the common prefix for all the items in the list.
*
* @param list the list to return the common prefix for
* @return the common prefix of all the items
*/
public String getCommonPrefix(Vector list) {
String result;
Trie trie;
trie = new Trie();
trie.addAll(list);
result = trie.getCommonPrefix();
if (m_Debug) {
System.out.println(list + "\n --> common prefix: '" + result + "'");
}
return result;
}
}
/**
* For initializing member variables.
*/
@Override
protected void initialize() {
super.initialize();
m_CommandHistory = new Vector();
m_HistoryPos = 0;
m_Completion = new CommandlineCompletion();
m_Variables = new HashMap<>();
}
/**
* Sets up the GUI after initializing the members.
*/
@Override
protected void initGUI() {
super.initGUI();
setLayout(new BorderLayout());
m_OutputArea = new JTextPane();
m_OutputArea.setEditable(false);
m_OutputArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
add(new JScrollPane(m_OutputArea), "Center");
m_Input = new JTextField();
m_Input.setFont(new Font("Monospaced", Font.PLAIN, 12));
m_Input.addActionListener(this);
m_Input.setFocusTraversalKeysEnabled(false);
m_Input.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
doHistory(e);
doCommandlineCompletion(e);
}
});
add(m_Input, "South");
}
/**
* Finishes up after initializing members and setting up the GUI.
*/
@Override
protected void initFinish() {
super.initFinish();
System.out.println("\nWelcome to the WEKA SimpleCLI\n\n"
+ "Enter commands in the textfield at the bottom of \n"
+ "the window. Use the up and down arrows to move \n"
+ "through previous commands.\n"
+ "Command completion for classnames and files is \n"
+ "initiated with . In order to distinguish \n"
+ "between files and classnames, file names must \n"
+ "be either absolute or start with '." + File.separator + "' or '~/'\n"
+ "(the latter is a shortcut for the home directory).\n"
+ " is used for deleting the text\n"
+ "in the commandline in chunks.\n"
+ "\n"
+ "Type 'help' followed by to see an overview \n"
+ "of all commands.");
loadHistory();
SwingUtilities.invokeLater(() -> m_Input.requestFocus());
}
/**
* Returns an icon to be used in a frame.
*
* @return the icon
*/
@Override
public ImageIcon getIcon() {
return ComponentHelper.getImageIcon("weka_icon_new_48.png");
}
/**
* Returns the current title for the frame/dialog.
*
* @return the title
*/
@Override
public String getTitle() {
return "SimpleCLI";
}
/**
* Returns the text area that is used for displaying output on stdout and
* stderr.
*
* @return the JTextArea
*/
@Override
public JTextPane getOutput() {
return m_OutputArea;
}
/**
* Not supported.
*
* @return always null
*/
@Override
public JMenuBar getMenuBar() {
return null;
}
/**
* Checks whether a thread is currently running.
*
* @return true if thread active
*/
public boolean isBusy() {
return (m_RunThread != null);
}
/**
* Starts the thread.
*
* @param runner the thread to start
*/
public void startThread(ClassRunner runner) {
m_RunThread = runner;
m_RunThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
m_RunThread.start();
}
/**
* Stops the currently running thread, if any.
*/
@SuppressWarnings("deprecation")
public void stopThread() {
if (m_RunThread != null) {
if (m_RunThread.isAlive()) {
try {
m_RunThread.stop();
}
catch (Throwable t) {
// ignored
}
}
m_RunThread = null;
}
}
/**
* Returns the variables.
*
* @return the variables
*/
public Map getVariables() {
return m_Variables;
}
/**
* The output area.
*
* @return the output area
*/
public JTextPane getOutputArea() {
return m_OutputArea;
}
/**
* Returns the command history.
*
* @return the history
*/
public List getCommandHistory() {
return m_CommandHistory;
}
/**
* Executes a simple cli command.
*
* @param command the command string
* @throws Exception if an error occurs
*/
public void runCommand(String command) throws Exception {
System.out.println("> " + command + '\n');
System.out.flush();
String[] commandArgs;
if (!System.getProperty("os.name").toLowerCase().contains("win")) {
commandArgs = Utils.splitOptions(command);
} else { // If we are on Windows, we must not replace \t, \n, etc., at this stage because \ is path separator
commandArgs = Utils.splitOptions(command, new String[] { "\\\\", "\\\""}, new char[] { '\\', '"' });
}
// no command
if (commandArgs.length == 0) {
return;
}
// find command
AbstractCommand cmd = AbstractCommand.getCommand(commandArgs[0]);
// unknown command
if (cmd == null) {
System.err.println("Unknown command: " + commandArgs[0]);
Help help = new Help();
help.setOwner(this);
help.execute(new String[0]);
return;
}
// execute command
String[] params = new String[commandArgs.length -1];
System.arraycopy(commandArgs, 1, params, 0, params.length);
cmd.setOwner(this);
try {
cmd.execute(params);
}
catch (Exception e) {
System.err.println("Error executing: " + command);
e.printStackTrace();
}
}
/**
* Changes the currently displayed command line when certain keys are pressed.
* The up arrow moves back through history entries and the down arrow moves
* forward through history entries.
*
* @param e a value of type 'KeyEvent'
*/
public void doHistory(KeyEvent e) {
if (e.getSource() == m_Input) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
if (m_HistoryPos > 0) {
m_HistoryPos--;
String command = m_CommandHistory.elementAt(m_HistoryPos);
m_Input.setText(command);
}
break;
case KeyEvent.VK_DOWN:
if (m_HistoryPos < m_CommandHistory.size()) {
m_HistoryPos++;
String command = "";
if (m_HistoryPos < m_CommandHistory.size()) {
command = m_CommandHistory.elementAt(m_HistoryPos);
}
m_Input.setText(command);
}
break;
default:
break;
}
}
}
/**
* performs commandline completion on packages and classnames.
*
* @param e a value of type 'KeyEvent'
*/
public void doCommandlineCompletion(KeyEvent e) {
if (e.getSource() == m_Input) {
switch (e.getKeyCode()) {
// completion
case KeyEvent.VK_TAB:
if (e.getModifiers() == 0) {
// it might take a while before we determined all of the possible
// matches (Java doesn't have an application wide cursor handling??)
m_Input.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
m_OutputArea
.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
String txt = m_Input.getText();
// java call?
if (txt.trim().startsWith("java ")) {
int pos = m_Input.getCaretPosition();
int nonNameCharPos = -1;
// find first character not part of a name, back from current
// position
// i.e., " or blank
for (int i = pos - 1; i >= 0; i--) {
if ((txt.charAt(i) == '"') || (txt.charAt(i) == ' ')) {
nonNameCharPos = i;
break;
}
}
if (nonNameCharPos > -1) {
String search = txt.substring(nonNameCharPos + 1, pos);
// find matches and common prefix
Vector list = m_Completion.getMatches(search);
String common = m_Completion.getCommonPrefix(list);
// just extending by separator is not a real extension
if ((search.toLowerCase() + File.separator).equals(common
.toLowerCase())) {
common = search;
}
// can we complete the string?
if (common.length() > search.length()) {
try {
m_Input.getDocument().remove(nonNameCharPos + 1,
search.length());
m_Input.getDocument().insertString(nonNameCharPos + 1,
common, null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
// ambigiuous? -> print matches
else if (list.size() > 1) {
System.out.println("\nPossible matches:");
for (int i = 0; i < list.size(); i++) {
System.out.println(" " + list.get(i));
}
} else {
// nothing found, don't do anything
}
}
}
} finally {
// set cursor back to default
m_Input.setCursor(null);
m_OutputArea.setCursor(null);
}
}
break;
// delete last part up to next blank or dot
case KeyEvent.VK_BACK_SPACE:
if (e.getModifiers() == KeyEvent.ALT_MASK) {
String txt = m_Input.getText();
int pos = m_Input.getCaretPosition();
// skip whitespaces
int start = pos;
start--;
while (start >= 0) {
if ((txt.charAt(start) == '.') || (txt.charAt(start) == ' ')
|| (txt.charAt(start) == '\\') || (txt.charAt(start) == '/')) {
start--;
} else {
break;
}
}
// find first blank or dot back from position
int newPos = -1;
for (int i = start; i >= 0; i--) {
if ((txt.charAt(i) == '.') || (txt.charAt(i) == ' ')
|| (txt.charAt(i) == '\\') || (txt.charAt(i) == '/')) {
newPos = i;
break;
}
}
// remove string
try {
m_Input.getDocument().remove(newPos + 1, pos - newPos - 1);
} catch (Exception ex) {
ex.printStackTrace();
}
}
break;
}
}
}
/**
* Only gets called when return is pressed in the input area, which starts the
* command running.
*
* @param e a value of type 'ActionEvent'
*/
@Override
public void actionPerformed(ActionEvent e) {
try {
if (e.getSource() == m_Input) {
String command = m_Input.getText();
int last = m_CommandHistory.size() - 1;
if ((last < 0) || !command.equals(m_CommandHistory.elementAt(last))) {
m_CommandHistory.addElement(command);
saveHistory();
}
m_HistoryPos = m_CommandHistory.size();
runCommand(command);
m_Input.setText("");
}
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
/**
* loads the command history from the user's properties file.
*/
protected void loadHistory() {
int size;
int i;
String cmd;
size = Integer.parseInt(PROPERTIES.getProperty("HistorySize", "50"));
m_CommandHistory.clear();
for (i = 0; i < size; i++) {
cmd = PROPERTIES.getProperty("Command" + i, "");
if (cmd.length() != 0) {
m_CommandHistory.add(cmd);
} else {
break;
}
}
m_HistoryPos = m_CommandHistory.size();
}
/**
* saves the current command history in the user's home directory.
*/
protected void saveHistory() {
int size;
int from;
int i;
String filename;
BufferedOutputStream stream;
size = Integer.parseInt(PROPERTIES.getProperty("HistorySize", "50"));
// determine first command to save
from = m_CommandHistory.size() - size;
if (from < 0) {
from = 0;
}
// fill properties
PROPERTIES.setProperty("HistorySize", "" + size);
for (i = from; i < m_CommandHistory.size(); i++) {
PROPERTIES.setProperty("Command" + (i - from), m_CommandHistory.get(i));
}
try {
filename =
WekaPackageManager.PROPERTIES_DIR.getAbsolutePath() + File.separatorChar
+ FILENAME;
stream = new BufferedOutputStream(new FileOutputStream(filename));
PROPERTIES.store(stream, "SimpleCLI");
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Displays the panel in a frame.
*
* @param args ignored
*/
public static void main(String[] args) {
weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO,
"Logging started");
LookAndFeel.setLookAndFeel();
// make sure that packages are loaded and the GenericPropertiesCreator
// executes to populate the lists correctly
weka.gui.GenericObjectEditor.determineClasses();
showPanel(new SimpleCLIPanel(), args);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy