Detecting and acting on keyboard direction keys in Java - java

G'day all,
I have a console project where it is intended the user presses the keyboard direction keys (non-numeric keypad) to move an avatar. I am having difficulty coding to check for the press of these keys. In Pascal it was easy enough to use "readkey" and code, for example, for #80 for the down keypress. However, I am stumped how to implement the same functionality in Java, though I think I understand the use of System.in and BufferedInputStream.
Could anyone help me out? Your thoughts or hints are much appreciated.

If java.io.console doesn't work for you (I haven't tried that), try JLine. I used it to solve a vaguely similar problem.

The Console support issue in Java is well known, I am not sure that this is doable.
This was not initially possible with System.in since it used to work line-based.
Sun eventually added a java.io.Console class.
Here are its JavaDocs:
http://java.sun.com/javase/6/docs/api/java/io/Console.html
Once you get the console (I think from System.console), you can get a reader and perhaps read characters from it, but I'm not sure if it includes keys.
Generally, you're supposed to use Swing or AWT if you want access to the keyboard, which is silly.
As of 2007, there was a feature request about it: here

Unfortunately this is not possible in a portable way:
http://forums.sun.com/thread.jspa?threadID=5351637&messageID=10526512
On Windows, reading from System.in will block until enter is pressed, even when you do not use a BufferedReader. Arrows will cycle through the command history. Try it yourself:
import java.io.*;
public class KeyTest {
public static void main(String[] argv) {
try {
InputStreamReader unbuffered = new InputStreamReader(System.in);
for (int i = 0; i < 10; ++i) {
int x = unbuffered.read();
System.out.println(String.format("%08x", x));
}
} catch (Exception e) {
System.err.println(e);
}
}
}
Same issue using the Console class (input buffered under Windows, arrow keys intepreted by Windows):
import java.io.*;
public class KeyTest2 {
public static void main(String[] argv) {
try {
Console cons = System.console();
if (cons != null) {
Reader unbuffered = cons.reader();
for (int i = 0; i < 10; ++i ) {
int x = unbuffered.read();
System.out.println(String.format("%08x", x));
}
}
} catch (Exception e) {
System.err.println(e);
}
}
}

Not with built-in Java code. Check out java curses libraries or JLine as mentioned above, if you want to continue.

Related

Java Loop InputStream until boolean = false

