Creating a JavaFX proxy causes a UnsupportedOperationException - javafx

I'm trying to write a JavaFX app in Clojure. As a simple test, I wanted to try to just launch a Hello World. To extend Application, I decided to try using proxy instead of :gen-class. I wanted to be able to create a bare-bones function that creates an Application, instead of requiring me to write the boilerplate every time.
The simple example I came up with was:
(let [^Application app
(proxy [Application] []
(start [self stage] (println "Hello World")))]
(Application/launch ^Class (.getClass app)
(into-array String [])))
The problem is, this causes an UnsupportedOperationException:
UnsupportedOperationException start chat.graphics_tests.javafx_wrapper.proxy$javafx.application.Application$ff19274a.start (:-1)
It seems like it can't find the start method that I implemented. My first thought was that the arguments to start were wrong. They seem correct though. The first argument it receives is "this", then the primary stage. I tried different numbers of arguments though, and I still get the same error. According to the docs:
If a method fn is not provided for an interface method, an
UnsupportedOperationException will be thrown should it be
called.
Which further my this suspicion.
The errors quite vague. Does anyone see what the problem is?

When writing proxy class definitions in Clojure you do not need the explicit self parameter in the method signature. The current instance will be implicitly bound to this which you will be able to use inside the methods.
Therefore your proxy call should look like this:
(proxy [Application] []
(start [stage] (println "Hello World")))

This appears to be because Application/launch requires a named class, which proxy doesn't create. (see the comment at the bottom of the answer. I'm trusting #Sam here).
I ended up caving and using :gen-class, and got it working after some fiddling.

Related

How do you get code to execute at the end of a procedure?

I'm working on a new piece of code at work to assist the rest of the programmers in making app server calls. Previously we just had a .i file and relied on the developer to make sure you made all the right calls and cleaned up the app server connection at the end of the program. Obviously some people have forgotten to do that in the past and it's caused problems for us.
I've been building a basic appserver.cls file, but I can't figure out how to get it to disconnect at the end of the program.
I've tried the following things so far.
ON CLOSE OF THIS-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't seem to fire at the end of the webspeed call.
DESTRUCTOR appserver():
cleanupAppServer().
END DESTRUCTOR.
This works when it does garbage collection, but Progress doesn't seem to do garbage collection at the end of a webspeed call and the objects are still in memory (which is an entirely different issue that I need to deal with).
ON CLOSE OF SESSION:LAST-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't even compile obviously.
I've tried a whole bunch of other things that are variants on these three to no avail.
Is there any way to do what I'm asking? Bonus points if it can be inside the appserver.cls file.
If I understand the question, you want to disconnect from another AppServer once the work is done. Would try something along the lines of the below work?
Create a AppServer-handle-wrapper class. This class is responsible for the A/S connection; it has a public "Handle" (or similarly-named) property that you can use to run stuff on the AppServer.
In this class' destructor you can add code that does your clean-up : disconnect and delete server handle .
Code that wants to run something on the AppServer does something like ...
def var asConn as AppServerConnection.
asConn = new AppServerConnection().
run foo.p on asConn:Handle (param1, out param2).
// cause GC
asConn = ?.
// manually destroy
delete object asConn.
The destructor will then do the right thing.
Note that if you have this code in an internal procedure or method, then the variable would go out of scope at the end of it, and the GC would kick in.
There's an example of this approach at https://github.com/consultingwerk/ADE-Sourcecode/blob/566ac0a6e085d6305a8f364f13a1d805d3597d2a/src/netlib/OpenEdge/Net/ServerConnection/ClientSocket.cls
Bear in mind that in the ClientSocket is that the handle is private - you may want to make it public for a general AppServer connection.

How to implement early stopping as an extension

As this thread, we can stop iteration loop by setting function (f:trainer -> bool) as Trainer's stop_triger.
But in this way, I think we can't use other extension such as LogReport which use stop_trigger=((args.epoch, '10')).
So, my question is how to implement early stopping as the Extension and how to send a signal to stop trainer's iteration from Extension.
thanks.
I implemented the example code on gist,
and updated the answer on the original thread.
I noticed that stop_trigger originally uses tuple notation like (args.epoch, '10'), instead we need to change to pass a callable object (EarlyStoppingTrigger in above example).

