Java text based application
Asked Answered
A

2

6

The main idea is to try and make an application that would have look-and-feel of a standard Linux-type terminal. Now I am limited to Java and here is what I want.

  1. Main Window (independent JFrame) with top menu (ok this I know how to do)
  2. Entire area below the menubar is for "console" that users could interact by typing in the commands (this I have no clue about).

Is there any easy-enough way of doing such a thing. This should be a text processing app and should run system-independent and standalone. All work logic should be derived from user input.

Any ideas?

August answered 25/4, 2012 at 10:19 Comment(2)
please see https://mcmap.net/q/993843/-create-a-quot-command-quot-consoleManville
this BeanShell seems to be just thing that I was after, but the example there does not seem to work properly.August
I
2

The 'console' could be implemented using a JTextPane. Whenever the window has focus, you can write any keypress to the text pane and parse, execute whenever 'Enter' is pressed (use a KeyListener and implement keyTyped).

Ivon answered 25/4, 2012 at 10:31 Comment(3)
"use a KeyListener" Wouldn't key bindings or a DocumentListener be better suited to this? For the simplicity, I preferred the other approach by user unknown.Serigraph
Possibly yes. The problem with DocumentListener is that you would have to distinguish between whether text was inserted (/document updated) by user input or by output from the 'programs' that are run as a result of the command.Ivon
The solution with the separate input field does not really give the look and feel of a linux terminal but I agree that it is simpler.Ivon
D
5

I guess you need two text components, a text-area and a text-field.

If the user enters text into the text-field at the bottom, and hits Enter, the text is moved into the text-area, where it isn't editable any more. Then processing takes place, eventually a result (or multiples) are printed to the text-area, and the next line can be entered.

The upper area could have a JScrollPane. Somehow, buffering has to be handled.

Here is a simple, complete and runnable example:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.plaf.ActionMapUIResource;
/**
    CmdPrompt

    @author Stefan Wagner
    @date Mi 25. Apr 17:27:19 CEST 2012
    (c) GPLv3
*/
public class CmdPrompt extends JFrame 
 {
    private static final String progname = "CmdPrompt 0.1";

    private JTextField input;
    private JTextArea history;

    public CmdPrompt ()
    {
        super (progname);
        JPanel mainpanel = new JPanel ();
        mainpanel.setLayout (new BorderLayout ());
        this.getContentPane ().add (mainpanel);

        input = new JTextField (80);
        history = new JTextArea ();
        mainpanel.add (history, BorderLayout.CENTER);
        mainpanel.add (input, BorderLayout.SOUTH);

        ActionMap actionMap = new ActionMapUIResource ();
        actionMap.put ("enter", new AbstractAction () {
            @Override
            public void actionPerformed (ActionEvent e) {
                String cmd = input.getText ();
                String sofar = history.getText ();
                history.setText (sofar + "\n> " + cmd + "\n"  + processCmd (cmd)); 
                input.setText ("");
            }
        });
        InputMap keyMap = new ComponentInputMap (input);
        keyMap.put (KeyStroke.getKeyStroke (KeyEvent.VK_ENTER, 0), "enter");

        SwingUtilities.replaceUIActionMap (input, actionMap);
        SwingUtilities.replaceUIInputMap  (input, JComponent.WHEN_IN_FOCUSED_WINDOW, keyMap);

        setSize (400, 400);
        setLocation (100, 100);
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setVisible (true);          
    }

    private void center ()
    {
        Toolkit tk = Toolkit.getDefaultToolkit ();
        Dimension screen = tk.getScreenSize ();
        Dimension d = getSize ();
        setLocation ((screen.width - d.width) / 2, (screen.height - d.height) / 2);
    }
    public static String processCmd (String cmd) 
    {
        String arr [] = cmd.split (" "); 
        if ("rev".equals (arr [0])) {
            return reverse (cmd.substring (4)); 
        }
        else if ("upp".equals (arr [0])) {
            return (cmd.substring (4)).toUpperCase (); 
        }
        else if ("low".equals (arr [0])) {
            return (cmd.substring (4)).toLowerCase (); 
        }
        else if ("help".equals (arr [0])) {
            return ("rev, upp, low, help"); 
        }
        return "unknown command";
    }
    public static String reverse (String cmd) 
    {
        return (cmd.length () < 2) ? cmd : reverse (cmd.substring (1)) + cmd.charAt (0); 
    }

    public static void main (final String args [])
    {
        Runnable runner = new Runnable () 
        {
            public void run () 
            {
                new CmdPrompt ();
            }
        };
        EventQueue.invokeLater (runner);
    }
}
Diphase answered 25/4, 2012 at 11:23 Comment(1)
Yeah, thanks this is great and can be tuned to look the way I want. It is just that I wanted to avoid GUI commands altogether. I will surely use this.August
I
2

The 'console' could be implemented using a JTextPane. Whenever the window has focus, you can write any keypress to the text pane and parse, execute whenever 'Enter' is pressed (use a KeyListener and implement keyTyped).

Ivon answered 25/4, 2012 at 10:31 Comment(3)
"use a KeyListener" Wouldn't key bindings or a DocumentListener be better suited to this? For the simplicity, I preferred the other approach by user unknown.Serigraph
Possibly yes. The problem with DocumentListener is that you would have to distinguish between whether text was inserted (/document updated) by user input or by output from the 'programs' that are run as a result of the command.Ivon
The solution with the separate input field does not really give the look and feel of a linux terminal but I agree that it is simpler.Ivon

© 2022 - 2024 — McMap. All rights reserved.