A library for creating interactive console applications in Java

Related tags

CLI console text-based
Overview

PRs Welcome License Build Status

Text-IO

Text-IO is a library for creating Java console applications. It can be used in applications that need to read interactive input from the user.

Features

  • supports reading values with various data types.
  • allows masking the input when reading sensitive data.
  • allows selecting a value from a list.
  • allows to specify constraints on the input values (format patterns, value ranges, length constraints etc.).
  • provides different terminal implementations and offers a Service Provider Interface (SPI) for configuring additional text terminals.

By default, Text-IO tries to use text terminals backed by java.io.Console. If no console device is present (which may happen, for example, when running the application in your IDE), a Swing-based terminal is used instead.

Example

TextIO textIO = TextIoFactory.getTextIO();

String user = textIO.newStringInputReader()
        .withDefaultValue("admin")
        .read("Username");

String password = textIO.newStringInputReader()
        .withMinLength(6)
        .withInputMasking(true)
        .read("Password");

int age = textIO.newIntInputReader()
        .withMinVal(13)
        .read("Age");

Month month = textIO.newEnumInputReader(Month.class)
        .read("What month were you born in?");

TextTerminal terminal = textIO.getTextTerminal();
terminal.printf("\nUser %s is %d years old, was born in %s and has the password %s.\n",
        user, age, month, password);

Click on the image below to see the output of the above example in a Swing-based terminal.

You can also use a web-based terminal, which allows you to access your application via a browser, as shown in the image below.

Useful links

Text-IO is available in Maven Central and JCenter.

