I made a console Othello game in C a while ago, so When I tried to make it in Java I wondered if system ("cls"); made in C could be done in Java, but I've had a lot of trouble, so I'll make a note here.
There seem to be several ways, There were a lot of confusing things like errors and warnings. Among them, I will introduce the one that was able to be implemented most smoothly this time.
This time, in making Othello I also wanted to consider extensibility when I wanted to control the output of the screen, so Create a ConsoleControl class that controls the output of the console screen It was implemented as a clearScreen method that clears the screen output.
Sorce Code ##
import java.io.IOException;
/**
*Class that controls the output of the console screen
*/
public class ConsoleControl {
/**
*Method to clear the output of the console screen
* @throws IOException
* @throws InterruptedException
*/
public void clearScreen() throws IOException, InterruptedException {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
}
For the time being, by calling the clearScreen method in the main method, I was able to clear the character string displayed at the command prompt.
I still couldn't understand why it would be "cls" if I wrote it like this because of my lack of knowledge. After studying and catching up with my understanding, I would like to add that amount.
2018/04/26 postscript When I visited after a long time, the number of views was close to 2000 views instead of 1000 views, so While swallowing it as a live broadcast material, I analyzed this program and investigated what kind of processing it was doing. Kusso, roughly smart.
First of all, regarding this ProccessBuilder class, if you look at the official explanation,
By saying "class for building an instance of Process class"
By creating an instance of this class, you can build an execution environment for a new process using external commands.
Looking at the contents with Open JDK SE8,
The command specified in the argument of the constructor is in the ProcessBuilder class
It was stored in a List
private List<String> command;
private File directory;
private Map<String,String> environment;
private boolean redirectErrorStream;
private Redirect[] redirects;
public ProcessBuilder(String... command) {
this.command = new ArrayList<>(command.length);
for (String arg : command)
this.command.add(arg);
}
This method was defined as follows: (Source quote from Open JDK)
public ProcessBuilder inheritIO() {
Arrays.fill(redirects(), Redirect.INHERIT);
return this;
}
This method just assigns the INHERIT flag to redirects using the Arrays.fill function. What does this INHERIT flag mean? The official description says:
This is the normal behavior of most operating system command interpreters (shells).
Also, the explanation about the inheritIO method is
Set the standard input / output source and output destination of the subprocess to be the same as the current Java process. This is a simple method. The following form of call pb.inheritIO() It behaves exactly the same as the next call. pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT) This behavior is equivalent to most operating system command interpreters and the standard C library function system ().
In other words, it turned out that the input / output of external programs can be integrated with the standard input / output of Java. See here for standard I / O. Well, at the end of the official explanation
This behavior is equivalent to most operating system command interpreters and standard C library functions system ().
If you think that it works the same as system (), you can explain the mandokusai by poi.
The source is long, so it is omitted. This method starts the command or executable file specified by ProcessBuilder. Somehow you can guess from the method name.
The source is (ry This method makes the thread currently being processed wait until the subprocess running in another thread ends.
I modified the previous source to do the following:
import java.io.IOException;
public class ConsoleControl {
private ProcessBuilder pb;
/**
*The constructor for the ConsoleControl class.
*Builds an environment to execute a new process that executes the specified command.
* @param command Command to execute
*/
public ConsoleControl(String... command) {
pb = new ProcessBuilder(command);
}
/**
*A method that clears the command prompt screen.
*/
public void cls() throws IOException, InterruptedException {
pb.inheritIO().start().waitFor();
/*
* //External command specified in the constructor argument of ProcesserBuild
* //Converted for execution at the command prompt
* ProcessBuilder pbInheritIO = pb.inheritIO();
* //Execute with external command
* Process pro = pbInheritIO.start();
* //Wait until the process running on another thread is finished
* pro.waitFor();
*/
}
}
var cc = new ConsoleControl("cmd", "/c", "cls");
var cc = new ConsoleControl("/bin/bash", "-c", "clear");
Is it like that? Perhaps the explanation is insufficient or misunderstood, so I would be grateful if you could point it out. Also, if you have free time, I'd be happy if you could come visit us for live broadcasting.
end.
Recommended Posts