I'm currently writing a program and I have this problem where I want to move the console's cursor to a specific location on the screen.
I quickly found out that this isn't possible in java so I wrote a C# script that would do this for me, but I only can run program in a separate process.
Is there a way to solve this?
Also I'm trying not to use any extra libraries like jline.
Here are some code snippets:
C#
using System;
namespace setCursor
{
public class program
{
static void Main(string[] args)
{
int x = Convert.ToInt16(args[0]);
int y = Convert.ToInt16(args[1]);
Console.SetCursorPosition(x ,y);
}
}
}
java
try
{
ProcessBuilder pb = new ProcessBuilder("setCursor", "0", "0");
Process p = pb.start();
p.waitFor();
for(int i = 0; i < 30; i++)
{
for(int j = 0; j < 120; j++)
{
Thread.sleep(1);
System.out.print(ContentOnTheScreen[i][j]);
}
}
}
catch (Exception e)
{
System.out.println(e);
}
Windows Terminal / console in recent version of Windows supports ANSI / VT codes so you could achieve movement of character position with System.out.print if your terminal is compatible. You will be able to tell by running this:
public class SetCursor {
private static String CSI = "\u001b[";
private static String at(int row, int col) {
return CSI+row+";"+col+"H";
}
public static void main(String[] args) throws InterruptedException {
System.out.println("HELLO");
System.out.print(at(1,1) + "ABCD");
System.out.print(at(10,5) + "EFGH");
System.out.println("WORLD");
for (int i = 0; i <= 100; i++) {
System.out.print(at(30,20) + " Progress: "+i+"%");
Thread.sleep(100);
}
}
}
It will either print the different values around the screen (running from a Windows Terminal Command Prompt), or if VT codes not supported (such as when running via IDE) the output might look strange:
HELLO
[1;1HABCD[10;5HEFGHWORLD
...
Related
I am able to launch Process with the help of below command and after launching multiple processes I want to control how many processes I want to keep at some point.
For example:
Initiate a Process inside a for loop of range 0 to 50
Pause the for loop once total active processes are 5
Resume for loop once it drop from 5 to 4 or 3 ...
I tried below code, but I am missing something.
public class OpenTerminal {
public static void main(String[] args) throws Exception {
int counter = 0;
for (int i = 0; i < 50; i++) {
while (counter < 5) {
if (runTheProc().isAlive()) {
counter = counter + 1;
}else if(!runTheProc().isAlive()) {
counter = counter-1;
}
}
}
}
private static Process runTheProc() throws Exception {
return Runtime.getRuntime().exec("cmd /c start cmd.exe /c \"dir && ping localhost\"");
}
}
Also, how to find out how many process are active? So that I can control active processes at a time.
You can use thread pool with fixed size.
For example:
public static void main(String[] args) throws Exception {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 50; i++) {
threadPool.submit(runTheProc);
}
}
private static final Runnable runTheProc = () -> {
Process process;
try {
process = Runtime.getRuntime().exec("cmd /c start cmd.exe /c \"dir && ping localhost\"");
} catch (Exception e) {
throw new RuntimeException(e);
}
while (process.isAlive()) { }
};
I got the code below from a sample code from tutorials point and tweaked it a little bit.
App.java
public static void main(String[] args) throws ParseException {
CommandTest t = new CommandTest();
t.start(args);
}
CommandTest.java
public class CommandTest {
void start(String[] args) throws ParseException {
//***Definition Stage***
// create Options object
Options options = new Options();
// add option "-a"
options.addOption(
Option.builder("a")
.longOpt("add")
.desc("add numbers")
.hasArg(false)
.valueSeparator('=')
.required(false)
.build()
);
// add option "-m"
options.addOption("m", false, "");
options.addOption(
Option.builder("m")
.longOpt("multiply")
.desc("multiply numbers")
.hasArg(false)
.valueSeparator('=')
.required(false)
.build()
);
//***Parsing Stage***
//Create a parser
CommandLineParser parser = new DefaultParser();
//parse the options passed as command line arguments
CommandLine cmd = parser.parse( options, args);
//***Interrogation Stage***
//hasOptions checks if option is present or not
if(cmd.hasOption("a")) {
System.out.println("Sum of the numbers: " + getSum(args));
} else if(cmd.hasOption("m")) {
System.out.println("Multiplication of the numbers: " + getMultiplication(args));
}
}
public static int getSum(String[] args) {
int sum = 0;
for(int i = 1; i < args.length ; i++) {
sum += Integer.parseInt(args[i]);
}
return sum;
}
public static int getMultiplication(String[] args) {
int multiplication = 1;
for(int i = 1; i < args.length ; i++) {
multiplication *= Integer.parseInt(args[i]);
}
return multiplication;
}
}
Now, my question is that, when i try to execute the above code with a parameter of -multi it will still be accepted? I've already set the options to receive only either -m or -multiply. However, it will still accept -multi
I am using commons-cli-1.3.1 (im trying to debug a legacy code by the way)
Note: Above source is a SAMPLE source only, no need to apply actual coding guidelines (good or bad) i just want to know why the behavior happens as it is.
This is the behaviour when a non-matching option gets found (org.apache.commons.cli.Options:233):
public List<String> getMatchingOptions(String opt) {
opt = Util.stripLeadingHyphens(opt);
List<String> matchingOpts = new ArrayList();
if (this.longOpts.keySet().contains(opt)) {
return Collections.singletonList(opt);
} else {
Iterator var3 = this.longOpts.keySet().iterator();
while(var3.hasNext()) {
String longOpt = (String)var3.next();
/******************************************************/
/* longOpt = "multiply" */
/* opt = "multi" */
/******************************************************/
if (longOpt.startsWith(opt)) {
matchingOpts.add(longOpt);
}
/******************************************************/
}
return matchingOpts;
}
}
As you can see in the highlighted block, if a short option isn't matched the library searches for the first long option that partially matches the entered option. It uses startsWith, and since "multiply".startsWith("multi") is true it defaults to option --multiply.
I'm trying to make visual novel game but i'm stuck with text animation
I tried to make it on console application for example so help me with making it on libgdx.
here's my sample code
public class TestC {
private static String message = "help me with textanimation";
public static void main(String[] args) {
for (int i = 0; i < message.length(); i++) {
System.out.print(message.charAt(i));
try {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Thanks in advance
Why don't you try to make it work with LibGDX and then ask help? It goes basicaly the same except instead of letting the program sleep you have to count time passed.
final float letterSpawnTime = .2f;
float timer = 0;
String completeText = "The complete text."
String drawText = "";
int stringIndex = 0;
public void update(float delta) {
timer += delta;
if (timer >= letterSpawnTime) {
drawText = drawText + completeText.charAt(stringIndex);
stringIndex++;
timer -= letterSpawnTime;
}
font.draw(someFont, drawText, x, y, etc...);
}
Something like that (written out of my head). To be a bit more efficient initialize the StringBuilder in the constructor once and just keep appending a single character to it instead of creating a new StringBuilder instance each time the you need to append a letter.
I am programing a midi maker that you can make a song through the console (and later a window) but I'm having a thread issue. When I want the song to start, the thread starts but it doesn't run the function that has the song player. I copy and pasted the base code from a working project and I cant figure out why it is not running. IT prints "setting up" but not "running". Here is my code for the function:
public void songStart() throws InterruptedException {
int temp;
channelVolume = new int[channelNotes.length][channelNotes[0].length];
if (channelNotes.length < userChannels.length) {
temp = channelNotes.length;
} else {
temp = userChannels.length;
}
for (int j = 0; j < userChannelNotesNumLongest; j++) {
for (int i = 0; i < temp; i++) {
if (channelNotes[i][j] == r) {
channelVolume[i][j] = 0;
} else if (advanced == false){
channelVolume[i][j]=50;
}
}
}
System.out.println("running");
for (int i = 0; i < temp; i++) {
for (int j = 0; j < userChannelNotesNumLongest; j++) {
noteOn(userChannels[i],channelNotes[i][j],channelVolume[i][j]);
Thread.sleep(interval);
noteOff(userChannels[i],channelNotes[i][j]);
}
}
}
And this is the code for the thread:
public class SongThread extends Thread {
public void run(){
try {
Main.song.songStart();
} catch (InterruptedException e) { }
}
}
Here is were the code runs the thread (i have a print in there that does print)
if (userInput.equals("start")) {
System.out.println("setting up");
SongThread thread = new SongThread();
thread.start();
}
Note: everything works fine until the thread tries to run the function, then it just stops running it. Also, it is the same base code in the other project that works fine. The function that is displayed is in a class instance in Main called song. And I don't get an error from the catch. Keep in mind that I copy and pasted the code from a working project and the only thing different is that it is not static and runs the instance from the Main class
I have tried making the songStart function static with everything inside as well. I have used all the combinations of try / catch an d throws exceptions in the thread and the function (where the thread didn't have a try / catch or throws and where the function has a try / catch or a throws). the way I have it in my working project is a throws in the function and a try / catch in the thread.
I have a console application in which I would like to put a non-deterministic progress bar on the command line while some heavy computations are done. Currently I simply print out a '.' for each iteration in a while loop similar to the following:
while (continueWork){
doLotsOfWork();
System.out.print('.');
}
which works but I was wondering if anyone had a better/cleverer idea since this can get to be a little bit annoying if there are many iterations through the loop.
Here an example to show a rotating progress bar and the traditional style :
import java.io.*;
public class ConsoleProgressBar {
public static void main(String[] argv) throws Exception{
System.out.println("Rotating progress bar");
ProgressBarRotating pb1 = new ProgressBarRotating();
pb1.start();
int j = 0;
for (int x =0 ; x < 2000 ; x++){
// do some activities
FileWriter fw = new FileWriter("c:/temp/x.out", true);
fw.write(j++);
fw.close();
}
pb1.showProgress = false;
System.out.println("\nDone " + j);
System.out.println("Traditional progress bar");
ProgressBarTraditional pb2 = new ProgressBarTraditional();
pb2.start();
j = 0;
for (int x =0 ; x < 2000 ; x++){
// do some activities
FileWriter fw = new FileWriter("c:/temp/x.out", true);
fw.write(j++);
fw.close();
}
pb2.showProgress = false;
System.out.println("\nDone " + j);
}
}
class ProgressBarRotating extends Thread {
boolean showProgress = true;
public void run() {
String anim= "|/-\\";
int x = 0;
while (showProgress) {
System.out.print("\r Processing " + anim.charAt(x++ % anim.length()));
try { Thread.sleep(100); }
catch (Exception e) {};
}
}
}
class ProgressBarTraditional extends Thread {
boolean showProgress = true;
public void run() {
String anim = "=====================";
int x = 0;
while (showProgress) {
System.out.print("\r Processing "
+ anim.substring(0, x++ % anim.length())
+ " ");
try { Thread.sleep(100); }
catch (Exception e) {};
}
}
}
Try using a carriage return, \r.
In GUI applications the approach is generally a spinning circle or bouncing/cycling progress bar. I remember many console applications using slashes, pipe and hyphen to create a spinning animation:
\ | / -
You could also use a bouncing character in brackets:
[-----*-----]
Of course, as the other answered mentioned, you want to use return to return to the start of the line, then print the progress, overwriting the existing output.
Edit: Many cooler options mentioned by Will in the comments:
Cooler ASCII Spinners?
If you know how much work you have to do and how much is left (or done), you might consider printing out a percent complete bar graph sort of progress bar. Depending on the scope of this project, this could simply be in ascii or you could also consider using graphics.