last mod: 27-jan-08 sciss
A SwingOSC
object is the client-side representation of a java GUI server. A lot of the method names are closely modelled after the Server class (the client representation of scsynth), so it"s fairly easy to use.
SwingOSC is also the name of the java / OSC based GUI library. For an overview of GUI objects using SwingOSC, please read the help file SwingGUI.
There is always a default Server, which is stored in the class variable default
. Any GUI components created without a target will be created on the default server. At startup, a server representation referring to the local machine is created and stored both in the class variables local
and default
. When you boot SwingOSC manually from a terminal (see below), please note that this default server assumes SwingOSC to listen at TCP port 57111 and to send an initial ping message to sclang (127.0.0.1:57120). If the initial ping is not send, you will have to call initTree
manually.
Note that in this document we will assume that the global variable g
is assigned to the default server, by executing the following line:
g = SwingOSC.default; // !
Method signatures:
<aServer>.boot( <startAliveThread = true> ) <aServer>.quit
Examples:
g.boot;
// ...
g.quit;
Note: this assumes that the file "SwingOSC.jar" has been copied into the main SuperCollider folder. If you want to use a different install location, set the class variable program
appropriately:
SwingOSC.program = "<completePathToAndIncludingSwingOSC.jar>";
Here's for example, what my "~/scwork/startup.rtf" reads:
SwingOptions.default.javaOptions = SwingOptions.default.javaOptions + "-Xdock:icon=/Users/rutz/Documents/workspace/SwingOSC/application.icns"; SwingOSC.program = "/Users/rutz/Documents/workspace/SwingOSC/build/SwingOSC.jar"; g = SwingOSC.default;
If you want to use a specific java
program, you can set the class field java
, e.g. to force SwingOSC to boot with a Java 1.4 version on Mac OS X:
SwingOSC.java = "/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Commands/java";
You can register a custom function to be executed when the server has been booted. For example:
Method signature:
<aServer>.doWhenBooted( <func>, <timeout = 20> )
Example:
(
g.doWhenBooted({
JSCWindow.viewPalette;
});
g.boot;
)
Differences to the audio Server
: doWhenBooted
's second argument here is timeout in seconds.
Alternatively you can combine the two methods above:
Method signature:
<aServer>.waitForBoot( <func>, <timeout = 20> )
Example:
(
g.waitForBoot({
JSCWindow.viewPalette;
});
g.boot;
)
On Mac OS 10.3.9 (Panther), there is a known issue with unixCmd
s blocking each other, so to boot SwingOSC and scsynth
successively, you may need to call g.unblockPipe
after booting SwingOSC.
You can boot a SwingOSC server from within sclang with the boot method (see above). However sometimes you may wish to boot it from a terminal or by double clicking an executable shell script in the Finder. Please refer to the Document "readme.html" in the main SwingOSC folder to learn about launching the server from a terminal. You usually launch the server by the following command:
cd <mainSwingOSCFolder> java -jar build/SwingOSC.jar -t 57111 -i -L
Make sure to use TCP port 57111 and restrict OSC communication to the local machine (-L
option) when possible.
If you prefer to use UDP transport, use -u
instead of -t
.
To quit the server press Ctrl-C
in the terminal.
You might want to create another server instance because
To create a new server:
<aServer> = SwingOSC.new( <name>, <addr>, <options>, <clientID> );
The name
must be a unique Symbol (no two servers with the same name may exist). The addr
is a NetAddr object describing the server's socket (IP and port). The options
argument is an instance of SwingOptions. If several clients are sharing the same server, use a different clientID
Integer (default: 0
) for each, so their objectID-allocators won't interfere.
Important: If you don't specify options
, default options will be created. loopBack
is turned on (true
) if the supplied addr
argument uses the loopback-IP "127.0.0.1"
, otherwise it is off. Inversely, if you don't specify an addr
, an appropriate address will be created: if the option
's loopBack
flag is true
, the address will be NetAddr( "127.0.0.1", 57111 )
. If loopBack
is false
, the local computer's IP address will be determined (only working on Unix systems). Therefore, to use a server without loopback as default:
g = SwingOSC.new( \test, options: SwingOptions.new.loopBack_( false )); SwingOSC.default = g; g.boot;
Do not try to modify the loopBack
settings an already existing server.
Here is another example:
( f = SwingOSC.new( \secondSwing, NetAddr( "localhost", 44444 )); f.options.protocol = \udp; // if you don't want tcp f.waitForBoot({ var win; win = JSCWindow( server: f ); win.onClose = { f.quit; }; JSCStaticText( win.view, Rect( 40, 40, 100, 30 )).font_( JFont( "Helvetica", 36 )).string_( "Kieka" ); win.front; }); // use this on MacOS 10.3.9 Panther if booting blocks: // g.unblockPipe; )
Method signatures:
// send a single message <aServer>.sendMsg( <arg1>, [ <arg2> ... ]) // send a single message as array <aServer>.listSendMsg( <arrayOfArgs> ) // send a bundle <aServer>.sendBundle( <time>, <arrayOfArgs1>, [ <arrayOfArgs2> ... ]) // send an array of messages as a bundle <aServer>.listSendBundle( <time>, <arrayOfArraysOfArgs> )
Examples:
g.sendMsg( '/print', '[', '/local', \OS_Name, '[', '/method', 'java.lang.System', \getProperty, 'os.name', ']', ']'); g.listSendMsg([ '/print', '[', '/local', \OS_Version, '[', '/method', 'java.lang.System', \getProperty, 'os.version', ']', ']' ]);
Note: bundle times should always be set to nil
for now, since they are not used by SwingOSC. this behaviour may change in the future, so your code is safe if you use nil
.
To receive replies, you can set up either a normal OSCresponderNode
or an OSCpathResponder
. If, for some reason, the address argument doesn't work, use nil
instead. Example:
( OSCpathResponder( g.addr, [ '/info', \confirm ], { arg time, resp, msg; var choice, rgb; resp.remove; choice = msg[ 2 ]; ("User's choice : " ++ [ "Ok", nil, "Cancel" ].at( choice )).postln; if( choice == 0, { OSCresponderNode( g.addr, '/set', { arg time, resp, msg; if( msg[ 1 ].asSymbol === \color, { resp.remove; msg.postln; rgb = msg[ 3 ]; ("New colour : " ++ Color.new255( (rgb >> 16 & 0xFF), (rgb >> 8) & 0xFF, rgb & 0xFF )).postln; }); }).add; g.sendBundle( nil, [ '/local', \color, '[', '/method', \colorChooser, \getColor, ']' ], [ '/get', \color, \RGB ]); }); }).add; // note : showConfirmDialog is modal and will block OSC processing in SwingOSC // until the dialog is closed. this is just an example anyway g.sendBundle( nil, [ '/local', \colorChooser, '[', '/new', 'javax.swing.JColorChooser', ']' ], [ '/query', \confirm, '[', '/method', 'javax.swing.JOptionPane', \showConfirmDialog, '[', '/ref', \null, ']', '[', '/ref', \colorChooser, ']', "Select a colour", 2, ']' ]); )
The above example can be simplified by using the sendMsgSync
method. This must be called inside a Routine
as for example created by fork
:
Method signature:
// send a single message and wait for a success or failure reply
<aServer>.sendMsgSync( <msgArray>, <successMsgArray>, <failureMsgArray>, <timeout = 4>, <condition> )
Example:
( fork { var choice, rgb, msg; g.sendMsg( '/local', \colorChooser, '[', '/new', 'javax.swing.JColorChooser', ']' ); msg = g.sendMsgSync([ '/query', \confirm, '[', '/method', 'javax.swing.JOptionPane', \showConfirmDialog, '[', '/ref', \null, ']', '[', '/ref', \colorChooser, ']', "Select a colour", 2, ']' ], [ '/info', \confirm ], timeout: 60 ); if( msg.notNil, { choice = msg[ 2 ]; ("User's choice : " ++ [ "Ok", nil, "Cancel" ].at( choice )).postln; if( choice == 0, { g.sendMsg( '/local', \color, '[', '/method', \colorChooser, \getColor, ']' ); msg = g.sendMsgSync([ '/get', \color, \RGB ], [ '/set', \color, \RGB ]); if( msg.notNil, { rgb = msg[ 3 ]; ("New colour : " ++ Color.new255( (rgb >> 16 & 0xFF), (rgb >> 8) & 0xFF, rgb & 0xFF )).postln; }, { "Timeout!".warn; }); }); }, { "This takes way too long, i'm giving up".postln; }); }; )
Note: a timeout
of nil
means no timeout (waits forever).
Method signatures:
<aServer>.addClasses( <url1>, [ <url2> ... ]) <aServer>.removeClasses( <url1>, [ <url2> ... ]) <aServer>.updateClasses( <url1>, [ <url2> ... ])
Example: see "DynamicClasses.html" in examples for folder.
URLs can point to single class files, jar archives or folders containing class files. Make sure to use proper file://...
URLs and not plain path names for files!
The updateClasses
method can be used to dynamically develop java classes. It is a shorthand for removing and re-adding the URLs in order to use modified recompiled versions of java classes.
Method signatures:
SwingOSC.local; // reference to default local server SwingOSC.default; // reference to default local server; this will be used in GUI elements when no explicit server is specified SwingOSC.quitAll; // quit all registered servers ; UNTESTED SwingOSC.killAll; // query the system for any SwingOSC server apps and hard quit them ; UNTESTED