How to compile and run some String entered in a TextArea? - java

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.

Related

Method with args inside an event handler with java

Okay, Hi guys. Currently I am taking an online course and for my final project i opted to do blackjack. Everything is running fine except for when a player needs to "hit" for another card. I have the code required for a hit within a method which uses args from a different method i created
public void Hitcardp1(int p1total, String p1scard1, String p1scard2){
int p1hitcard;
p1hitcard = (int)Math.ceil(Math.random()*10);
p1total = p1total + p1hitcard;
P1Area.setText("Card: " +p1scard1+ "\nCard: " +p1scard2+ "\nCard: +p1hitcard);
}
I need to put this in an event handler for when the hit button is clicked or interacted with. However it comes up with an error saying:
"Required int, string, string
I have tried putting the args within the event handler, however, it just creates a larger error.
I am relatively new to java and would really appreciate the help
There is not enough information about your handler and class.
Error comes because of missing args.
your method have to be run as:
Hitcardp1(p1total,p1scard1,p1scard2);
also, you have missed " in your code.
P1Area.setText("Card: " +p1scard1+ "\nCard: " +p1scard2+ "\nCard: "+p1hitcard);

In Rhino js, newlines don't get converted properly

I am experimenting with the Rhino java engine, which I want to embed in a project of mine. I made a Scriptable object scope which defines the global functions print, printLine, log, logLine in JavaScript. I can pull all data printed and logged by these functions by calling pullOutput, which returns a pair of all printed Output and logged Output. I have tested these functions and everything works as expected, but one thing.
When I give as argument for my log functions a new line, the string doesn't contain a new line char
but just "\n". For example the following code:
Context context;
try {
context = Context.enter();
TemplateScope scope = TemplateScope.init(context);
context.evaluateString(scope, "log(\"test\" + \"\\n\");", "test source", 1, null);
Pair<String, String> result = scope.pullOutput();
System.out.println("log is: " + result.b);
} finally {
Context.exit();
}
gives:
out is:
log is: test\n
Which is obviously not what I am expecting.
The complete code is here:
https://gist.github.com/4139978
Already fixed it. Another library overwrote my own rhino version with an old version and introduced this bug.

Using deployJava.runApplet to target specific element

After many years of successfully maintaining an applet that uses the good old:
<script src="foo.js"></script>
method of embedding a Java applet, we're unable to cover our ears and sing "La la la!" anymore.
It's time to be using:
deployJava.runApplet()
When I fire this method using a click handler (here using an event listener on a button via jQuery, but it doesn't matter):
$('#button').click(function() {
deployJava.runApplet(attributes, parameters, version);
});
...it wipes out the entire existing document and replaces it with the applet. All I need to know is how to target a specific DOM element to be the container for the applet, so that my page doesn't get wiped.
It seems like it would be an attribute I could pass in the form of target: someElement where "someElement" is either a DOM object or the element's ID as a string. But alas, I can't find documentation for such an attribute.
For the sake of being complete, here's what's being passed:
/*here is where I imagine there might be an applicable attribute */
var attributes = {
name: "SomeName",
code: "some.class",
archive: "some.jar",
width: 640,
height: 400
};
var parameters = {
someParameter: someValue
};
var version = "1.5";
I can document.write everything I need to rebuild a document, but I'm sure you can all well imagine how hideous that prospect seems to me.
Any pointers would be greatly appreciated.
As alternative to Christophe Roussy solution you may override document.write while running deployJava.runApplet.
Like so:
function docWriteWrapper(func) {
var writeTo = document.createElement('del'),
oldwrite = document.write,
content = '';
writeTo.id = "me";
document.write = function(text) {
content += text;
}
func();
writeTo.innerHTML += content;
document.write = oldwrite;
document.body.appendChild(writeTo);
}
An then:
docWriteWrapper(function () {
deployJava.runApplet(attributes, parameters, "1.6");
});
A little bit hackish but works like a charm;)
So the core of the problem is this: deployJava.js uses document.write. If you use this method AFTER page render (vs. as a part of the initial page render) it will first clear the document. Which has obvious negative repurcussions.
Although intended for JavaFX, people have reported success with dtjava.js, and I have every reason to believe it's a viable alternative.
However, other stakeholders on my team have already done work surrounding deployJava.js and are unwilling to throw away that work, which meant I needed to stick to deployJava.js. There's only one way to do this: make sure that deployJava is called during page render, not via Ajax, event, or other delayed trigger.
In the end, we are collecting our information, and passing it to a second page which will render the applet as expected. It works, and in most scenarios our clients will be doing this anyhow (collecting information, passing it server-side, and getting a redirect response), so it didn't make sense to force the issue. We are passing information via query string but you could probably use cookies and/or localstorage API instead, if you wanted the window.location to stay cleaner-looking.
Thanks for the replies, even though they were in the comment area. Other replies are still being taken on board if someone has a better way of doing it!
If you are using jQuery and want to target a specific dom element, rather than just appending:
function docWriteWrapper(jq, func) {
var oldwrite = document.write, content = '';
document.write = function(text) {
content += text;
}
func();
document.write = oldwrite;
jq.html(content);
}
docWriteWrapper($('#mydiv'), function () {
deployJava.runApplet(attributes, parameters, version);
});
To solve this annoying issue I downloaded and hacked deployJava.js at line 316, replaced the line by my own:
// document.write(n + "\n" + p + "\n" + r);
myDiv.append(n + "\n" + p + "\n" + r);
Where myDiv is a js global variable set to the desired div before calling runApplet:
myDiv = jQuery('#someDiv');
If you find a less intrusive solution let me know...

gettext-common example doesn't work

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.

J2ME converter program not accepting user's input

I am having problems with my converter program not accepting the value the user inputs. Everything seems so right but the result is always as if the user entered nothing. If anyone can just point me in the right direction I would greatly appreciate it!
my project consists of 2 files (1 midlet and 1 class).
code was too long to post on this forum so I uploaded the zip.
Edit hosted here now should be cleaner: removed
I can't really narrow it down to a small piece of code because it could be any number of things which I have already tried. I know its asking quite a bit but the code isn't insanely long. I'd be extremely grateful if anyone could take a look.
edit 2: the file seems to be trying to download an image... here is the code in another forum i posted in but got no answers.: http://www.codingforums.com/showthread.php?p=1024059#post1024059
edit 3: here is where I think the problem lies in the code:` public double customForm (String fName)
{
ui_form = new Form(fName);
ui_form.addCommand(Convert);
ui_form.addCommand(Back);
display.setCurrent(ui_form);
num = new TextField("Enter the number of units you would like to convert", "", MAX_CHARS, TextField.ANY);
ui_form.append(num);
ui_form.setCommandListener(this);
/***********************/
/* THIS IS NOT WORKING*/
// str = num.getString();
str = "The number is: " + num.getString();
try
{
numUnits = Double.parseDouble(str);
}
catch (NumberFormatException nfe)
{
}
finally
{
return numUnits;
}
//return str;
}
`
but you will probably need to look at the rest of the code to see where the problem lies. this is just the root i think
You cannot read the text field right after it has been added to a form. It looks like you assumed the num.getString() method to block until there's user input - this is not the case. User input is provided asynchronously, i.e. you should read the text field's content in response to a user command, somewhere in the commandAction() method (in your case when the Convert command has been issued by the user).
Handling user events asynchronously is a core pattern in GUI development. In this regard I recommend to read some example code for command handling in JavaME, for instance this or this.

Categories