I have this input stream that checks if I have a certain CAD file open or not. I am doing this by using an input stream to run a tasklist command with the name I want to check. I currently have a boolean that returns true if the specific CAD file isn't open. If the CAD file is open, it returns false. However, I want it to be able to loop this until the CAD file is open because as of right now I have to keep running it in order for it to work. I also need to be able to check this boolean from a separate class. I have it in my main right now so i could test it. My code looks like this...
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
String notOpen = "INFO: No tasks are running which match the specified criteria";
StringBuilder textBuilder = new StringBuilder();
String command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
int i;
InputStream myStream = Runtime.getRuntime().exec(command).getInputStream();
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
String output = textBuilder.toString();
boolean logical = output.contains(notOpen);
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
}
}
My other class is going to have an 'if statement' that checks whether my boolean "logical" is false, and if so, print something. I have tried every possible method I could think of, but I cannot get it to function the way I want it to. Every other thing I found involving looping an inputstream didn't really apply to my situation. So hopefully someone can help me out in achieving what I want to do.
I would start by moving everything out of main and into a different class. This will make retrieving values and calling specific functions easier. Then create an object of that class in main. Once that is done, I'd create a get method for the boolean variable. Now to focus on the loop. Once the object is created in main, create a conditional loop inside of main which calls the function you need until a different condition is met. This condition might be met once the file is open. After the condition is met, it exits to another loop that relies on another conditional, such as user input.
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
AutoCadFile file = new AutoCadFile();
//loop 1
//Some conditional so the program will
//continue to run after the file has been found.
// while(){
//loop 2
//check to see if the file is open or not
//while(logical){
//}
//}
}
}
Other class
import java.io.IOException;
import java.io.InputStream;
public class AutoCadFile {
private String notOpen;
private StringBuilder textBuilder;
private String command;
private int i;
private InputStream myStream;
private String output;
private boolean logical;
public AutoCadFile() {
notOpen = "INFO: No tasks are running which match the specified criteria";
textBuilder = new StringBuilder();
command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
output = textBuilder.toString();
logical = output.contains(notOpen);
try {
myStream = Runtime.getRuntime().exec(command).getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void checkForFileOpen() {
try {
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean getFileBoolean() {
return logical;
}
}
My other class is going to have an if statement that checks whether my boolean logical is false ...
Well, logical is a local variable within a method. So no code in another class is going to be able to see it.
There are two common approaches to this kind of thing:
Make the variable (i.e. logical) a field of the relevant class. (Preferably NOT a static field because that leads to other problems.)
Put your code into a method that returns the value you are assigning to logical as a result.
From a design perspective the second approach is preferable ... because it reduces coupling relative to the first. But if your application is tiny, that hardly matters.
I can see a couple of other significant problems with your code.
When you use exec(String), you are relying on the exec method to split the command string into a command name and arguments. Unfortunately, exec does not understand the (OS / shell / whatever specific) rules for quoting, etcetera in commands. So it will make a mess of your quoted string. You need to do the splitting yourself; i.e something like this:
String[] command = new String{} {
"tasklist",
"/fi",
"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]"
};
Your code potentially leaks an input stream. You should use a "try with resource" to avoid that; e.g.
try (InputStream myStream = Runtime.getRuntime().exec(command).getInputStream()) {
// do stuff
} // the stream is closed automatically ... always

Beginner Q: how to open a file in Java and keep it open

This is just for a simple command-line standalone program in Java.
I'd like to open a file to write to, and keep it open. I need to write formatted floats/doubles to it, in human-readable ASCII, like a CSV file.
I have tried various approaches (1) (2) (3) I have found through my favorite search engine, and they have the form:
try {
// some file handle opening sequence
}
catch ( <some exception> ) {
// do something
}
finally {
// do something else
}
(...or in the case of the third example, the file opening/writing/closing is inside a function that throws an exception.) I realize it's good programming style to make sure that you've opened a file ok, but for my purposes that's really not necessary.
Anyway the problem with the above approach is that outside of the try{} block, the filehandle is closed. I'd like to keep it open, because the kernel of my code consists of a huge loop that I go through a few 100,000 times (say), and each time through I'd like to output a single float (in ASCII) to the file.
With the above form, the only way to do that is to enclose my huge for loop inside the try{} block. Which seems silly. Alternatively, I could re-open the file every time through the loop, but that means additional logic, opening the file as a 'new' file the first time, and appending in all subsequent times.
Is there some way to open the file, keep it open to write to it occasionally, and then close it when I'm done?
Something like:
{
// open file "data.out"
}
for (i=0;i<100000;i++) {
// do a lot of stuff
//
// calculate some quantity "x"
//
// output float "x" in ASCII form, appending it to data.out
}
{
// close data.out
}
Does Java allow that? Thanks.
Of course you can simple store your FileWriter somewhere, as any other variable. You can, for example, encapsulate the whole writing logic in its own class, which offers one write method for your specified format.
But why does it seem silly? Perhaps this approach might help...
public void methodA(File myFile) throws IOException{
try ( FileWriter writer = new FileWriter( myFile ) ) {
writeTo(writer);
}
}
private void writeTo(FileWriter writer) throws IOException {
for (i=0;i<100000;i++) {
// do a lot of stuff
//
// calculate some quantity "x"
//
// output float "x" in ASCII form, appending it to data.out
}
}
This way, one method takes care of the opening/closing/exceptions, while the other method can concentrate on the important writing stuff, using the FileWriter given to it.
as you said the file is closed at the end of the try block. Possibly
the FileWriter object is created inside the try block:
(You did not post a real java code, only a pseudo code.)
Example, hope this helps
public static void main(String[] args)
{
...
BufferedWriter ofs=null; // should by outside the try block
try
{
Path logfile = Paths.set("C:\\temp\\log.log");
ofs = Files.newBufferedWriter(logfile); // new in java 8
YourWorker.doYourJob(ofs);
} catch (Exception e)
{ e.printStackTrace();
} finally
{
if (ofs!=null) { try { ofs.close(); } catch (Exception e) {} }
}
System.exit(1);
} //---------- end of main()
} //---- end of class

from c# to java, how to swap method of 'Serializer.TryReadLengthPrefix'

I'm trying to render the following method into java from c#.
some components are easily recognizable, for instance (please correct me if I'm wrong but) it seems that:
C#: Java
Console.WriteLine = System.out.println
Some components are more opake. Such as using, I guess that has no equivalent in java, isn't it? So I'm thinking I'll just ignore it, is that prudent?
A little background before we go on, I'm trying to decode a google protocol buffer .pb file.
Serializer.TryReadLengthPrefix(file, PrefixStyle.Base128, out len) is doubtless tricky as well, but it's the whole crux of the program, so it's important.
I'm reasonably certain that in place of that I should use something like this:
while ((r = Relation.parseDelimitedFrom(is)) != null) {
RelationAndMentions relation = new RelationAndMentions(
r.getRelType(), r.getSourceGuid(), r.getDestGuid());
labelCountHisto.incrementCount(relation.posLabels.size());
relTypes.addAll(relation.posLabels);
relations.add(relation);
for(int i = 0; i < r.getMentionCount(); i ++) {
DocumentProtos.Relation.RelationMentionRef mention = r.getMention(i);
// String s = mention.getSentence();
relation.mentions.add(new Mention(mention.getFeatureList()));
}
for(String l: relation.posLabels) {
addKnownRelation(relation.arg1, relation.arg2, l, knownRelationsPerEntity);
}
}
But that's an unwieldy beast and I'm not sure exactly what to do with it.
I've been at this too long and my capacity to think clearly is totally disipated but if one among you who is expert in c# and java feels up to this momentus undertaking, far be it from me to stop you.
static void ProcessFile(string path)
{
try
{
Console.WriteLine("Processing: {0}", path);
using (var file = File.OpenRead(path))
{
int len, count = 0;
while(Serializer.TryReadLengthPrefix(file, PrefixStyle.Base128, out len))
{
Console.WriteLine("Fragment: {0} bytes", len);
using (var reader = new ProtoReader(file, null, null, len))
{
ProcessRelation(reader);
count++;
}
}
Console.WriteLine("{0}, {1} Relation objects parsed", path, count);
Console.Error.WriteLine("{0}, {1} Relation objects parsed", path, count);
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
finally
{
Console.WriteLine();
}
}
if you're feeling particularly ambitious please do dig the who code here.
Can you pls. elaborate more on
I'm trying to decode a google protocol buffer .pb file.
Usually you have protobuf definition file.. Google protobuff, auto-generates "code" file based on this "def" file. Generally there is no point in decoding that file...
you generate the C# code file using definition.pb/proto by calling protoc.exe
again you generate the code file in Java using same definition.pb/proto and by same calling protoc.exe ( same command switch will be different)
and you can communicate across both language.. you dont have to map/find equivalent.. hopefully I answered your q..
if you have further q. post your .pb/proto file (definition not data)
if you don't have the definition file.. let us know.. we can than may be able to take further steps.

How to distinguish the mode (Java/JS/Android) the Processing sketch runs?

I write a multiplatform logic game, that will have to work in all modes: Java, JS and Android. I need to do some things different in all modes (especially, but not limited to, storage, for Java/Android I want to use load/saveTable and for JS - localStorage).
To do that I need to get the information, which is the mode the sketch runs. And I need to do this in runtime, just to avoid keeping different source for all platforms.
I was looking in the docs but found nothing in the topic. My Google research also led me to thoughts, that nobody even asked for that...
I was thinking about using try/catch to check some functions that exist in Java but not in JS, but this seems to be rather unelegant and whatismore I can not find the propper way for that.
What I have found is:
try {
PApplet a;
a = new PApplet();
mode = "JAVA";
}
catch(Throwable e) {
mode = "JS";
}
This distinguishes Java and JavaScript, but can not recognize Android...
So to summarize - what's the best way to distinguish, whether I run the sketch in JS or Java mode on runtime?
Ok, I have found quite nice way with try/catch:
String mode;
mode = "unknown";
try {
java.lang.Object a;
a = new java.lang.Object();
mode = "JAVA";
}
catch(Throwable e) {
mode = "JS";
}
This distinguishes JavaScript from the Java/Android but can not distinguish Android from Java. But since the differences are minimal this not causes significant problems with compatibility to me.
If someone knows the way to do this better - please post your answer!
I figured out how to detect Java vs. Android mode. Kind-of a hack:
import java.lang.reflect.*;
Method getInternalProcessingMethod(String methodName) {
/*
* Helper method that can be used to return
* an internal processing method by name
*/
Class cls = this.getClass();
try {
return cls.getMethod(methodName);
} catch (Exception e) {
return null;
}
}
boolean isAndroidMode() {
/*
* Determine if we're running in Android mode or not
*/
// What?
// In Android mode 'displayDensity' is a field and in Java
// mode 'displayDensity' is a method. This is a hack...but
// it works.
if (getInternalProcessingMethod("displayDensity") == null) {
return true;
}
return false;
}
And then you can use this to do something like what I use it for:
void settings() {
IS_ANDROID_MODE = isAndroidMode();
if (IS_ANDROID_MODE) {
println("Android mode detected");
fullScreen();
SAVE_LOCATION = "blah.json";
} else {
println("Java mode detected");
size(600, 1233);
SAVE_LOCATION = "data/blah.json";
}
}
Now I can have my test app run on my desktop in a small window but then run fullscreen with a different save file path on Android.

Does Java have a using statement?

Does Java have a using statement that can be used when opening a session in hibernate?
In C# it is something like:
using (var session = new Session())
{
}
So the object goes out of scope and closes automatically.
Java 7 introduced Automatic Resource Block Management which brings this feature to the Java platform. Prior versions of Java didn't have anything resembling using.
As an example, you can use any variable implementing java.lang.AutoCloseable in the following way:
try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
...
}
Java's java.io.Closeable interface, implemented by streams, automagically extends AutoCloseable, so you can already use streams in a try block the same way you would use them in a C# using block. This is equivalent to C#'s using.
As of version 5.0, Hibernate Sessions implement AutoCloseable and can be auto-closed in ARM blocks. In previous versions of Hibernate Session did not implement AutoCloseable. So you'll need to be on Hibernate >= 5.0 in order to use this feature.
Before Java 7, there was no such feature in Java (for Java 7 and up see Asaph's answer regarding ARM).
You needed to do it manually and it was a pain:
AwesomeClass hooray = null;
try {
hooray = new AwesomeClass();
// Great code
} finally {
if (hooray!=null) {
hooray.close();
}
}
And that's just the code when neither // Great code nor hooray.close() can throw any exceptions.
If you really only want to limit the scope of a variable, then a simple code block does the job:
{
AwesomeClass hooray = new AwesomeClass();
// Great code
}
But that's probably not what you meant.
Since Java 7 it does: http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec
The syntax for the code in the question would be:
try (Session session = new Session())
{
// do stuff
}
Note that Session needs to implement AutoClosable or one of its (many) sub-interfaces.
Technically:
DisposableObject d = null;
try {
d = new DisposableObject();
}
finally {
if (d != null) {
d.Dispose();
}
}
The closest java equivalent is
AwesomeClass hooray = new AwesomeClass();
try{
// Great code
} finally {
hooray.dispose(); // or .close(), etc.
}
As of now, no.
However there is a proposal of ARM for Java 7.
If you're interested in resource management, Project Lombok offers the #Cleanup annotation. Taken directly from their site:
You can use #Cleanup to ensure a given
resource is automatically cleaned up
before the code execution path exits
your current scope. You do this by
annotating any local variable
declaration with the #Cleanup
annotation like so:
#Cleanup InputStream in = new FileInputStream("some/file");
As a
result, at the end of the scope you're
in, in.close() is called. This call is
guaranteed to run by way of a
try/finally construct. Look at the
example below to see how this works.
If the type of object you'd like to
cleanup does not have a close()
method, but some other no-argument
method, you can specify the name of
this method like so:
#Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
By default, the cleanup method is presumed to be
close(). A cleanup method that takes
argument cannot be called via
#Cleanup.
Vanilla Java
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
With Lombok
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
#Cleanup InputStream in = new FileInputStream(args[0]);
#Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
No, Java has no using statement equivalent.
In java 8 you can use try. Please refer to following page. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Please see this List of Java Keywords.
The using keyword is unfortunately not part of the list.
And there is also no equivalence of the C# using keyword through any other keyword as for now in Java.
To imitate such "using" behaviour, you will have to use a try...catch...finally block, where you would dispose of the resources within finally.
ARM blocks, from project coin will be in Java 7. This is feature is intended to bring similar functionality to Java as the .Net using syntax.
To answer the question regarding limiting scope of a variable, instead of talking about automatically closing/disposing variables.
In Java you can define closed, anonymous scopes using curly brackets. It's extremely simple.
{
AwesomeClass hooray = new AwesomeClass()
// Great code
}
The variable hooray is only available in this scope, and not outside it.
This can be useful if you have repeating variables which are only temporary.
For example, each with index. Just like the item variable is closed over the for loop (i.e., is only available inside it), the index variable is closed over the anonymous scope.
// first loop
{
Integer index = -1;
for (Object item : things) {index += 1;
// ... item, index
}
}
// second loop
{
Integer index = -1;
for (Object item : stuff) {index += 1;
// ... item, index
}
}
I also use this sometimes if you don't have a for loop to provide variable scope, but you want to use generic variable names.
{
User user = new User();
user.setId(0);
user.setName("Andy Green");
user.setEmail("andygreen#gmail.com");
users.add(user);
}
{
User user = new User();
user.setId(1);
user.setName("Rachel Blue");
user.setEmail("rachelblue#gmail.com");
users.add(user);
}

Categories