Comments
  • Any way to get TextTerminal.print method to handle \r ?

    Any way to get TextTerminal.print method to handle \r ?

    I would like to use the print method of TextTerminal to output a line that is continually updated. In past, I was able to accomplish this using \r at the end of printf format string. So far, I have been unable to get this working with TextIO. Is there any way to accomplish this?

    Thanks again,

    -Tony

    opened by tonypiazza 20
  • autocomplete using up and down arrow key

    autocomplete using up and down arrow key

    how do I even begin to implement some sort of autocomplete at the input cursor by using up and down arrow keys ?

    I suppose this will be a nice feature for text-io that others are interested in.

    Say I have List<String> names = Arrays.asList("albert", "alice", "ava", "betty", "cathy");

    So when asked about inputting a name, at the input prompt, if I type in the first letter as "a", (but before typing in the second letter), and I hit the up arrow key, I would like the word "albert" to pop up at the input prompt.

    I suppose I'll need to write my own methods to implement the nitty gritty.

    Can someone show me first on how to capture the input before hitting enter ?

    How do I make use of the up and down arrow keys. Is it by registering handlers and how ?

    Thanks!

    opened by mokun 16
  • refresh line

    refresh line

    Is there a way to go beyond changing the value on the whole screen or the value on, say, the 5th line from the bottom of the screen ?

    I can see in the Weather that it calls terminal.resetLine() and terminal.moveToLineStart() to refresh the value of the very last line on the screen.

    In TextTerminal, there is :

        @Override
        public boolean resetLine() {
            return resetToOffset(startLineOffset);
        }
    
        @Override
        public boolean moveToLineStart() {
            overwriteOffset = startLineOffset;
            return true;
        }
    

    We can literally build a game out of the text terminal if we can give the ability to change the value of a text with, say, overwrite(x,y), where x being the x-th position from the left, y being the y-th line from the bottom.

    opened by mokun 4
  • Making System console as default instead of JLint based console.

    Making System console as default instead of JLint based console.

    I am building a console application using text-io in intellij ide. I have added text-io:2.7.2 dependency in pom. I am creating terminal as TextIO textIO = TextIoFactory.getTextIO(). When I run this application in IDE, it opens a JLint based terminal.

    Then I am using maven-shade plugin to create an uber jar. When I run this jar on mac terminal, it is throwing below error -

    Exception in thread "main" java.lang.NoClassDefFoundError: javafx/scene/paint/Color
    	at org.beryx.textio.jline.JLineTextTerminal.<clinit>(JLineTextTerminal.java:64)
    	at org.beryx.textio.jline.JLineTextTerminalProvider.getTextTerminal(JLineTextTerminalProvider.java:32)
    	at org.beryx.textio.TextIoFactory$Holder.getDefaultTerminal(TextIoFactory.java:95)
    	at org.beryx.textio.TextIoFactory$Holder.<init>(TextIoFactory.java:65)
    	at org.beryx.textio.TextIoFactory$Holder.<clinit>(TextIoFactory.java:54)
    	at org.beryx.textio.TextIoFactory.getTextIO(TextIoFactory.java:111)
    	at com.javastreets.jeegen.Main.main(Main.java:12)
    Caused by: java.lang.ClassNotFoundException: javafx.scene.paint.Color
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    	... 7 more
    

    I want to use the standard console/terminal, how to default the TextIOFactory to use console instead of JLint.

    Using below gets me what I wanted but just wondering if there is better way of doing that with TextIOFactory -

    TextIO textIO = new TextIO(new ConsoleTextTerminalProvider().getTextTerminal());

    And, thanks for this cool libarby 👍 !

    opened by manikmagar 4
  • Specific Maven example for WebTextTerminal

    Specific Maven example for WebTextTerminal

    Hallo Serban,

    Many thanks for making available text-io, I think it is fantastic and the best tool in the java world for providing a command line regardless of the interface.

    Both the console and swing versions worked great out of the box, was possible to learn how to use them very quickly. My difficulty is with the WebTexTerminal. I'm struggling to get it working under Maven without success so far. I'm able to compile the Gradle demo, but unable to port this into the maven project. The documentation available on this part I'm unfortunately unable to follow and understand what is missing.

    Would it be possible to ask for a quick demo specifically written in Maven just for the WebTextTerminal?

    Many thanks in advance.

    opened by maxbrito500 3
  • Fixed SwingTextTerminal memory leak

    Fixed SwingTextTerminal memory leak

    When a SwingTextTerminal calls getStyle(StyleData), it always adds a new style to it's Document. After a couple thousand lines of printed text, the unnecessary references start to cause issues. This change modifies the style name to be a hashcode of the style, and only adds a new style to its document when document.getStyle(<hash>) returns null.

    Test code (which, in a perfect world, takes 20 seconds to run):

    import org.beryx.textio.TextIO;
    import org.beryx.textio.TextIoFactory;
    import org.beryx.textio.swing.SwingTextTerminal;
    
    import java.awt.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            TextIO io = TextIoFactory.getTextIO();
            SwingTextTerminal terminal = (SwingTextTerminal) io.getTextTerminal();
            terminal.display();
            long initialTime = System.nanoTime();
    
            for (int i = 0; i < 100; i++) {
                EventQueue.invokeAndWait(() -> spam(terminal));
    
                // Delay so the text actually appears in the terminal
                Thread.sleep(200);
    
                terminal.resetToOffset(0);
            }
    
            double timeInSeconds = (System.nanoTime() - initialTime) / 1000000000.0;
            System.out.println("Elapsed time: " + timeInSeconds);
        }
    
        private static void spam(SwingTextTerminal t) {
            for (int i = 0; i < 100; i++) {
                t.println("This text is long enough to fill up the entire line.");
            }
        }
    }
    

    Output before PR: Elapsed time: 141.755707654

    Output after PR: Elapsed time: 20.540818568

    Note: I'm not quite sure if this change breaks anything else, as I don't have the most knowledge of Swing. I was experiencing trouble in an application I'm developing with this library and used YourKit to analyze the program, and it led me straight to the getStyle() method. As soon as I implemented this change, the problem went away, and as far as I could tell, there weren't any side effects. Let me know if there's anything else I need to modify to improve this PR.

    opened by mattco98 3
  • Input masking doesn't work with SystemTextTerminal

    Input masking doesn't work with SystemTextTerminal

    Sample code:

    import org.beryx.textio.TextIO;
    import org.beryx.textio.system.SystemTextTerminal;
    
    public class Test
    {
        public static void main(String[] args)
        {
            final SystemTextTerminal terminal = new SystemTextTerminal();
            final TextIO             textIO   = new TextIO(terminal);
    
            final String password = textIO.newStringInputReader()
                .withMinLength(1)
                .withInputMasking(true)
                .read("Password");
        }
    }
    

    Result:

    textio-input-masking

    Java version:

    C:\tmp\textio>java -version
    openjdk version "17.0.1" 2021-10-19
    OpenJDK Runtime Environment Temurin-17.0.1+12 (build 17.0.1+12)
    OpenJDK 64-Bit Server VM Temurin-17.0.1+12 (build 17.0.1+12, mixed mode, sharing)
    

    Expected result is for the input to be masked and the typed characters to be invisible.

    opened by RedShift1 2
  • Error Message Provider for EnumInputReader  with Numbered Values

    Error Message Provider for EnumInputReader with Numbered Values

    It would be great if we had the possibility to replace the standard "Enter a value between 1 and X" error message in the EnumInputReader. I'm developing an application in Portuguese, so the default english message doesn't fit well.

    By debugging i found that there isn't any checks for a Message Provider in the method getValueFromIndex of class InputReader:

    private T getValueFromIndex(String sVal, TextTerminal<?> textTerminal) {
            try {
                int optIndex = Integer.parseInt(sVal);
                if (optIndex > 0 && optIndex <= this.possibleValues.size()) {
                    return this.possibleValues.get(optIndex - 1);
                }
            } catch (NumberFormatException var4) {
            }
    
            textTerminal.executeWithPropertiesPrefix("error", (t) -> {
                textTerminal.print(this.getDefaultErrorMessage(sVal));
                textTerminal.println(" Enter a value between 1 and " + this.possibleValues.size() + ".");
            });
            textTerminal.println();
            return null;
    }
    
    opened by Jprnp 2
  • how to save a history of previous input ?

    how to save a history of previous input ?

    Thanks to https://github.com/beryx/text-io/issues/17 that I now have the autocomplete setup for my program.

    There are times that I would like to reenter the same input that I made in the past.

    Is there an elegant way to program the Left and Right arrow keys to scroll backward and forward the input ?

    I come up with this in SwingHandler but fall short of what to do next ?

        private static final String KEY_STROKE_LEFT = "pressed LEFT";
        private static final String KEY_STROKE_RIGHT = "pressed RIGHT";
        private String historyInput = "";
        private int historyIndex = -1;
        private String[] history = {};
    
      public SwingHandler(SwingTextTerminal terminal) {
            this.terminal = terminal;
            terminal.registerHandler(KEY_STROKE_LEFT, t -> {
                if (historyIndex >= 0) {
                    historyIndex--;
                    String text = (historyIndex < 0) ? historyInput : choices[historyIndex ];
                    t.replaceInput(text, false);
                }
                return new ReadHandlerData(ReadInterruptionStrategy.Action.CONTINUE);
            });
    
    opened by mokun 2
  • prompt input

    prompt input

    How do I programmatically input something in a prompt ?

    Say, I want to run a demo of how to make an input in a prompt.

    Is there something in SwingHandler that I can use in order to simulate manually typing in something and hit the enter ?

    Thanks !

    opened by mokun 2
  • how to prevent cursor from moving

    how to prevent cursor from moving

    Hi,

    How do I defensively "fix" the position of the blinking cursor right at the line of the most recent input ?

    Currently, the up, down, left, right arrow key can move the cursor key elsewhere on the terminal, which is undesirable, especially that the user may not know that the cursor key needs to be returned to that same spot in order to continue to type the input.

    Thanks much for this great API !

    opened by mokun 2
  • Change error messages

    Change error messages

    Hi, I'm still clueless to change error message when using text-io, do I need to call withParseErrorMessagesProvider for every input reader that have been made?

    Thanks.

    opened by 10120128 2
  • MockTextTerminal strips out new lines

    MockTextTerminal strips out new lines

    On calling org.beryx.textio.mock.MockTextTerminal#getOutput the returned string has all the new lines and leading/trailing spaces removed because org.beryx.textio.mock.MockTextTerminal#stripAll is called on the stored string before returning it.

    Given that the output is joined using the new line as separator, I assume this has been done in order to have a uniform and linear output. Unfortunately, this doesn't allow to test certain scenarios, like "Does the output ends with a new line?".

    In my opinion, stripping should be an option that the consumer of the class can decide to use or not. A simple overload of getOutput() with a boolean flag would be enough :)

    opened by cdprete 0
  • Allow cumulative possible values and properties configurators

    Allow cumulative possible values and properties configurators

    Hi. At the moment, the methods with[Numbered]PossibleValues and withPropertiesConfigurator only apply globally, aka to all the possible choices. It would be nice to be able to to define the possible values in a cumulative way and also pass the configurator to just that subset of possible values so to render them differently. I know I can print all the properties manually and use an int reader as workaround to have the same behaviour, but it's quite ugly.

    Does this feature make sense to you?

    Cheers

    opened by cdprete 0
  • How to use MockTextTerminal

    How to use MockTextTerminal

    Hi. Can you please provide some documentation or guidance on how to use the MockTextTerminal? I would like to unit-test my business logic and the example in the repository with the Robot is not really adequate for unit tests (given the definition of unit test).

    Kind regards and thanks in advance.

    opened by cdprete 7
  • Cookies on WebTextTerminal

    Cookies on WebTextTerminal

    Hello,

    Was able to make progress quickly, the command line app is looking great thanks to Text-IO.

    What is now missing is persistent memory. This can be done on the swing and command line interfaces very easily using files on disk for storage to remember a user that is logged, but not so trivial for the WebTextTerminal because the ContextHandlers don't seem to be exposed for usage. Otherwise would be possible to solve this by extracting URL paths and cookies.

    Perhaps exposing the Context object from Ratpack is the simplest way? I imagine it is not easy to create a common mechanism for both spark and ratpack, on this case just needed for RatPack.

    How would you recommend that we can access cookies and the URL from within Text-IO for the purpose of persistent user-memory? (to know who is logged inside the app).

    Again: many, many thanks. Really good library.

    opened by maxbrito500 5
