views:

1949

answers:

7

Hey, I've been developing an application in the windows console with Java, and want to put it online in all of its console-graphics-glory.

Is there a simple web applet API I can use to port my app over?

I'm just using basic System.out and System.in functionality, but I'm happy to rebuild my I/O wrappers.

I think something along these lines would be a great asset to any beginning Java developers who want to put their work online.

A: 

I remember seenig telnet client applet implementationa around years ago (back when people used telnet). Maybe you could dig them out and modify them.

skaffman
+4  A: 

Sure, just make into an applet, put a small swing UI on it with a JFrame with two components - one for writing output to, and one for entering inputs from. Embed the applet in the page.

Lars Westergren
Done, posted the result below. Thanks Lars!
Dean
A: 

System.out and System.in are statics and therefore evil. You'll need to go through your program replacing them with non-statics ("parameterise from above"). From an applet you can't use System.setOut/setErr/setIn.

Then you're pretty much sorted. An applet. Add a TextArea (or equivalent). Append output to the text area. Write key strokes to the input. Job done.

Tom Hawtin - tackline
I only use System.in and System.out in my IO class wrapper - So that won't take too long.So I suppose the answer is just to use a TextArea. Thanks!
Dean
+3  A: 

As a premier example of a glorious and incredibly useful cnsole-like webapp, please see goosh, the Google Shell. I cannot imagine browsing the Net without it anymore.

Granted, there's no source code, but you might get out a bit of its magic by using Firebug or so.

Using a TextArea might be a bug-prone approach. Remember that you'll need to do both input and output to this TextArea and that you must thus keep track of cursor position. I would suggest that, if you really do this approach, you abstract away over a plain TextArea (inheritance, maybe?) and use a component that has, e.g. a prompt() to show the prompt and enable input and a also follows the usual shell abstraction of having stdin (an InputStream, that reads from the prompt, but can be bound to, let's say files or so) and stdout and possibly stderr, OutputStreams, bound to the TextArea's text.

It's not an easy task, and I don't know of any library to do it.

Aleksandar Dimitrov
+1  A: 

I did as Lars suggested and wrote my own.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.awt.Font;

public class Applet extends JFrame {
    static final long serialVersionUID = 1;

    /** Text area for console output. */
    protected JTextArea textArea;

    /** Text box for user input. */
    protected JTextField textBox;

    /** "GO" button, in case they don't know to hit enter. */
    protected JButton goButton;

    protected PrintStream printStream;
    protected BufferedReader bufferedReader;

    /**
     * This function is called when they hit ENTER or click GO.
     */
    ActionListener actionListener = new ActionListener() {
     public void actionPerformed(ActionEvent actionEvent) {
      goButton.setEnabled(false);
      SwingUtilities.invokeLater(
       new Thread() {
        public void run() {
         String userInput = textBox.getText();
         printStream.println("> "+userInput);
         Input.inString = userInput;
         textBox.setText("");
         goButton.setEnabled(true);
        }
       } 
      );
     }
    };

    public void println(final String string) {
     SwingUtilities.invokeLater(
      new Thread() {
       public void run() {
        printStream.println(string);
       }
      } 
     );
    }

    public void printmsg(final String string) {
     SwingUtilities.invokeLater(
      new Thread() {
       public void run() {
        printStream.print(string);
       }
      } 
     );
    }

    public Applet() throws IOException {
     super("My Applet Title");

     Container contentPane = getContentPane();

     textArea = new JTextArea(30, 60);
     JScrollPane jScrollPane = new JScrollPane(textArea);
     final JScrollBar jScrollBar = jScrollPane.getVerticalScrollBar();
     contentPane.add(BorderLayout.NORTH, jScrollPane);
     textArea.setFocusable(false);
     textArea.setAutoscrolls(true);
     textArea.setFont(new Font("Comic Sans MS", Font.TRUETYPE_FONT, 14));

     // TODO This might be overkill
     new Thread() {
      public void run() {
       while(true) {
        jScrollBar.setValue(jScrollBar.getMaximum());
        try{
         Thread.sleep(100);
        } catch (Exception e) {}
       }
      }
     }.start();

     JPanel panel;
     contentPane.add(BorderLayout.CENTER, panel = new JPanel());

     panel.add(textBox = new JTextField(55));
     textBox.addActionListener(actionListener);

     panel.add(goButton = new JButton("GO"));
     goButton.addActionListener(actionListener);

     pack();

     // End of GUI stuff

     PipedInputStream inputStream;
     PipedOutputStream outputStream;

     inputStream = new PipedInputStream();
     outputStream = new PipedOutputStream(inputStream);

     bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859_1"));
     printStream = new PrintStream(outputStream);

     new Thread() {
      public void run() {
       try {
        String line;
        while ((line = bufferedReader.readLine()) != null) {
         textArea.append(line+"\n");
        }
       } catch (IOException ioException) {
        textArea.append("ERROR");
       }
      }
     }.start();
    }
}

This below code was in a separate class, "Input", which has a static "inString" string.

    public static String getString() {
     inString = "";

     // Wait for input
     while (inString == "") {
      try{
       Thread.sleep(100);
      } catch (Exception e) {}
     }

     return inString;
    }

Through-out the lifespan of the project I will probably maintain this code some more, but at this point - it works :)

Dean
+1  A: 

Hi Dean,

I'm trying to get your wicked applet code to work, but I'm getting a weird error.

java.lang.ClassCastException: Applet cannot be cast to java.applet.Applet at sun.applet.AppletPanel.createApplet(AppletPanel.java:785) at sun.applet.AppletPanel.runLoader(AppletPanel.java:714) at sun.applet.AppletPanel.run(AppletPanel.java:368) at java.lang.Thread.run(Thread.java:619)

I see you say public Applet() halfway thru your code - so JFrame isn't an applet yet - but doing this allows you to make your Jframe into an applet.

I did Java in school back in 2000, so I've been away a while. I'm making a Java MUD game for fun that uses PHP MYSQL for the back end. I like the console idea, and Java seemed easiest.

Unless someone has another easy web-able interface that will let me do console

Thanks Rob

Rob
I haven't actually touched that project in ages, but when I get around to it (hopefully soon!) I'll have a look at your problem and get back to you!
Dean
A: 

Thanks Dean, look fwd to it. Otherwise i'm still searching for a good applet console. i'm making a MUD game and it's a pretty big part :)

Rob