I'm having some trouble writing a GUI in Java that can interact with Tcl scripts. When a Tcl script is run, I want information passed to this GUI and displayed. Further inputted information on the GUI should be able to be returned back to the script.
I'm currently using Tcl/Java. Unfortunately, I am using Teamcenter and according to the user manual, the Tk toolkit is not supported. So I'm trying to work with Swing again.
This is what I've tried to get to work for Swing, but nothing shows up when I run the script:
package require java
java::import javax.swing.JFrame
set window [java::new javax.swing.JFrame]
$window setSize 100 100
$window setVisible true
I've also found out about Swank, but there seems to be little documentation on it, so I'm not sure how to proceed.
Any advice on how to best approach this? Or where to find additional resources?
I'm not familiar with the Java libraries you mentioned, but judging from the
When a Tcl script is run, I want information passed to this GUI and displayed. Further inputted information on the GUI should be able to be returned back to the script.
statement your case is a perfect fit for IPC. I mean that I'd just start a Tcl program, connect your running Java and Tcl programs via some sort of IPC and then just do the exchange between them using an agreed-upon protocol.
The simplest cross-platform IPC might use TCP sockets: say, your Java application opens a socket on a random port listening on some loopback interface address and then passes the address of this socket to the Tcl application it spawns; the Tcl application then connects to that socket and both applications do exchange their commands and responses.
Another possibility is to communicate with the script using the standard IO channels of the Tcl shell hosting it — stdin and stdout: your Java host writes its commands to the spawned Tcl application's stdin and reads its output back from its stdout. This way is possibly simpler than a TCP socket but requires special handling on Windows (you have to run the script using tclsh, not wish as in the latter case it will have its standard channels connected to nowhere).
If you don't need cross-platform IPC and are okay to use external Tcl libraries, then you could communicate through platform-specific things like Unix-domain sockets, D-Bus, Windows named pipes (Unix named pipes can be used without extra packages), DDE etc.
Searching for background on what your problem might be, I found this thread on comp.lang.tcl which explains the problem. The issue is that you're not creating the GUI from the AWT Event Thread. To do that, you need to make a small Java class that implements Runnable (called Runner below) and which creates your GUI objects and shows them. This you can then instantiate and fire off through SwingUtilities.invokeLater via JTcl:
java::call javax.swing.SwingUtilities invokeLater [java::new Runner]
However, you're using JTcl which includes a package (hyde) that lets you put your Java code inside your Tcl code:
package require java
package require hyde
hyde::jclass Runner -package your.helper -implements Runnable {
public void run() {
your.Frame f = new your.Frame();
// ...
f.setVisible(true);
}
}
java::call javax.swing.SwingUtilities invokeLater [java::new your.helper.Runner]
It's just a shame that it isn't documented more clearly; it's easy to miss because it is located within the jtcllib documentation group.
Teamcenter doesn't support "external customizations".
I wrote the GUI in Java separately and ended up using Teamcenter's internal API to get the GUI to display.
Related
I am quite a beginner, any advice is much appreciated.
I have a linux application OpenBTS used to simulate and run a GSM network on a software defined radio device e.g USRP.
I want to build an application that interfaces with the OpenBTS command line on Linux. I want to give the user an easier way to configure and to display the current configurations of the application. The user would have an interface in which he could play with the configurations without the need to use the terminal.
I don't know if this is possible ?
Is it possible to interact with a Linux CLI through a GUI ? If yes what is the most efficient programming language, coding technique or approach to do that ?
Thanks a lot
You could generate a config file using your GUI and then use standard in to get the configuration into OpenBts. When launching OpenBts with the configuration file config.txt you could simply run it as follows.
./OpenBts < config.txt
You could also do this from you GUI by launching OpenBts in a process from your GUI application in a similar fashion, however this requires a fork() and exec()
In C++, you can take inputs from user through GUI then run appropriate openBTS commands using system()/popen(). Based on the return values of system()/popen(), can provide status of the operation back to the user.
Say we have a Java Swing application, swingapp, running in one JVM. Is it possible to control swingapp from a Java application running in another JVM/process, e.g. like this:
ControlApp.java
process = startSwingAppInAnotherProcess();
JFrame frame = getSwingAppJFrame();
frame.visible(false) // hide swingapps JFrame
doAllKindsOfThingsWithJFrame(frame)..
killSwingApp(process);
The use case is GUI testing, where I want a generic solution that can start/stop any Swing app in an external process to isolate it from the test runner completely, but it should still be able to control the app via Swing manipulation.
If possible, concrete examples would be very much appreciated.
I think there are platform-dependent ways to send UI events to GUI elements in the same desktop; however I would better think of some standard interprocess communication.
You can try to start your applications in a certain port range and just make them search for each sibling and communicate between them by sockets. Or you can start a kind of parent daemon process in which every child registers itself (by sockets again), and then the parent communicates state changes to its children (something like a distributed version of Subject-Observer pattern)
One could use somewhat "higher" level sockets - ZeroMQ for this.
Here are client and server implementations:
You could start with a server to implement jframe.hide API call.
Note: if you don't like native C transport implementation, then you could just switch to
pure java version without additional changes to your code.
From Java code, is there a way to maximize the window of a different GUI application? I have access to Process objects created for these other programs, as well as a semi-reliable way to get their PIDs and a generic String indicating the name of the process binary (e.g. "firefox").
I can also programmatically execute full bash shell statements (including commands connected with pipes), if there's some command-line way of going about it.
On MS Windows, I recall seeing somewhere about a Java library that wraps the win32 windowing API, allowing one to pass those Windows-specific signals to applications - would there be something similar to that on a Linux setup? This is for a Red Hat system, if that matters.
Not in a "standards-based" way, no.
The X-Windows system is independent of specific window managers, as such, there is no standard way to "maximize" a window. It ultimately depends on the features of the window manager in use...
My problem is pretty simple i have an application written in java and i want to send commands to it ex ( click a button , send some key strokes , click a menu item ) from my application witch i will write in delphi. Is this concept even possible ?
I actually had to do this at the last place I worked, you can get around it with complex window events etc... as mentioned above but if you have access to the Java source simply write other access methods either that call a specific runtime that closes (i.e. trigger a public static void main(String[] args); via a native call or via the command line.
OR
Implement simple a simple message system between Java/Delphi over TCP/IP and send either XML or some simple string mappings (I think it took about an hour to set up Maps that could pass back and forth).
In my case we were simply handling reporting and talking to the database so it was pretty easy to work around without getting into a native call. Alternatively, there is(was) a port of the JNI for Delphi that worked pretty well with Delphi 7. I have no clue what runtime you're using but it might be an option.
Honestly, the TCP/IP method is probably the easiest. It doesn't take a lot to implement, it doesn't eat a lot of resources and it allows you to execute "myMenuItem.onClick()" pretty easily as a packet, you just have to expose the methods.
http://home.pacifier.com/~mmead/jni/delphi/
Well It depends on which Java GUI technology is used . If SWT or AWT is used , you can get handle of UI components, because these two toolkit uses native libararies.. On the other hand, if that java application GUI is created by beans of SWING, you can not get any handle. Because, swing toolkit is implemented by pure Java..
If the Java app can be modified, the Java Robot API (included in JRE 1.3 and newer) might be helpful. This would allow to control a Swing application which does not provide windows handles as Gursel wrote. Obviously there would be some IPC required, which could be implemented using sockets for example.
The short: YES, but depending on the Java application, it might be difficult and unreliable.
I'm not a Java guy so I don't know if this is the norm, but the one Java application I had to automate displayed a single dialog that only used 1 (one) window handle! It was made up of several edit boxes, buttons, what looked like combo-boxes, but those were not true Windows controls but widgets re-created by whatever GUI toolkit the original developer used. I wasn't able to use normal Windows messages to manipulate those because, as far as Windows was concerned, it was a single window.
Happily the only thing I had to do was click a single button. I used mouse_event to move the mouse over the expected area for the button and then again to click the button. It works, but manipulating input this way is both unreliable and fragile.
To clarify Daniel Chapman and mjn comments, find below a code extract showing Delphi controlling a Java Swing UI component (TextField) contained in a Jframe based on NetBeans ClientEditor sample.
Please notice, that this example does not use the Java source code or use TCP, XML, Windowing events handling technics or IPC, it's just simply Delphi code calling some Java code.
procedure TForm1.Button1Click(Sender: TObject);
begin
FJFrame := Tjavax_swing_JFrame.Create('Client Editor');
FClientEditor := Tclienteditor_ClientEditor.Create;
FJFrame.GetContentPane().Add(FClientEditor);
FJFrame.Pack;
FJFrame.SetVisible(True);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// Delphi setting a value in a Java Swing UI component
FclientEditor.FirstNameTextField.SetText('Delphi 1stName');
end;
The long type names are just as a matter of clarity for this example and can be shorter of course.Additionally there is no problem with JNI in this example.
Have you had a look at Java for Delphi?
It let's you call Java from Delphi exposing the Java types as Delphi types.
How can i gain control on window based appliaction in java.
I am not asking like world or Excel.
I am asking for a window based application, suppose a media player(not specific window media player) any media player that is running on window.
How would you control the windows based application if you took Java out of the equation?
Does the program provide a COM interface? There are a number of Java-COM
bridges.
Does the program provide a plug-in API? You could write the DLL in C/C++, then either use JNI/JNA to interact with the DLL from Java, or use some kind-of interprocess communications layer.
Do you have have some view in the to low level Win32 message pump of the program? Then perhaps you could create native DLL to send messages via SendMessage on behalf of the java program.
It really depends on what you expect to do with the program, and what the program provides. There is no built-in functionality allowing one program to control another program, especially from Java.