How can I print to the same line? - java

I want to print a progress bar like so:
[# ] 1%
[## ] 10%
[########## ] 50%
But these should all be printed to the same line in the terminal instead of a new one.
What I mean by that is that each new line should replace the previous, it's not about using print() instead of println().
How can I do that in Java?

Format your string like so:
[# ] 1%\r
Note the \r character. It is the so-called carriage return that will move the cursor back to the beginning of the line.
Finally, make sure you use
System.out.print()
and not
System.out.println()

In Linux, there is different escape sequences for control terminal. For example, there is special escape sequence for erase whole line: \33[2K and for move cursor to previous line: \33[1A. So all you need is to print this every time you need to refresh the line. Here is the code which prints Line 1 (second variant):
System.out.println("Line 1 (first variant)");
System.out.print("\33[1A\33[2K");
System.out.println("Line 1 (second variant)");
There are codes for cursor navigation, clearing screen and so on.
I think there are some libraries which helps with it (ncurses?).

First, I'd like to apologize for bringing this question back up, but I felt that it could use another answer.
Derek Schultz is kind of correct. The '\b' character moves the printing cursor one character backwards, allowing you to overwrite the character that was printed there (it does not delete the entire line or even the character that was there unless you print new information on top). The following is an example of a progress bar using Java though it does not follow your format, it shows how to solve the core problem of overwriting characters (this has only been tested in Ubuntu 12.04 with Oracle's Java 7 on a 32-bit machine, but it should work on all Java systems):
public class BackSpaceCharacterTest
{
// the exception comes from the use of accessing the main thread
public static void main(String[] args) throws InterruptedException
{
/*
Notice the user of print as opposed to println:
the '\b' char cannot go over the new line char.
*/
System.out.print("Start[ ]");
System.out.flush(); // the flush method prints it to the screen
// 11 '\b' chars: 1 for the ']', the rest are for the spaces
System.out.print("\b\b\b\b\b\b\b\b\b\b\b");
System.out.flush();
Thread.sleep(500); // just to make it easy to see the changes
for(int i = 0; i < 10; i++)
{
System.out.print("."); //overwrites a space
System.out.flush();
Thread.sleep(100);
}
System.out.print("] Done\n"); //overwrites the ']' + adds chars
System.out.flush();
}
}

You could print the backspace character '\b' as many times as necessary to delete the line before printing the updated progress bar.

package org.surthi.tutorial.concurrency;
public class IncrementalPrintingSystem {
public static void main(String...args) {
new Thread(()-> {
int i = 0;
while(i++ < 100) {
System.out.print("[");
int j=0;
while(j++<i){
System.out.print("#");
}
while(j++<100){
System.out.print(" ");
}
System.out.print("] : "+ i+"%");
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("\r");
}
}).start();
}
}

One could simply use \r to keep everything in the same line while erasing what was previously on that line.

In kotlin
print()
The print statement prints everything inside it onto the screen.
The print statements internally call System.out.print.
println()
The println statement appends a newline at the end of the output.

You can just do
System.out.print("String");
Instead
System.out.println("String");

Related

System.out.print("") isnt printing before the console is stopped by Scanner(System.in), e.i. cursor is just waiting

Here's the code:
private boolean getPlayerAction() {
while (player.getHandValue() < 21) {
System.out.print("Do you want to Hit or Stand?: ");
char c = getInput();
switch (c) {
case 'h' -> {
player.setCard(dealer.dealCard());
System.out.println(player.toString());
}
case 's' -> {
return true;
}
default -> System.out.println("Invalid entry, try again.");
}
}
if (player.getHandValue() > 21) {
System.out.println("Sorry. You bust.");
return false;
}
return true;
}
private char getInput() {
String input = in.nextLine();
if (!input.isEmpty()) return input.toLowerCase().charAt(0);
return 'b';
}
and here's the output:
Dealer is showing 10 with QS
You have 13 with 3H JC
It should have the prompt: "Do you want to Hit or Stand?: " where the blank line is. If I hit enter the output looks like this:
Dealer is showing 10 with QS
You have 13 with 3H JC
Do you want to Hit or Stand?: Invalid entry, try again.
Additional side note, I tried running this with println() instead of print() and it works as it should, but using print() I get the funky weirdness.
First thing I notice is that you may be well served by adding c.tolowercase() before entering the switch statement. That will guarantee that the player's choice is read in regardless of whether they type h or H (or s or S, as it may be).
I think your problem is probably in how Java handles it's System.out.print() and System.out.println() functions. It may be something to do with trying to continue your output stream with System.out.print() after it has closed the stream for that line if you used System.out.println() for your last output display (the part that tells the player their current hand)?
Unless you have a reason that you absolutely need to use .print(), I'd say just use .println() for it since you said that definitely works if you can't find a reason why .print() doesn't.
EDIT:
Maybe your issue is that .print() doesn't close the output stream, so it runs into an issue when immediately after when you try to open the input stream in what the machine sees as the middle of outputting?
You may need to flush the output to see it appear where you're hoping.
Try adding:
System.out.flush();
right after your System.out.print("Do you want to Hit or Stand?: ");
Your not showing any of the code that actually prints the statements before the print() line which is likely the code that is actually causing this issue.
Although, for your case you may need to consider calling
in.next() instead of in.nextLine() when using a print() statement instead of a println(). Thats just a guess since the other code is missing.
The code could also be optimized a lot better but, I am guessing this is some school assignment so it might not matter.

Java countdown print in same point of screen [duplicate]

I want to print a progress bar like so:
[# ] 1%
[## ] 10%
[########## ] 50%
But these should all be printed to the same line in the terminal instead of a new one.
What I mean by that is that each new line should replace the previous, it's not about using print() instead of println().
How can I do that in Java?
Format your string like so:
[# ] 1%\r
Note the \r character. It is the so-called carriage return that will move the cursor back to the beginning of the line.
Finally, make sure you use
System.out.print()
and not
System.out.println()
In Linux, there is different escape sequences for control terminal. For example, there is special escape sequence for erase whole line: \33[2K and for move cursor to previous line: \33[1A. So all you need is to print this every time you need to refresh the line. Here is the code which prints Line 1 (second variant):
System.out.println("Line 1 (first variant)");
System.out.print("\33[1A\33[2K");
System.out.println("Line 1 (second variant)");
There are codes for cursor navigation, clearing screen and so on.
I think there are some libraries which helps with it (ncurses?).
First, I'd like to apologize for bringing this question back up, but I felt that it could use another answer.
Derek Schultz is kind of correct. The '\b' character moves the printing cursor one character backwards, allowing you to overwrite the character that was printed there (it does not delete the entire line or even the character that was there unless you print new information on top). The following is an example of a progress bar using Java though it does not follow your format, it shows how to solve the core problem of overwriting characters (this has only been tested in Ubuntu 12.04 with Oracle's Java 7 on a 32-bit machine, but it should work on all Java systems):
public class BackSpaceCharacterTest
{
// the exception comes from the use of accessing the main thread
public static void main(String[] args) throws InterruptedException
{
/*
Notice the user of print as opposed to println:
the '\b' char cannot go over the new line char.
*/
System.out.print("Start[ ]");
System.out.flush(); // the flush method prints it to the screen
// 11 '\b' chars: 1 for the ']', the rest are for the spaces
System.out.print("\b\b\b\b\b\b\b\b\b\b\b");
System.out.flush();
Thread.sleep(500); // just to make it easy to see the changes
for(int i = 0; i < 10; i++)
{
System.out.print("."); //overwrites a space
System.out.flush();
Thread.sleep(100);
}
System.out.print("] Done\n"); //overwrites the ']' + adds chars
System.out.flush();
}
}
You could print the backspace character '\b' as many times as necessary to delete the line before printing the updated progress bar.
package org.surthi.tutorial.concurrency;
public class IncrementalPrintingSystem {
public static void main(String...args) {
new Thread(()-> {
int i = 0;
while(i++ < 100) {
System.out.print("[");
int j=0;
while(j++<i){
System.out.print("#");
}
while(j++<100){
System.out.print(" ");
}
System.out.print("] : "+ i+"%");
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("\r");
}
}).start();
}
}
One could simply use \r to keep everything in the same line while erasing what was previously on that line.
In kotlin
print()
The print statement prints everything inside it onto the screen.
The print statements internally call System.out.print.
println()
The println statement appends a newline at the end of the output.
You can just do
System.out.print("String");
Instead
System.out.println("String");

How do I format this text? java

So here's the problem. Turn a text file into the correct formatting.
The point of the problem is that I have to read a file, a text file, which contains code in that text file. The code in that has terrible formatting. The formatting issue is that when there is a curly brace like this {, the next line is not 4 spaces to the right, it's just all to the very left. Like this:
while (blah blah blah) {
sysout(blahblahblah);
When it should be this:
while (blah blah blah) {
sysout(blahblahblah);
And there's no other differences between the 2. The only rule is to simply make it so every time there is a curly brace like this {, to make sure the next line is 4 spaces to the right. And vice versa. So every time there's a curly brace like this }, the next line should be 4 spaces to the left. I hope you guys understand this.
This is my issue. I learned how to make a program where a piece of text with multiple spaces and lines is turned into a single line with a single space every time. Wasn't too hard.
For this, though, I have to keep everything on the same line. So if there's 30 lines, the new program I make is also 30 lines. I need to keep very similar spacing, but the simple difference is the whole brace thing. So basically, I just have to make the line after a brace either 4 spaces to the right, and then do the same so it is to the left 4 spaces if it's a } curly brace.
So how do I do this exactly? I don't know how to just fix that without messing up other things. It's such a simple thing I have to do; just make the lines following the braces 4 spaces to the right or left, but I just have no idea what syntax to use to accomplish this. Thanks!
EDIT: This might have just made it easier. So, basically, all lines either end with a right curly brace, a left curly brace, or a semi-colon. No matter what. So every time one of those pops up, it is the end of a line. So maybe if you know how that makes it easier, then I'm just letting you know.
There are programs that will do this for you automatically, so you don't need to reinvent the wheel. For instance, in Eclipse, type: ctrl-a (select all) ctrl-i (auto-indent).
Here's a pseudocode you can start with:
int indentLevel = 0;
while(currentchar = nextchar != null){
printCurrentChar
if(currentchar is '{'){
indentLevel++;
}else if(currentchar is '}'){
indentLevel--;
}else if(currentchar is '\n'){
print indentLevel * 4 spaces
}
}
you might need to deal with escaped braces and other complications though
You can do this pretty easily using regular expressions. If you do not know it and planning to be a programmer, then definitely learn it. It will save for you lots of time in future.
public class TextIndentator
{
public static void main(String[] args) throws IOException
{
File uglyText = new File("ugly.txt");
System.out.println((uglyText.exists() && !uglyText.isDirectory()) ? getNiceText(uglyText) : "FILE \"ugly.txt\" at " + System.getProperty("user.dir") + " do not exists");
}
static String getNiceText(File uglyText) throws IOException
{
// Opening file
FileInputStream inputStream = new FileInputStream(uglyText);
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(isr);
StringBuilder builder = new StringBuilder();
StringBuffer buffer = new StringBuffer();
// Algorithm starts here
String line;
boolean checkNext = false;
while ((line = reader.readLine()) != null)
{
if(checkNext)
{
// If previous line finished with '{' (And optionally with some whitespaces after it) then, replace any amount (including zero) of whitespaces with 4 witespaces
builder.append(line.replaceFirst("\\s*", " "));
}
else
{
builder.append(line);
}
// Check if line line finishes with { (And optionally with some whitespaces after it)
if(line.matches(".*\\{\\s*")) checkNext = true;
else checkNext = false;
//Append line separator at the end of line
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
}
}

Why cant my while-loop with system.in.read() get the last line in console?

Im stuck with a problem regarding System.in.read(). I want to print everything that is pasted into the console.
My code looks like this:
import java.io.IOException;
public class printer {
public static void main(String[ ] args) {
int i;
try {
while ((i = System.in.read()) != -1) {
char c = (char)i;
System.out.print(c);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
The problem is that if you paste ,for example, three lines into the console the program will then print the two first lines, but not the third. Why is that? It prints the third if i press enter but with a huge space between the second and the third line.
I've also tried to store every char in a string and then print the whole string after the loop, but the loop never ends. Is their a way to stop this specific loop (I will not know how many rows the user will paste)
Your app echoes any line you type (or paste) in the console. Problem is, consoles are a thing of the past, and they were supposed to do stuff line by line. This means your app only prints after having read the new line character, because System.in.read blocks.
The text you are pasting already includes two line breaks, but the last line lacks this delimiter. This is what you are posting, where <nl> means a line break:
line1<nl>line2<nl>line3
If you go to your fav text editor, paste there, add an additional line break at the end and copy all again with the "select all" menu, you'll see the last line.

How to Determine Indentation: Converting Java Source FIle to HTML File

I'm trying to programatically convert a Java source file into an HTML file using PrintWriter to write to a seperate .html file
Example source file may look like this.
HelloWorld.java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
while (true) {
System.out.println("Hello World!");
// Disregard this ridiculous example
}
}
}
All My printing works fine except I have a problem with indentation. Everyting is aligned left.
HelloWorld.html (as seen in browser):
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
while (true) {
System.out.println("Hello World!");
// Disregard this ridiculous example
}
}
}
Program Source Code Snippet: I want this program to determine for me, which line in the java source code should get indentation when it is being converted to HTML. I don't want to do it manually, because then I'd have to write a different program for every source file
PrintWriter output = new PrintWriter(newFile);
output.print("<!DOCTYPE html><html><head>"
+ "<style>"
+ ".keyword { font-weight: bold; color: blue}"
+ "</style></head><body>");
while (input.hasNextLine()) {
String line = input.nextLine();
String[] tokens = line.split(" ");
for (int i = 0; i < tokens.length; i++) {
if (keywordSet.contains(tokens[i])) {
// Gives Java keyword bold blue font
output.print("<span class=\"keyword\">");
output.print(tokens[i] + " ");
output.print("</span>");
} else {
output.print(tokens[i] + " ");
}
}
output.print("<br/>");
}
output.print("</body><html>");
output.close();
Note: The reason I split() each line is because certain keywords that may be in that line, are doing to be highlighted in the html file, which I do with a <span>, as noted in my code
In the program source code, I obviously don't have any indenting implementation, so I know why I don't have indentation in the html file. I really don't know how to go about implementing this.
How do I determine which line gets indentation, and how much indentation?
EDIT:
My Guess: Determine how much whitespace is in the line before splitting it, save the into a variable, then print those spaces in for form of &nbsp's before I print anything else in the line. But how do I determine how much whitespace is at the beginning of the line?
You can use a CSS class with white-space: pre or pre-line or pre-wrap.
You can wrap each line in a <p> with a calculated margin-left. It could be a multiple of 10px, for example. This would let you also change brace styles.
Basically, you'll have to keep a variable, indentLevel. Increment it for each { not in a string or a comment, and decrement it for each } not in a string or a comment. Indent each line, say 10px times the indent level. Test; do you want continuation lines indented more?
Use pre tag.
The tag defines preformatted text.
Text in a element is displayed in a fixed-width font (usually
Courier), and it preserves both spaces and line breaks.
You don't need to dermine which line needs to be indented because pre tag preserves ALL spaces, carriage returns and line feeds 'as-is' from the original HTML source code.
If you check the HTML that is rendered in StackOverflow in something marked as code you will see that it uses this tag.
Maybe it's better to first prepare String with your source code adding needed HTML, and replacing spaces with . This can be done with String.replace() method - iterate over you keywordSet and replace all keywords with its wrapped versions. Then you will able to write full string into your stream.
I figure out what I was trying to accomplish
...
int whiteSpace = 0;
while (whiteSpace < line.length() && Character.isWhitespace(line.charAt(j))) {
whiteSpace++;
}
String[] tokens = line.split(" ");
// Print white space
for (int i = 0; i < whiteSpace; i++) {
output.print("&nbsp");
}
...

Categories