(************** Content-type: application/mathematica ************** CreatedBy='Mathematica 5.1' Mathematica-Compatible Notebook This notebook can be used with any Mathematica-compatible application, such as Mathematica, MathReader or Publicon. The data for the notebook starts with the line containing stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info@wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. *******************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 20792, 510]*) (*NotebookOutlinePosition[ 21606, 539]*) (* CellTagsIndexPosition[ 21562, 535]*) (*WindowFrame->Normal*) Notebook[{ Cell[CellGroupData[{ Cell["Some notes on the GUIKit", "Title", TextAlignment->Center, TextJustification->0], Cell[CellGroupData[{ Cell["Introduction", "Section"], Cell[TextData[{ "The GUIKit is a recent addition to ", StyleBox["Mathematica ", FontSlant->"Italic"], "- supplied as part of the software at version 5.1 - which uses J/Link to \ add a Graphical User Interface (GUI) to ", StyleBox["Mathematica", FontSlant->"Italic"], " applications. For what follows it is important to use Version 1.0.2 (or \ better) of GUIKit. To determine which version you have, load the GUIKit and \ execute:" }], "Text"], Cell[BoxData[ \(GUIKit`Information`$Version\)], "Input"], Cell[TextData[{ " If necessary, the latest version can be downloaded from the ", ButtonBox["GUIKit online site", ButtonData:>{ URL[ "http://www.wolfram.com/solutions/mathlink/guikit/"], None}, ButtonStyle->"Hyperlink"], "." }], "Text"], Cell[TextData[{ "Although the documentation for the latest version is reasonably complete, \ and it is possible to use it to create some impressive interfaces, I do not \ find it as easy to use as I would like. These notes and program fragments are \ designed to augment the documentation - not replace it. If you wish to use \ any of the (free) functions defined here, I suggest you click above to \ download the notebook version of this page. Feedback and suggestions \ regarding this page will be extremely welcome. If you use the Super Widget \ Package, please ensure that the copyright notice remains intact if you pass \ it on.\n\n", StyleBox["Please note", FontVariations->{"Underline"->True}], " that the implied criticism of the GUIKit design may reflect my lack of \ understanding of this rather new ", StyleBox["Mathematica", FontSlant->"Italic"], " technology, and that GUIKit is, in any case, an interesting and usable \ extension to ", StyleBox["Mathematica", FontSlant->"Italic"], "." }], "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Relationship to J/Link", "Section"], Cell[TextData[{ "The GUIKit is built upon J/Link - the package that links ", StyleBox["Mathematica", FontSlant->"Italic"], " to Java. Although J/Link is extremely powerful, GUIKit inherits two \ serious problems from J/Link:\n\[FilledSmallCircle] Java runs as a separate \ process. This means that if you position a Java (i.e. J/Link) window over a \ notebook, and click on the notebook, you will conceal the window \[Dash] even \ though the user is expected to respond to the window. This can give the \ appearance of a hung program.\n\[FilledSmallCircle] ", StyleBox["Mathematica", FontSlant->"Italic"], " graphics can be rendered in a Java window, but if a mouse-listener is \ attached, the {x,y} coordinates returned are unrelated to the graphical \ coordinate system. See the Interactive Graphics Package for a solution to \ this problem for J/Link applications. Here you will see how to solve this \ problem for the GUIKit \[Dash] which can result in some ", StyleBox["great", FontVariations->{"Underline"->True}], " applications!" }], "Text"] }, Open ]], Cell[CellGroupData[{ Cell[TextData[{ "GUIKit and ", StyleBox["Mathematica", FontSlant->"Italic"], " Contexts" }], "Section"], Cell[TextData[{ "Using the GUIKit, a window definition typically consists of a nested \ sequence of Widget calls, in which each Widget defines some element of the \ window \[Dash] such as a portion of text, an image, button, slider, etc. \ \[Dash] or, indeed, the window (the \"Frame\" widget) that is used to wrap up \ all these elements. Each Widget comes with many options, and can include \ sections of ", StyleBox["Mathematica", FontSlant->"Italic"], " code inside Script blocks. This code is meant to execute in specific \ situations \[Dash] such as when a mouse button is pressed \[Dash] and \ provides the feedback from the GUIKit window to the rest of your ", StyleBox["Mathematica", FontSlant->"Italic"], " code." }], "Text"], Cell["\<\ Unfortunately, a Widget definition can be stored and used more than once. \ This would typically be the case for a fairly low-level widget \[Dash] such \ as (say) some kind of enhanced text box \[Dash] it is not likely to be a \ problem for the average GUIKit user. However, the GUIKit design solved this \ problem in a very draconian way. All the symbols belonging to the Global` \ context in a script are moved into a private context, and the $ContextPath is \ stripped bare while the script is being executed! In addition, certain GUIKit \ functions, such as PropertyValue, actually spawn private versions of \ themselves which are installed in the private script context and are not \ equivalent to their public siblings! Because of all this overkill, some \ careful programming is required to use GUIKit in many applications \[Dash] \ use the option IncludedScriptContexts -> {$Context} on GUIRun and GUIRunModal \ unless you find these context manipulations useful..\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["A simple GUIKit definition", "Section"], Cell["\<\ Here is a function which displays a message in a box with \"OK\" and \"Cancel\ \" options. It returns a code to indicate which button was pressed:\ \>", "Text"], Cell[BoxData[ \(\(Needs["\"];\)\)], "Input", CellLabel->"In[1]:="], Cell[BoxData[ RowBox[{ StyleBox[\(AskOK[s_String, title_String]\), FontColor->GrayLevel[0]], StyleBox[":=", ShowContents->True], RowBox[{ StyleBox["Module", ShowContents->True, FontColor->RGBColor[1, 0, 0]], StyleBox["[", FontColor->GrayLevel[0]], StyleBox[ RowBox[{ RowBox[{"{", RowBox[{"ans", StyleBox["=", ShowContents->True, FontColor->RGBColor[1, 0, 0]], "0"}], "}"}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"GUIRunModal", "[", "\[IndentingNewLine]", RowBox[{ RowBox[{"Widget", "[", RowBox[{"\"\\"", ",", RowBox[{"{", "\[IndentingNewLine]", RowBox[{\("\" \[Rule] title\), ",", "\[IndentingNewLine]", \("\" \[Rule] False\), ",", "\[IndentingNewLine]", \(WidgetSpace[5]\), ",", "\[IndentingNewLine]", \({WidgetFill[], WidgetSpace[20], Widget["\", {"\" \[Rule] s, "\" \[Rule] Widget["\", InitialArguments \[Rule] {"\", PropertyValue[{"\", "\"}], 18}]}], WidgetFill[], WidgetSpace[20]}\), ",", "\[IndentingNewLine]", \(WidgetSpace[5]\), ",", "\[IndentingNewLine]", RowBox[{"{", "\[IndentingNewLine]", RowBox[{\(WidgetFill[]\), ",", RowBox[{"Widget", "[", RowBox[{"\"\\"", ",", RowBox[{"{", RowBox[{\("\" \[Rule] "\"\), ",", "\[IndentingNewLine]", RowBox[{"BindEvent", "[", RowBox[{"\"\\"", ",", RowBox[{ "Script", "[", " ", "\[IndentingNewLine]", RowBox[{ RowBox[{"ans", StyleBox["=", ShowContents->True, FontColor->RGBColor[1, 0, 0]], "1"}], ";", "\[IndentingNewLine]", \ \(CloseGUIObject[GUIObject[]]\)}], "\[IndentingNewLine]", "]"}]}], "]"}]}], "\[IndentingNewLine]", "}"}]}], "]"}], ",", "\[IndentingNewLine]", \(WidgetSpace[5]\), ",", "\[IndentingNewLine]", RowBox[{"Widget", "[", RowBox[{"\"\\"", ",", RowBox[{"{", RowBox[{\("\" \[Rule] "\"\ \), ",", "\[IndentingNewLine]", RowBox[{"BindEvent", "[", RowBox[{"\"\\"", ",", RowBox[{ "Script", "[", " ", "\[IndentingNewLine]", RowBox[{ RowBox[{"ans", StyleBox["=", ShowContents->True, FontColor->RGBColor[1, 0, 0]], "2"}], ";", "\[IndentingNewLine]", \ \(CloseGUIObject[GUIObject[]]\)}], "\[IndentingNewLine]", "]"}]}], "]"}]}], "\[IndentingNewLine]", "}"}]}], "]"}], ",", "\[IndentingNewLine]", \(WidgetFill[]\)}], "\[IndentingNewLine]", "}"}], ",", "\[IndentingNewLine]", \(WidgetSpace[5]\)}], "\[IndentingNewLine]", "}"}]}], "]"}], ",", "\[IndentingNewLine]", \(IncludedScriptContexts \[Rule] \ {$Context}\)}], "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", "ans"}]}], FontColor->GrayLevel[0]], StyleBox["\[IndentingNewLine]", FontColor->GrayLevel[0]], StyleBox["]", FontColor->GrayLevel[0]]}]}]], "Program", CellLabel->"In[13]:="], Cell["This tests the function:", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(AskOK["\", "\"]\)], "Input",\ CellLabel->"In[14]:="], Cell[BoxData[ \(1\)], "Output", CellLabel->"Out[14]="] }, Open ]], Cell["\<\ As you can see, this definition is rather complicated to perform such a \ simple task! Part of the problem is that few of the defaults in GUIKit seem \ to be ideal here. GUIKit's defaults seem to be the basic Java defaults, which \ are often not very useful. Thus, the \"Label\" widget seems to produce text \ which is a little too small, also the default layout is not spaced out at \ all, and you have to make special provision to cause the buttons to directly \ close the box and return a result.\ \>", "Text"], Cell["\<\ Note the use of WidgetSpace to create vertical space above and below the text \ and buttons, and horizontal space between the two buttons. WidgetFill before \ and after the two button widgets causes them to become centered.\ \>", "Text"], Cell["\<\ Several of the options (such as \"Resizable\") that are used in the above \ example, are not documented. You can get a list of methods, events, and \ properties using the following function:\ \>", "Text"], Cell[BoxData[ \(GUIDetails[s_String] := Module[{ref}, \[IndentingNewLine]ref = GUILoad[Widget[s, Name -> "\"]]; Widget["\", {"\" \[Rule] 50, "\" \[Rule] 60}]\[IndentingNewLine]ans = GUIInformation[ref, "\"]\[IndentingNewLine]]\)], "Input", CellLabel->"In[15]:="], Cell["\<\ This call should work for any named Widget, although you may get an error \ message if the widget in question requires arguments. Note that most of the \ names returned in this way are of a very general nature and not generally \ useful. You may want to extract the list and use complement it with another \ type of widget to isolate the really relevant information. Except where the \ names enable you to guess how to use the information, it is necessary to use \ Java documentation to understand this completely.\ \>", "Text"], Cell[CellGroupData[{ Cell[BoxData[ \(GUIDetails["\"] // Short\)], "Input", CellLabel->"In[4]:="], Cell[BoxData[ TagBox[\({"MethodNames" \[Rule] {"Action", "Add", "AddActionListener", \[LeftSkeleton]324\[RightSkeleton], "ViewToModel", "Wait", "Write"}, \[LeftSkeleton]1\[RightSkeleton], "PropertyNames" \[Rule] {\[LeftSkeleton]1\[RightSkeleton]}}\), Short]], "Output", CellLabel->"Out[4]//Short="] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell["Window - what window?", "Section"], Cell[TextData[{ "Return now to the AskOK function and activate it. Now click on this \ notebook (moving it if necessary) and observe how the GUIKit window, which is \ running as a separate process, is concealed. The result can be intensely \ confusing for an end user, who will probably conclude that your program has \ hung! To avoid this problem, you may wish to conceal all the ", StyleBox["Mathematica", FontSlant->"Italic"], " notebooks while a GUIKit window is open. Notice that this function stores \ the list of notebooks that it has hidden and only makes those notebooks \ visible again afterwards. This is because various packages, such as J/Link, \ use hidden notebooks as part of their operation. It is obviously important \ that these are not made visible as a side-effect of the operation." }], "Text"], Cell[BoxData[{ \(\(concealed\[Breve]notebooks = {};\)\), "\[IndentingNewLine]", \(ConcealNotebooks[opt_] := If[opt, \[IndentingNewLine]concealed\[Breve]notebooks = Select[Notebooks[], \(Options[#, Visible]\)[\([1, 2]\)] &]; \[IndentingNewLine]Scan[ SetOptions[#, Visible \[Rule] False] &, concealed\[Breve]notebooks], \ \[IndentingNewLine]\[IndentingNewLine]Scan[ SetOptions[#, Visible \[Rule] True] &, concealed\[Breve]notebooks]; \ \[IndentingNewLine]concealed\[Breve]notebooks = {};\[IndentingNewLine]]\)}], \ "Input", CellLabel->"In[1]:="], Cell[TextData[{ "GUI programmers refer to modal and modeless windows. The above window is \ termed a 'modal' window because the program enters a different 'mode' while \ the window is being displayed. Modeless windows (displayed using GUIRun) are \ more like the palette windows (actually tiny notebooks) that open when you \ start a newly installed ", StyleBox["Mathematica", FontSlant->"Italic"], ". It is normal for windows of this kind to get covered up \[Dash] since \ the program does not enter a different mode for the time while they are \ visible. " }], "Text"], Cell["\<\ Observe that if you are contemplating a large GUI application, it is \ important to think early on about the relationship between your GUI windows \ and the existing notebook interface. If you want to interact with your user \ via a modal window, will he or she need to refer to information in a notebook \ in order to respond?\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Using textfields", "Section"], Cell["\<\ Here is an example of a \"TextField\" Widget. Almost every serious GUI \ application will use several of these to prompt the user for input. \ \>", "Text"], Cell[BoxData[ \(Widget["\", \[IndentingNewLine]{"\" -> "\<42\>"}\ \[IndentingNewLine]] // GUIRunModal\)], "Input", CellLabel->"In[8]:="], Cell["\<\ If you play with this example a little, it is obvious that the raw \ \"textfield\" widget will require quite a lot of customisation if it is going \ to share the 'look and feel' of a typical Windows application (say). In \ particular: \[FilledSmallCircle] The window opens with the cursor on the left. Thus if \ the user types a '1' character, it will appear in the 100's field. In a \ normal Windows application the cursor appears on the right, or the whole \ field is selected, so that it can be replaced by typing over it. \[FilledSmallCircle] If the textfield is going to represent an integer (say), \ it would be nice if the user were prevented from typing anything else. \[FilledSmallCircle] In a sophisticated application, it is normal for \ displayed data to vary, both because of user input, and as a result of \ programmed interactions \[Dash] perhaps as a result of user input into \ another, related field. It is less than obvious how to achieve this effect \ using GUIKit.\ \>", "Text"], Cell["\<\ While some of these concerns may sound trivial, users of GUI applications \ expect everything to work in a predictable way, and an idiosyncratic GUI \ application may be very unappealing.\ \>", "Text"] }, Open ]], Cell[CellGroupData[{ Cell["A more substantial GUIKit example", "Section"], Cell[TextData[{ "This ", ButtonBox["notebook", ButtonData:>{ URL[ "http://www.dbaileyconsultancy.co.uk/guikit/karbonat.nb"], None}, ButtonStyle->"Hyperlink"], " contains a serious GUIKit example, kindly provided by Daniel Huber of \ Metohm Ltd. It illustrates what can be achieved with GUIKit \[Dash] and the \ amount of work required! This notebook required ", StyleBox["Mathematica", FontSlant->"Italic"], " 5.1 and GUIKit 1.0.2." }], "Text"] }, Open ]], Cell[CellGroupData[{ Cell["Super Widgets", "Section"], Cell["\<\ In conclusion, GUIKit Widgets give you the tools to build a Java GUI, but at \ a remarkably low level. A great deal of additional code is needed to 'wire \ up' the widgets to achieve the following :\ \>", "Text"], Cell[TextData[{ "\n\[FilledSmallCircle] Provide numeric fields that respond appropriately.\ \n\[FilledSmallCircle] Extract data from the GUI into ", StyleBox["Mathematica", FontSlant->"Italic"], " variables.\n\[FilledSmallCircle] Provide appropriate feedback for \ interactive graphics applications.\n\[FilledSmallCircle] Enable applications \ to update the contents of widgets programmatically.\n\[FilledSmallCircle] \ Handle the greying of widgets/menu items that should not be used in \ particular situations.\n\n I have written the ", ButtonBox["Super Widget Package", ButtonData:>{ URL[ "http://www.dbaileyconsultancy.co.uk/superwidgetpackage/\ superwidgetpackage.html"], None}, ButtonStyle->"Hyperlink"], " to address these issues, and unleash the real power of the GUIKit in \ Mathematica." }], "Text"] }, Open ]] }, Open ]] }, FrontEndVersion->"5.1 for Microsoft Windows", ScreenRectangle->{{0, 1280}, {0, 967}}, AutoGeneratedPackage->None, WindowToolbars->"EditBar", WindowSize->{1016, 673}, WindowMargins->{{Automatic, 38}, {Automatic, 0}}, Visible->True, ShowSelection->True, ShowCellLabel->False, Magnification->1, StyleDefinitions -> "HelpBrowser.nb" ] (******************************************************************* Cached data follows. If you edit this Notebook file directly, not using Mathematica, you must remove the line containing CacheID at the top of the file. The cache data will then be recreated when you save this file from within Mathematica. *******************************************************************) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[1776, 53, 90, 2, 105, "Title"], Cell[CellGroupData[{ Cell[1891, 59, 31, 0, 65, "Section"], Cell[1925, 61, 460, 11, 42, "Text"], Cell[2388, 74, 60, 1, 29, "Input"], Cell[2451, 77, 255, 7, 25, "Text"], Cell[2709, 86, 1037, 21, 143, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[3783, 112, 41, 0, 65, "Section"], Cell[3827, 114, 1079, 20, 109, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[4943, 139, 113, 5, 65, "Section"], Cell[5059, 146, 753, 15, 76, "Text"], Cell[5815, 163, 996, 14, 93, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[6848, 182, 45, 0, 65, "Section"], Cell[6896, 184, 170, 3, 25, "Text"], Cell[7069, 189, 82, 2, 29, "Input"], Cell[7154, 193, 5135, 97, 601, "Program"], Cell[12292, 292, 40, 0, 25, "Text"], Cell[CellGroupData[{ Cell[12357, 296, 119, 3, 29, "Input"], Cell[12479, 301, 60, 2, 27, "Output"] }, Open ]], Cell[12554, 306, 523, 8, 59, "Text"], Cell[13080, 316, 247, 4, 42, "Text"], Cell[13330, 322, 214, 4, 25, "Text"], Cell[13547, 328, 366, 7, 89, "Input"], Cell[13916, 337, 538, 8, 59, "Text"], Cell[CellGroupData[{ Cell[14479, 349, 93, 2, 29, "Input"], Cell[14575, 353, 358, 7, 27, "Output"] }, Open ]] }, Open ]], Cell[CellGroupData[{ Cell[14982, 366, 40, 0, 65, "Section"], Cell[15025, 368, 826, 13, 76, "Text"], Cell[15854, 383, 633, 13, 169, "Input"], Cell[16490, 398, 580, 11, 59, "Text"], Cell[17073, 411, 351, 6, 42, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[17461, 422, 35, 0, 65, "Section"], Cell[17499, 424, 165, 3, 25, "Text"], Cell[17667, 429, 161, 3, 69, "Input"], Cell[17831, 434, 1012, 16, 151, "Text"], Cell[18846, 452, 212, 4, 25, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[19095, 461, 52, 0, 65, "Section"], Cell[19150, 463, 472, 12, 42, "Text"] }, Open ]], Cell[CellGroupData[{ Cell[19659, 480, 32, 0, 65, "Section"], Cell[19694, 482, 222, 4, 25, "Text"], Cell[19919, 488, 845, 18, 200, "Text"] }, Open ]] }, Open ]] } ] *) (******************************************************************* End of Mathematica Notebook file. *******************************************************************)