Releases(v3.4.1)
JLine is a Java library for handling console input.

JLine JLine is a Java library for handling console input. It is similar in functionality to BSD editline and GNU readline but with additional features

null 1.2k Jan 5, 2023
Spring based interactive shell

Spring Shell 3 Spring Shell 3 is a work to solely depend on Spring Boot 2.x and not trying to keep any backward compatibility with older Spring Shell

Spring 609 Dec 14, 2022
Java library for creating text-based GUIs

Lanterna Lanterna is a Java library allowing you to write easy semi-graphical user interfaces in a text-only environment, very similar to the C librar

null 2k Dec 31, 2022
Tiny logging wrapper dedicated for CLI-oriented applications

Dynamic Logger Tiny logging wrapper dedicated for CLI oriented applications with non-static logger that require dynamic threshold/level changes, progr

Dzikoysk 3 Sep 25, 2022
Command-line API for Atlassian JIRA using the Tomitribe CREST library

Atlassian JIRA Command-Line (CLI) Jamira is a command-line API for Atlassian JIRA using the Tomitribe CREST library. Installation Jamira can be downlo

Tomitribe 12 Sep 10, 2022
JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. Go check the README.md file to see how to use it.

JCLR JCLR (JavaColor) is a library that allows you to write colored text in your terminal. It use the ANSI color system. To start using it, go to the

