Windows 7 Console
by
, January 25th, 2012 at 04:31 PM (3544 Views)
Well I encountered a problem recently that a lot of people were complaining about when I Googled, which is a lot of the time I like to share some basic console programs with only have functional java installed, and on windows 7 the command I used to use to open command prompt [Runnable.getRunnable().exec("exec /k run.bat")] no longer works due to security precautions. So I made a simple class that creates the functional equivalent of console for programs. Possibly the size of the console might need to be tweaked for each program, but that's not tricky. I've only tested this on one program, and here is what I did to convert the program completely out of System.out.
An image:
consoleGui1.jpg
Put the ConsoleGUI inside the package of your class(es) and, if necessary, set it's package.
First - make a private static global variable of type ConsoleGUI.TAScanner and call it whatever your old Scanner was called
Second - Make another variable of ConsoleGUI.TAPrintStream. This is your new output stream. (Can't currently use printf)private static ConsoleGUI.TAScanner scanner
Third - Using your IDE replace all calls to System.out( with out(private static ConsoleGUI.TAPrintStream out
Fourth - Remove your old Scanner.
Fifth - In your main method add these lines (Unless you used different variable names)
Recompile, and your done!ConsoleGUI.toGUI(); scanner = ConsoleGUI.getScanner(); out = ConsoleGUI.getStream();
The class
Note - If you find any bugs / inefficiencies do talk!package me.timothy.consolegui; import java.util.Scanner; import javax.swing.*; import java.awt.BorderLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.io.PrintStream; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.File; import java.io.IOException; import java.util.InputMismatchException; import javax.swing.text.DefaultCaret; /** * Turns a console program into a basic GUI program, useful * for Window 7 programs that are unable to open command * prompt with a .jar All a class has to do in order to use * this program is call the static method toGUI(), a special Scanner is * acquirable instead of System.in * (Attrievable by a call to getScanner(), which is static) * By a call to saveSaveText(true), it will save the calls to out and scanner, * however it does not throw any exceptions and may cause lag if * there are a lot of System.out calls. * * @author Timothy Moore */ public class ConsoleGUI extends JFrame { private static volatile boolean saveRun = false; /** * The ConsoleGUI */ private static ConsoleGUI gui; /** * The Scanner being used */ private TAScanner scanner; /** * The stream being used */ private TAPrintStream stream; /** * The main text area, where calls to System.out go */ private JTextArea txtArea; /** * Where the user enters information */ private JTextField userField; /** * The submit button, not actually necessary */ private JButton submit; /** * The JScrollPane wrapper */ private JScrollPane sPane; /** * Creates the GUI */ private ConsoleGUI() { setSize(350, 350); setTitle("Console GUI"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null); setLayout(new BorderLayout()); txtArea = new JTextArea(); txtArea.setEditable(false); sPane = new JScrollPane(txtArea); add(sPane, BorderLayout.CENTER); userField = new JTextField(); userField.setEditable(false); userField.setActionCommand("submit"); submit = new JButton("Submit"); submit.setActionCommand("submit"); JPanel bot = new JPanel(); bot.setLayout(new BorderLayout()); bot.add(userField, BorderLayout.CENTER); bot.add(submit, BorderLayout.EAST); add(bot, BorderLayout.SOUTH); } /** * Sets the program to use the ConsoleGUI instead of the regular * Console */ public static void toGUI() { try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { gui = new ConsoleGUI(); gui.stream = gui.createPrintStream(); gui.setVisible(true); } }); }catch(Exception exc) { handleException("Failed to convert to gui", exc, saveRun); } } public static void setConsoleTitle(String tit) { gui.setTitle(tit); } /** * Creates a TAPrintStream based on the text area */ private TAPrintStream createPrintStream() { return new TAPrintStream(txtArea); } /** * @return a new TAScanner */ private TAScanner createScanner() { return new TAScanner(userField, submit); } /** * @return the print stream */ public static TAPrintStream getStream() { return gui.stream; } /** * Sets if it is saving the text, by default false * @param b if it should save text */ public static void setSaveText(boolean b) { saveRun = b; } /** * @return the scanner to use. Has most methods of Scanner * @throws NullPointerException if called before toGUI */ public static TAScanner getScanner() { if(gui.scanner == null) gui.scanner = gui.createScanner(); return gui.scanner; } /** * Handles an exception with the specified message and * underlying throwable. This method will handle all * exceptions appropriately. * * This method will return normally. * * @param msg the message, can be null. * @param exc the exception, cannot be null * @param saveToFile if file io should be attempted. */ public static void handleException(String msg, Throwable exc, boolean saveToFile) { try { TAPrintStream out = getStream(); out.print(msg); out.println(" - " + exc.getClass().getSimpleName()); StackTraceElement[] elements = exc.getStackTrace(); for(StackTraceElement t : elements) { out.println(t); } }catch(Exception exce) { // Not cool. exce.printStackTrace(); } } /** * For testing purposes, shows an example usage of this program */ public static void main(String[] args) { ConsoleGUI.toGUI(); //ConsoleGUI.setSaveText(true); TAScanner scanner = ConsoleGUI.getScanner(); TAPrintStream out = ConsoleGUI.getStream(); out.println("Type a string"); String str = scanner.nextLine(); out.println("Type an int"); int i = scanner.nextInt(); out.println("You typed "+str+" and "+i); out.println("Say something starting with y"); boolean b = scanner.nextBoolean(); out.println(b); out.println("Say something starting with n"); b = scanner.nextBoolean("n", true); out.println(b); out.println("Say banana"); b = scanner.nextBoolean("banana", false); out.println(b); out.println(); RuntimeException exc = new RuntimeException(); handleException("Test", exc, true); //for(int i = 0; i < 50; i++) { out.println("Purposeful Spam"); } } @Override public String toString() { return "initialized"; } /** * Short for TextAreaPrintStream, this stream sends all messages * to the GUI instead of the regular System.out * * @author Timothy Moore */ public class TAPrintStream { private JTextArea txtArea; private BufferedWriter fileWriter; private final File file = new File("lastRun.txt"); /** * Create a print stream to the specified text area */ private TAPrintStream(JTextArea txtArea) { this.txtArea = txtArea; DefaultCaret caret = (DefaultCaret)txtArea.getCaret(); caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); } public void print(Object msg) { txtArea.append(msg.toString()); if(saveRun) { if(fileWriter == null) { //System.out.println("Creating file writer"); try { file.createNewFile(); fileWriter = new BufferedWriter(new FileWriter(file)); }catch(Exception exc) { saveRun = false; handleException("Failed to create file", exc, false); } Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { fileWriter.close(); }catch(IOException e) { handleException("Failed to close writer", e, false); } } }); } //System.out.println("Saving to filewriter"); try { String[] msgs = msg.toString().split("/n"); for(String s : msgs) { fileWriter.write(s); fileWriter.newLine(); } }catch(Exception e) { handleException("Failed to write to file", e, false); saveRun = false; } } } public void print(boolean msg) { print(new StringBuilder().append(msg)); } public void print(int msg) { print(new StringBuilder().append(msg)); } public void print(long msg) { print(new StringBuilder().append(msg)); } public void print(double msg) { print(new StringBuilder().append(msg)); } public void println() { print("\n"); } public void println(Object msg) { print(new StringBuilder().append(msg).append("\n")); } public void println(int msg) { println(new StringBuilder().append(msg)); } public void println(long msg) { println(new StringBuilder().append(msg)); } public void println(boolean msg) { println(new StringBuilder().append(msg)); } public void println(double msg) { println(new StringBuilder().append(msg)); } } /** * Short for TextAreaScanner, this Scanner retrieves messages * from the GUI instead of the regular new Scanner(System.in) * * @author Timothy Moore */ public class TAScanner implements ActionListener { private String str; private JTextField field; private JButton but; /** * Creates a scanner based on the specified text field * and button */ private TAScanner(JTextField field, JButton but) { this.field = field; this.but = but; field.addActionListener(this); but.addActionListener(this); } /** * Reads one string */ public String readLine() { field.setEditable(true); str = null; while(str == null) { delay(100); } ConsoleGUI.getStream().println(new StringBuilder("> ").append(str)); return str; } /** * Same as readLine() */ public String nextLine() { return readLine(); } /** * Same as readInt() */ public int nextInt() { return readInt(); } /** * Same as readBoolean() */ public boolean nextBoolean() { return readBoolean(); } /** * Same as readLong() */ public long nextLong() { return readLong(); } /** * @return an integer from user */ public int readInt() { try { return Integer.valueOf(readLine()); }catch(NumberFormatException exc) { throw new InputMismatchException(exc.getMessage()); } } /** * @return a long from user */ public long readLong() { try { return Long.valueOf(readLine()); }catch(NumberFormatException exc) { throw new InputMismatchException(exc.getMessage()); } } /** * @return a boolean from user, assuming anything starting with a y is yes */ public boolean readBoolean() { return readBoolean("Y", true); } /** * This is not case sensitive. * @return a boolean from user * @param str the string that the response needs to be true * @param start if the string has to start with the string or be completely that string */ public boolean readBoolean(String str, boolean start) { if(start) { return readLine().toLowerCase().startsWith(str.toLowerCase()); }else { return readLine().equalsIgnoreCase(str); } } /** * Same as <code>readBoolean(String str, boolean str)</code> */ public boolean nextBoolean(String str, boolean start) { return readBoolean(str, start); } @Override public void actionPerformed(ActionEvent event) { str = field.getText(); field.setText(""); } } /** * Like thread.sleep but does not throw exceptions. Use with caution * @param ms the time in ms */ public static void delay(long ms) { try { Thread.sleep(ms); }catch(InterruptedException exc) { } } }
EDIT:
Fixed some inefficiencies and added saveLastRun