0

Im currently writing a program that runs a class that implements runnable. I have it so the time in a format of HH:MM:SS is printed to the screen every second. Heres the code:

public class LaunchCounter
{

 public static void main(String[] args)
 {
    //Runs the CounterThread
    new CounterThread().start();
  }
}

And here is the counter class

public class CounterThread implements Runnable
{
 //Declare new thread
 private Thread thread;

public void start()
{
        thread = new Thread(this, "");
        thread.start();
}

@Override
public void run()
{   
    //Formatter used to display just time not date
    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

        //never ending forloop to display time
        for(int i = 1; i > 0; i++)
        {
            try
            {

                //Runtime.getRuntime().exec( "cmd /c cls" );
                //Sleep for 1 second after each loop
                Thread.sleep(1000);

                //new calender is created
                Calendar cal = Calendar.getInstance();
                System.out.println(dateFormat.format(cal.getTime()));
            }
            catch(Exception e1)
            {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
}

This works perfectly fine. What i am trying to achieve is that the line that is printed is cleared after waiting a second, and the the new time is printed and so on. So 12:00:01 becocomes 12:00:02 with out taking a new line.

I've tried System.out.print("\b\b\b\b\b\b\b") and Runtime.getRuntime().exec( "cmd /c cls" ); But this is just printing squares to the console.

How would i achieve this?

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
Aaronward
  • 129
  • 2
  • 11

2 Answers2

2

The problem is the terminal you're using. (My guess is that you are using the terminal in your IDE.) If your output terminal doesn't do full terminal emulation, it will either ignore the \b characters or display them as unprintable characters.

I tested the following code in IntelliJ IDEA 16 and verified that \b is ignored by the built in IDEA terminal. I then tested it in the MacOS terminal and it worked the way you want it to.

package test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class CounterThread implements Runnable {
  //Declare new thread
  private Thread thread;

  public void start() {
    thread = new Thread(this, "");
    thread.start();
  }

  @Override
  public void run() {
    //Formatter used to display just time not date
    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    //never ending forloop to display time
    for (int i = 1; i > 0; i++) {
      try {

        //Runtime.getRuntime().exec( "cmd /c cls" );
        //Sleep for 1 second after each loop
        Thread.sleep(1000);

        //new calender is created
        Calendar cal = Calendar.getInstance();
        System.out.print("\b\b\b\b\b\b\b\b");
        System.out.print(dateFormat.format(cal.getTime()));
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }

  public static void main(String[] args) throws Exception {
    //Runs the CounterThread
    new CounterThread().start();
    final Object monitor = new Object();
    synchronized (monitor) {
      monitor.wait();
    }
  }
}
  • 1
    I would add, for the noob's benefit, that "the console" in Java is not a window on a screen. It's just a source and a sink for streams of bytes. If there _is_ a window on the screen, that window is controlled by some _other_ program (a.k.a., "terminal emulator", "console window", "shell window", ..., or your IDE) and how that other program interprets the bytes that your program writes to `System.out` depends on what program it is, how it is configured, what old-fashioned hardware terminal it is emulating, etc.) – Solomon Slow Apr 13 '16 at 19:18
  • I used the code you provided, Still no luck. I am using Eclipse Mars IDE on windows 8.1. it must just not be possible on this IDE. – Aaronward Apr 13 '16 at 19:36
  • 2
    It won't work in your IDE because the console output in Eclipse isn't a proper terminal with terminal emulation (the thing that interprets the special characters like \b). Try executing the program in a proper terminal emulator. On OS X, the Terminal app is built in; on Linux, pretty much any shell you run will be in a terminal emulator; on Windows, there are many terminal emulators you can try. – David Coleman Apr 13 '16 at 21:56
0

You're on the right track using Runtime.getRuntime().exec("cls");. See this post here by Holger for maybe why you're not able to clear the console.

To solve this problem, we have to invoke the command line interpreter (cmd) and tell it to execute a command (/c cls) which allows invoking builtin commands. Further we have to directly connect its output channel to the Java process’ output channel, which works starting with Java 7, using inheritIO():

import java.io.IOException;

public class CLS {
   public static void main(String... arg) throws IOException, InterruptedException {
    new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
   } 
}

Now when the Java process is connected to a console, i.e. has been started from a command line without output redirection, it will clear the console.

Community
  • 1
  • 1
Sean
  • 507
  • 1
  • 9
  • 27