J/Link Example: A Button Palette

Code for the Palette example from section 1.3 of the J/Link User Guide.

This example demonstrates the use of the ShareFrontEnd function to allow Java interface elements interact with notebook windows in the same way that front end palettes can.

Because of current limitations with ShareFrontEnd, this example will not work with a remote kernel; the same machine must be running the kernel and the front end.

To try this example, evaluate all the initialization cells (you can do this with the menu command Kernel/Evaluation/Evaluate Initialization). Then go to the Example section.

Code

BeginPackage["PaletteDemo`", "JLink`"];

PaletteDemo;

Begin["`Private`"];

paletteButton[label_String, buttonFunc_String] :=
	JavaBlock[
		Module[{button, listener},
			button = JavaNew["java.awt.Button"];
			button@setLabel[label];
			(* Note that the button function callbacks are private to this package, so we need
			   to make sure that when they are called from Java their full names are used. Thus,
			   we prepend this package's Private` context to the names we send to Java.
			*)
			listener = JavaNew["com.wolfram.jlink.MathActionListener", "PaletteDemo`Private`" <> buttonFunc];
			button@addActionListener[listener];
			button
		]
	]

showPalette[buttons:{__?JavaObjectQ}] :=
	JavaBlock[
		Module[{frm, tok},
			frm = JavaNew["com.wolfram.jlink.MathFrame"];
			frm@setLayout[JavaNew["java.awt.GridLayout", 0, 1]];
			frm@add[#]& /@ buttons;
			ReleaseJavaObject[buttons];
			frm@pack[];
			tok = ShareFrontEnd[];
			(* We use the frame's onClose method to unregister the request for
			   front end sharing.
			*)
			frm@onClose["UnshareFrontEnd[" <> ToString[tok] <> "]"];
			JavaShow[frm];
		]
	]

printButtonFunc[event_, _] :=
	JavaBlock[
		NotebookApply[SelectedNotebook[], event@getSource[]@getLabel[]];
		(* We need to explicitly release the event object, since it was sent to
		   Mathematica before the JavaBlock was entered. *)
		ReleaseJavaObject[event]
	]

applyButtonFunc[event_, _] :=
	JavaBlock[
		With[{nb = SelectedNotebook[]},
			NotebookApply[nb, event@getSource[]@getLabel[], All];
			ReleaseJavaObject[event];
			SelectionEvaluate[nb]
		];
	]

plotButtonFunc[event_, _] :=
	(
		Plot[x,{x,0,1}];
		ReleaseJavaObject[event];
	)

printButtonFunc2[event_, _] :=
	JavaBlock[
		Print[event@getSource[]@getLabel[]];
		ReleaseJavaObject[event];
	]

PaletteDemo[] :=
	JavaBlock[
		Module[{btn1, btn2, btn3, btn4},
			InstallJava[];
			btn1 = paletteButton["insertMe", "printButtonFunc"];
			btn2 = paletteButton["Expand[\[SelectionPlaceholder]]", "applyButtonFunc"];
			btn3 = paletteButton["Create Plot", "plotButtonFunc"];
			btn4 = paletteButton["printMe", "printButtonFunc2"];
			showPalette[{btn1, btn2, btn3, btn4}]
		]
	]
	
End[];
EndPackage[];

Example

You should have called InstallJava prior to running this example.

PaletteDemo[]

Note that you can continue to use the front end normally while the palette window is visible and active.

When you are finished with the palette window, close it. This will shut down front end sharing and kernel sharing.