Java-类似于控制台的Web小程序
嗨,我一直在使用Java在Windows控制台中开发应用程序,并希望将其在线发布在其所有console-graphics-glory中。
我可以使用一个简单的Web applet API来移植我的应用程序吗?
我仅使用基本的System.out和System.in功能,但很高兴重建我的I / O包装器。
我认为,对于希望将其工作放在网上的任何新手Java开发人员而言,遵循这些思路将是一项巨大的财富。
解决方案
我记得大约在几年前(人们使用telnet时)中看到了seeig telnet客户端applet的实现。也许我们可以将它们挖掘出来并进行修改。
当然,只要做成一个applet,就在上面放一个带有JFrame的小摆幅UI,它带有两个组件,一个用于向其中写入输出,一个用于从中输入输入。将小程序嵌入页面中。
System.out和System.in是静态的,因此是邪恶的。我们需要遍历程序,并用非静态变量("上方参数")替换它们。从小程序中,我们不能使用System.setOut / setErr / setIn。
然后,我们几乎可以分类了。一个小程序。添加一个TextArea(或者等效项)。将输出追加到文本区域。将按键输入到输入中。任务完成。
作为光荣的,非常有用的类似cnsole的webapp的一个杰出示例,请参阅goosh,即Google Shell。我无法想象没有它就浏览网络。
当然,没有源代码,但是通过使用Firebug或者类似的东西,我们可能会发现它的魔力。
使用TextArea可能是易于出错的方法。请记住,我们需要同时对此TextArea进行输入和输出,因此必须跟踪光标位置。我建议,如果我们确实采用这种方法,则可以在一个普通的TextArea上进行抽象(可能是继承性),并使用一个具有例如一个prompt()
来显示提示并启用输入,一个prompt()
也遵循通常的shell抽象,即具有stdin
(一个InputStream,它从提示中读取,但是可以绑定到文件等)和` stdout和可能的stderr OutputStreams绑定到TextArea的文本。
这不是一件容易的事,而且我不知道有什么图书馆可以做到这一点。
我按照Lars的建议做了,写了我自己的。
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(); } }
下面的代码在单独的类" Input"中,该类具有静态的" inString"字符串。
public static String getString() { inString = ""; // Wait for input while (inString == "") { try{ Thread.sleep(100); } catch (Exception e) {} } return inString; }
在项目的整个生命周期中,我可能会保留一些代码,但现在它可以工作了:)