Scythe 3 Aug 21, 2021
Java annotation-based framework for parsing Git like command line structures

Airline Airline is a Java annotation-based framework for parsing Git like command line structures. Latest release is 0.8, available from Maven Central

null 847 Nov 26, 2022
ASCII renderer in pure java with no external dependencies

Java ASCII Render ASCII renderer in pure java with no external dependencies. Java ASCII Render supports graphical primitives/elements, layers, context

David E. Veliev 140 Dec 12, 2022
Command line parsing framework for Java

JCommander This is an annotation based parameter parsing framework for Java 8. Here is a quick example: public class JCommanderTest { @Parameter

Cedric Beust 1.8k Dec 29, 2022
Jansi is a small java library that allows you to use ANSI escape sequences to format your console output which works even on windows.

Description Jansi is a small java library that allows you to use ANSI escape codes to format your console output which works even on Windows. It also

FuseSource 955 Dec 28, 2022
JLine is a Java library for handling console input.

JLine JLine is a Java library for handling console input. It is similar in functionality to BSD editline and GNU readline but with additional features

null 1.2k Jan 5, 2023
Tic-Tac-Toe-GUI - This repository contains Java based interactive Tic-Tac-Toe game.

Tic-Tac-Toe This repository contains Java based interactive Tic-Tac-Toe game. In this game you can play individual or with another player with your na

Ahmed Hossam 11 Sep 1, 2022
Sniffy - interactive profiler, testing and chaos engineering tool for Java

Sniffy Sniffy is a Java profiler which shows the results directly in your browser. It also brings profiling to your unit (or rather component) tests a

Sniffy 139 Dec 23, 2022
Drifty is an open-source interactive File Downloader system built with java. It is currently available in CLI mode and has the GUI version under active development.

Drifty Drifty is an open-source interactive File Downloader system built using Java. It takes the link to the file, the directory where it needs to be

Saptarshi Sarkar 60 Dec 24, 2022
Terminal GUI library for simple ANSI console tools and graphical interfaces with Windows/Linux support

TerminalCore Terminal GUI library for Windows/Linux. This library contains all colors as ascii codes, native functions of the respective operating sys

Pascal 3 Oct 19, 2022
Spring based interactive shell

Spring Shell 3 Spring Shell 3 is a work to solely depend on Spring Boot 2.x and not trying to keep any backward compatibility with older Spring Shell

Spring 609 Dec 14, 2022
Sourcetrail - free and open-source interactive source explorer

Sourcetrail Sourcetrail is a free and open-source cross-platform source explorer that helps you get productive on unfamiliar source code. Windows: Lin

Coati Software 13.2k Jan 5, 2023
Web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more.

Apache Zeppelin Documentation: User Guide Mailing Lists: User and Dev mailing list Continuous Integration: Contributing: Contribution Guide Issue Trac

The Apache Software Foundation 5.9k Jan 8, 2023
ThirdEye is an integrated tool for realtime monitoring of time series and interactive root-cause analysis.

ThirdEye is an integrated tool for realtime monitoring of time series and interactive root-cause analysis. It enables anyone inside an organization to collaborate on effective identification and analysis of deviations in business and system metrics. ThirdEye supports the entire workflow from anomaly detection, over root-cause analysis, to issue resolution and post-mortem reporting.

null 87 Oct 17, 2022