Question

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?

Was it helpful?

Solution 3

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top