I'm new to java so excuse me if this is commong knowldge but I have searched hard and couldn't find anything helpful, relevant or understandable(Which is odd considering I'm a C developer!).
My question is "How can I make java print a Unicode string in the windows shell ?". For simplicity say I have the hello world code in another language(ex: "سلام") and I want to display it in the shell (actually i want to get Unicode too, but first I have to figure this one out).
This works perfectly in Intellij IDEA without any extra lines of code!
System.out.println("سلام");
but doesn't work in shell.
I'm seriously disappointed, I migrated from C just to get a better deal with Unicode!
I used Intellij IDEA/Java 1.8 on Windows 10 and tried a bunch of things in a somewhat disorganized manner, but have it almost working. First, here's the code:
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class Java901App {
public static void main(String[] args) {
//System.out.println("Hello world!");
//System.out.println("سلام");
try{
PrintStream outStream = new PrintStream(System.out, true, "UTF-8");
outStream.println("Hello world!");
outStream.println("سلام");
} catch(UnsupportedEncodingException e){
System.out.println("Caught exception: " + e.getMessage());
}
}
}
Note that the encoding for the PrintStream is set to UTF-8. See the selected answer for this post: Chinese Characters Displayed as Questions Marks in Mac Terminal
I added Arabic Script Supplemental Fonts to Windows based on this article from Microsoft: Why does some text display with square boxes in some apps on Windows 10? I'm not sure whether this was essential, but it definitely did no harm. I uninstalled Arabic Script Supplemental Fonts and nothing changed so this step was not necessary.
Before running the app from the console I called chcp 65001. That was definitely essential even though the PrintStream was defined to use UTF-8, as shown in the screen shot below.
I tried setting different fonts for the Command Prompt window by clicking the icon in the top left of the window, selecting Defaults form the dropdown menu and then clicking the Fonts tab. Some worked (e.g. Consolas) and some didn't (e.g. MS Gothic). Note this comment from a SuperUser post: In order for chcp 65001 to work, you must be using a TrueType font in the command prompt.
Here's some sample output:
So it is working except that the characters in the text you provided are being rendered in reverse order. Does anyone know how to fix that, presumably by somehow specifying in the Java source that the text is for a right-to-left language?
Update:
I amended the code so that the Persian text is rendered correctly in the Command Prompt window, though a side effect is that it no longer renders correctly when the code is run within the IDE. Here's the revised code:
public static void main(String[] args) {
try{
StringBuilder persianHello = new StringBuilder("سلام");
PrintStream outStream = new PrintStream(System.out, true, "UTF-8");
outStream.println("Hello world!");
outStream.println(persianHello); // Renders backwards in console, but correctly in the IDE.
byte directionality = Character.getDirectionality(persianHello.charAt(0));
if (directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC) {
outStream.println("Reversed string:" + persianHello.reverse()); // Renders correctly in console, but backwards in the IDE...
}
} catch(UnsupportedEncodingException e){
System.out.println("Caught exception: " + e.getMessage());
}
}
And here's the Command Prompt output using that code:
This fix is a hack; what's really needed is code that will behave correctly regardless of whether it is run from the IDE or the Command Prompt.
Related
I try to write a console Card game with java. and I have to use these ♥ ♦ ♣ ♠ characters. But when I start the program on command prompt characters look like ? ? ? ? . I try Unicode and ASCII and I got the same results. I use intellij idea. and I can write these Ascii characters 217┘ 218┌ 191┐ 192└ 196─
I try to print them like
System.out.println("♥")
or
System.out.println(Character.toString('\u2661'))
Unicode characters \u2661 ... and so on.
ASCII 3 4 5 6
It works on Intellij Idea terminal.
when I try to write manually on command prompt alt+3, I can write ♥ but when starting the game it looks like ?
here a png of my default encoding.xml
here output of Inellij console
and here output of cmd console
───────────────────────────────────────────────
Edit:
try {
if (System.getProperty("os.name").contains("Windows")){
new ProcessBuilder("cmd", "/c", "chcp 65001").inheritIO().start().waitFor();
}
} catch (IOException | InterruptedException ex) {}
All you really needed to paste was System.out.println("♥"), the rest is irrelevant.
There isn't enough information in your question for a proper answer. I think it is one of these three:
[1] your file is in some charset encoding (say, UTF-8), but the javac run that makes the class file is configured with -encoding ISO-8859-1 or something else that isn't UTF-8. If you're letting intellij compile it for you I kinda doubt this is it.
[2] the console that you're running this in (the console view of intellij, perhaps), also has a charset encoding and it is not UTF_8.
[3] it's UTF-8 all the way down, but, the font used to render it doesn't have the symbol available to it. This is also unlikely; the usual way to render a missing character is a box, or a diamond with a question mark inside, not a plain ?. Or is that what you see?
Assuming you are trying to print using System.out, then try this:
import java.io.PrintStream;
import static java.nio.charset.StandardCharsets.UTF_8;
public class App {
public static void main(String[] args) {
System.out.println("First attempt: ♣");
PrintStream out = new PrintStream(System.out, true, UTF_8);
out.println("Second attempt: ♣");
}
}
In my environment, this prints the following output:
First attempt: ?
Second attempt: ♣
In some cases this may still not be sufficient, depending on how you are running your code. For example if you are running it inside NetBeans, then the following may need to be added to the Netbeans start-up options:
-Dfile.encoding=UTF-8
My intentions are to ask the user to write down some code in a TextArea, then see if that code compiles, and if it does, print out the results to another TextArea, which acts like a console.
Edit:Solving this via online compilers is the priority.
To accomplish this, I've tried using online compilers (i.e. compilerjava.net) and used the library HtmlUnit, but the library came in with a lot of errors, especially when reading the JavaScript code and returned me pages of 'warnings' that increase the compile & run time for about 20 seconds. I will leave the code below with explanations if anyone has intentions about trying to fix it.
I've also tried using the JavaCompiler interface, which did succeed in compiling, but under the conditions that I have provided the exact location of the .java file, which is something I have to create using the information I get from the TextArea. So again, a dead end.
I decided to come back to online compilers, since if I can manage to just return the data from the compiled program, I am set. The only issue is I haven't yet found an online compiler that allows a user to access its fields via Java code ( since its something too specific). I would appreciate any help on this if anyone can provide a way to send and retrieve data from an online compiler.
Here is the code using the HtmlUnit library, on the site 'compilerjava.net'. It is so close to working that the only 2 issues I have is that,
1) Run-time is too long.
2) I cannot access the console output of the code. Reasoning is that, when you hit 'compile', the output text-area's text turns into "executing". After a few seconds, it turns into the output of the code. When I try to access it, the data I retrieve is always "executing" and not the desired output. Here is the code;
public class Test {
public static void main(String[] args) {
try {
// Prevents the program to print thousands of warning codes.
java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);
java.util.logging.Logger.getLogger("org.apache.http").setLevel(java.util.logging.Level.OFF);
// Initializes the web client and yet again stops some warning codes.
WebClient webClient = new WebClient( BrowserVersion.CHROME);
webClient.getOptions().setThrowExceptionOnFailingStatusCode( false);
webClient.getOptions().setThrowExceptionOnScriptError( false);
webClient.getOptions().setJavaScriptEnabled( true);
webClient.getOptions().setCssEnabled( true);
// Gets the html page, which is the online compiler I'm using.
HtmlPage page = webClient.getPage("https://www.compilejava.net/");
// Succesfully finds the form which has the required buttons etc.
List<HtmlForm> forms = page.getForms();
HtmlForm form = forms.get( 0);
// Finds the textarea which will hold the code.
HtmlTextArea textArea = form.getTextAreaByName( "code");
// Finds the textarea which will hold the result of the compilation.
HtmlTextArea resultArea = page.getHtmlElementById( "execsout");
// Finds the compile button.
HtmlButtonInput button = form.getInputByName( "compile");
System.out.println( button.getValueAttribute());
// Simple code to run.
textArea.setText( "public class HelloWorld\n" +
"{\n" +
" // arguments are passed using the text field below this editor\n" +
" public static void main(String[] args)\n" +
" {\n" +
" System.out.print( \"Hello\");\n" +
" }\n" +
"}");
// Compiles.
button.click();
// Result of the compilation.
System.out.println( resultArea.getText());
} catch ( Exception e) {
e.printStackTrace();
}
}
}
As I said, this final code System.out.println( resultArea.getText()); prints out "executing", which implies that I have succeeded in pressing the compile button on the webpage via code.
So after this long wall of text, I'm either looking for a way to fix the code I presented, which is so darn close to my answer but not quite, or just an entirely different solution to the problem I presented at the beginning.
P.S. Maven is the last hope.
I am new to ExpectJ Java programming. I downloaded jar's and able to do few send() and expect() methods. send() would fire a command on console and expect() would identify any prompt's so inputs can be provided. Expect only reads is there are prompts, and not other info. For example, if want to fire, spawn.send("ls") and get list of all file names and so certain action, is that possible?.
Is there way so I can read normal output of spawn.send("ls") for example, without expect which only captures prompts?
You can indeed capture the output stream:
It is one of the methods of the ExpectJ.Spawn class
I am also very new to Java, but I got the output, however, I am still struggling on getting the prompt recognized as I get extra control characters from Unix so do not trust what comes after the second System.out.println (the sh,expect part)
the output works fine, just set it in a variable if you want, or if you use swing, send it to a textarea with a listener.
BTW! if you know how to do the expect without these bloody control characters, 1m,34 [001 and so on, I welcome your input
import expectj.ExpectJ;
import expectj.Spawn;
public class myExpectinator {
public myExpectinator(){
}
public void connect(){
try {
ExpectJ ex = new ExpectJ(10);
Spawn sh = ex.spawn("10.10.10.10", 22, "name", "password");
System.out.println(sh.getCurrentStandardOutContents());
System.out.println(sh.getCurrentStandardErrContents());
sh.expect("~ $");
sh.send("ps\n");
System.out.println(sh.getCurrentStandardOutContents());
//sh.expectClose();
sh.stop();
}
catch(Exception e) {
System.out.println(e);
}
}
}
I am trying to get the values of from the following xml, but the code i've written returns a bunch of question-marks instead of what it was supposed to return. I'm guessing it must be some encoding issue, but I haven't found anything about that yet on the web.
<channel>
<title>ΖΩΔΙΑ Προβλέψεις, 1 Σεπτεμβρίου 2012</title>
</channel>
zodiaClass.java
public class zodiaClass {
#Root(strict = false)
public static class Example {
#Path("channel")
#Element
private String title;
}
public static void main(String[] list) throws Exception {
Persister persister = new Persister();
File file = new File("example1/download.xml");
Example example = persister.read(Example.class, file);
System.out.println(example.title);
}
}
output:
????? ??????????, 1 ??????????? 2012
[As requested, this is a translation of the above comment thread into the form of an answer.]
I suspect that the issue is with the output, rather than with the input. Not all command-line environments support Greek. To test this, you can try System.out.println("\u03B1"); if your command-line supports Greek, it should show up as α (lowercase alpha).
In one of your comments, you mention that you're using Eclipse. If it does turn out that the problem is with the output, then a Google search for Eclipse console encoding suggests that there are a number of different approaches that people have tried successfully — everything from modifying the relevant Run Configuration within Eclipse to editing eclipse.ini and the system encoding.
Update: [not really an update, but I'm trying to maintain the illusion of a regular answer . . .] I see from your follow-up comment that you were able to change the console encoding by changing the encoding of the *.java file. Cool!
I need to translate my app, so i want to use gettext-common from http://code.google.com/p/gettext-commons
I checked out the svn and tried to compile the example:
javac -classpath ../java I18nExample.java
java -classpath ../../target/gettext-commons-0.9.6.jar:. I18nExample
The program does not give me the targeted output; I have absolutely no idea whats going on!
It seems that the de.properties is completly ignored. If I set the Properties file to "de" in the Factory's constructor, I get partly the output I want to see.
Is there anywhere in the internet a working example of gettext for java?
this is the output from the example script:
First run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
Second run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
There are a couple of issues, perhaps due to the build process.
First, for the message lookup to work, I needed to move the en and de resources into Messages_en.properties and Messages_de.properties in order to make a real resource bundle.
Second, the example code tries to use messages with no translations available, like the "file is open" stuff. Here's an updated version of what I tried; this all appears to work with the above modification:
public static void main(String[] args) {
I18n i18n = I18nFactory.getI18n(I18nExample.class, "Messages");
for (int i = 0; i < 2; i++) {
if (i == 0) {
print("First run");
} else {
print("Second run");
i18n.setLocale(Locale.GERMAN);
}
print("Current locale: " + i18n.getLocale());
print(i18n.tr("This text is marked for translation and is translated"));
String mark = i18n.marktr("This text is marked for translation but not translated");
print(mark);
print(i18n.tr(mark));
mark = i18n.tr("This is the {0}. text to be translated", "chat (noun)");
print(mark);
mark = i18n.tr("This is the {0}. text to be translated", "chat (verb)");
print(mark);
print(i18n.tr("chat (noun)"));
print(i18n.tr("chat (verb)"));
print("");
}
}
Note also that to insert translated words, you need something like this:
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (noun)")));
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (verb)")));
However, without un-banging (removing the ! and providing an English translation in Messages_en.properties, it shows up as chat (noun), which... strikes me as being almost useless.
The documentation is lacking on this aspect.