Clojure, JavaFX Eventhandler not in namespace

i'm trying to make a EventHandler for my FXML based View in my Clojure Projekt.
As described here: http://drowsy.de/blog/?p=7 i added in the FXML this
onAction="(use 'ui.listener) (add-tolist-listener event)"
to a button.
But when i launch the application i get following error message:
LoadException Error resolving onAction='(use 'ui.listener)
(add-tolist-listener event)', either the event handler is not in
the Namespace or there is an error in the script.
In ui.listener is the eventhandler
(defn add-tolist-listener [event]
(println "I'm a Button"))
Any idea why this doesn't work?
I tried it with this notation
onAction = #add-tolist-listener
and it didn't worked too.
Thanks!
I am completely unfamiliar with JavaFX, however:
onAction="(use 'ui.listener) (add-tolist-listener event)"
This looks like Java code, so having Clojure syntax in here doesn't seem like it would work? I suspect you would have to call your Clojure code using Java?
Going off "Calling Clojure code from Java".
You would have to try something like:
ui.listener.add_tolist_listener
You might also find this blog post gives you another idea to try: Invoking Clojure code from Java.
Now is set up the action in my start function via
(.setOnAction (.lookup root "#startCalculationBtn")
(proxy [EventHandler] []
(handle [^ActionEvent event]
(start-calculation))
)
)
And it works.

Access python function from javascript in QWebView

I am writing a Python/PyQt4 application that generates and displays a page in a QWebView widget. The page includes javascript code that I would like to be able to call functions returning data from the python application.
So far I can call functions that do not return data (using the pyqtSlot decorator), and call functions that do take parameters by exposing them as properties (using the pyqtProperty decorator). What I haven't worked out how to do is to call a python function with parameters, that returns data.
The question 9615194 explains how to do this from C++, but I cannot see how to transfer this to PyQt4.
I suspect you're not using the result= keyword to specify the return value in your pyqtSlot decorator?
#pyqtSlot(str, result=str)
def echo(self, phrase):
return self.parent().echo(phrase)
I ran afoul of this myself recently. No errors are generated if you omit result=, the method just silently returns nothing. Pretty maddening 'til I figured it out. See my answer to this question for a worked example.

Flex/Flash: capture 'trace' in code?

In Flash/Flex, is it possible to capture the result of 'trace' in code?
So, for example, if one part of the code calls trace("foo"), I'd like to automatically capture the string "foo" and pass it to some other function.
Edit: I'm not interested in trying to use trace instead of a proper logging framework… I want to write a plugin for FlexUnit, so when a test fails it can say something like: "Test blah failed. Here is the output: ... traced text ...".
Edit 2: I only want to capture the results of trace. Or, in other words, even though my code uses a proper logging framework, I want to handle gracefully code that's still using trace for logging.
As far as I know it's impossible to do it externally, google brings up no results. Have you considered creating a variable for the output and then adding that to the log, eg:
var outputtext = "text";
trace(outputtext);
// log outputtext here
Disregard if it isn't feasible, but I can't think of any other way.
However you can do it internally, if it's just for development purposes: http://broadcast.artificialcolors.com/index.php?c=1&more=1&pb=1&tb=1&title=logging_flash_trace_output_to_a_text_fil
If you want to write traces to a log, you can just use the Debug version of Flash Player and tell it to log traces.
I have a Debug.write method that sends the passed messages over a LocalConnection which I use that instead of trace. My requirement is to be able to capture the debug statements even when the SWF is running out of the authoring environment, but you can use this method to capture the trace messages.
As far as I understood you don't want to use logging, which is of course the right way to do it.
So, you can simply create a Static class with method trace, and call this method from anywhere in the application, that's how you will get all traces to one place, then could do what ever you want with the trace string before printing it to console.
Another way is to create bubbling trace event and dispatch it whenever you want to trace message, then add listener to STAGE for it and catch all events...
Hope its help
I would suggest looking through the source for the swiz framework. They use the flex internal logLogger app-wide and use best practices in a good majority of their code.

Resources