adding all of botlist, initial add
[botlist.git] / botclient / botnetclient / lisp / ui / swing / swing_example_lisp.html
blob4a5284d8a5c4ca36bef07fb9d93de84ded41cf96
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
2 <!-- Created by htmlize-1.34 in css mode. -->
3 <html>
4 <head>
5 <title>swing_example.lisp</title>
6 <style type="text/css">
7 <!--
8 body {
9 color: #000000;
10 background-color: #ffffff;
12 .builtin {
13 /* font-lock-builtin-face */
14 color: #da70d6;
16 .comment {
17 /* font-lock-comment-face */
18 color: #b22222;
20 .comment-delimiter {
21 /* font-lock-comment-delimiter-face */
22 color: #b22222;
24 .doc {
25 /* font-lock-doc-face */
26 color: #bc8f8f;
28 .function-name {
29 /* font-lock-function-name-face */
30 color: #0000ff;
32 .keyword {
33 /* font-lock-keyword-face */
34 color: #a020f0;
36 .string {
37 /* font-lock-string-face */
38 color: #bc8f8f;
40 .type {
41 /* font-lock-type-face */
42 color: #228b22;
44 .variable-name {
45 /* font-lock-variable-name-face */
46 color: #b8860b;
49 a {
50 color: inherit;
51 background-color: inherit;
52 font: inherit;
53 text-decoration: inherit;
55 a:hover {
56 text-decoration: underline;
58 -->
59 </style>
60 </head>
61 <body>
62 <pre>
63 <span class="comment-delimiter">;;</span><span class="comment">################################################
65 swing_example.lisp
66 Usage:
67 ABCL-PROMPT&gt;&gt;&gt; (load "swing_example.lisp")
69 Use with ABCL (known as Armed Bear Common Lisp)
70 Author: Berlin Brown &lt;berlin dot brown at gmail.com&gt;
71 Date: 4/15/2008
73 "The opposite of a correct statement is a false statement." -- Niels Bohr
75 *LICENSE* (new bsd license):
76 -----------------------
77 [2] http://www.opensource.org/licenses/bsd-license.php
79 *Short Overview*
80 ---------------
81 Swing Client View (an swing example implemented for ABCL lisp)
83 *Full Overview*
84 ---------------
85 I always have trouble finding the right tool to create simple, throw-away
86 UIs. I created this code to launch a set of perl test scripts. I needed basic
87 menu-item/button action handlers and a text-area to view and/or parse the incoming
88 text that would have normally been piped to standard output.
90 I ended up choosing common-lisp as opposed to python or ruby because the lisp syntax is
91 just as light, and powerful a general purpose language; it is perfectly suited for my task.
92 I commonly use emacs, so I am already equipped with an editor. I decided to use Swing and ABCL for the
93 UI toolkit, and for no real particular reason. If I can create this UI using swing running on the JVM,
94 it will be 100 times easier using another toolkit. Plus, swing and the jvm is reliatively
95 portable. In the future, I hope to convert this to a more portable MVC architecture.
96 This Swing widget creation code could operate as the view for a larger system and then I could
97 easily switch with another lisp gui toolkit library.
99 *Setup and Environment*
100 -----------------------
101 ABCL runs like any other java application. Once, you compile the single jar and resource
102 bundled *.cls lisp binary files, a script is available that you use to launch the ABCL main class:
104 org.armedbear.lisp.Main
106 You need a working java runtime and JDK (preferablly Sun's jre/jdk 1.5 or greater),
107 a common lisp implementation (e.g. CMUCL, SBCL, or CLISP) and the ABCL package.
108 Download the latest ABCL from sourceforge [1] http://armedbear.org/abcl.html
109 Any of the common lisp implemenations will work. In the past, I have compiled
110 ABCL on win32 cygwin with clisp and Ubuntu Linux with SBCL. I didn't
111 experience any issues. You may have some trouble configuring the customization
112 file to point to your JDK. I had to modify the script and just removed the operating
113 system detect code.
115 I added this to the buttom of the ABCL customizations.lisp file
116 to override any pre-existing definitions:
117 (setq *jdk* "C:\\Program Files\\Java\\jdk1.5.0_11\\")
118 (setq *java-compiler* "javac")
120 Follow the steps in the README file:
121 Start your common lisp implemenation and get to the lisp REPL prompt:
123 Load build-abcl.lisp:
125 (load "build-abcl.lisp")
127 Then do:
129 (build-abcl:build-abcl :clean t :full t)
131 Launch the ABCL startup script:
132 $$$ abcl.bat
134 c:\projects\tools\home\projects\projects_ecl\botclient\botnetclient\lisp\ui\swin
135 g&gt;org.armedbear.lisp.Main
136 Armed Bear Common Lisp 0.0.10 (built Tue Apr 8 2008 12:43:18 -0500)
137 Java 1.5.0_11 Sun Microsystems Inc.
138 Java HotSpot(TM) Client VM
139 Low-level initialization completed in 0.656 seconds.
140 Startup completed in 2.171 seconds.
141 Type ":help" for a list of available commands.
143 CL-USER(1): (load "swing_example.lisp")
145 *Source Code*
146 -----------------------
147 This code can be a little hard to follow. There is a lot of typing needed
148 to setup and instantiate the java classes or access the java fields.
149 So, I suggest you use lisp syntactic sugar to beautify and cleanup the example
150 and remember to send me your patches.
152 *Useful tests from the ABCL java test suite*
153 -----------------------
154 [a] Example to create an instance of a java object with the String constructor
155 -------------------
156 (deftest jnew.1
157 (let ((constructor (jconstructor "java.lang.String" "java.lang.String")))
158 (jclass-of (jnew constructor "foo")))
159 "java.lang.String"
160 "java.lang.String")
162 [b] Accessing the 'int' java primitive
163 -------------------
164 (deftest jclass-name.8
165 (jclass-name (jclass "int"))
166 "int")
168 [c] Invoking a java method.
169 -------------------
170 (deftest jclass.4
171 (let ((class1 (jcall (jmethod "java.lang.Object" "getClass") "foo"))
172 (class2 (jclass "java.lang.String")))
173 (jcall (jmethod "java.lang.Object" "equals" "java.lang.Object")
174 class1 class2))
177 [d]
178 -------------------
179 (deftest jclass.3
180 (equal (jclass '|java.lang.String|) (jclass "java.lang.String"))
183 Example static method call "System.getenv('KEY')
184 (jstatic "getenv" (jclass "java.lang.System") "KEY")
186 Java Static Fields:
187 (jfield-raw "java.lang.Boolean" "TRUE")
189 *Synonymous java code (see the lisp function initTextAreaLayout)*:
190 ---------------------------------
191 I created a 100% java skeleton version to see how to transform that code to lisp. Here is
192 some of the java source.
194 import java.awt.BorderLayout;
195 import java.awt.event.ActionEvent;
196 import javax.swing.AbstractAction;
197 import javax.swing.BoxLayout;
198 import javax.swing.JButton;
199 import javax.swing.JFrame;
200 import javax.swing.JMenu;
201 import javax.swing.JMenuBar;
202 import javax.swing.JMenuItem;
203 import javax.swing.JPanel;
204 import javax.swing.JScrollPane;
205 import javax.swing.JTextArea;
206 import javax.swing.JTextField;
207 import javax.swing.ScrollPaneConstants;
208 import javax.swing.UIManager;
210 private void initTextAreaLayout() {
211 pathField = new JTextField(DEFAULT_PATH, 40);
212 final JPanel topPanel = new JPanel();
213 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
214 topPanel.add(pathField);
216 final JPanel buttonPanel = new JPanel();
217 this.readRequestsButton = new JButton("Run Action");
219 buttonPanel.add(this.readRequestsButton);
220 topPanel.add(buttonPanel);
222 contentArea = new JTextArea(25, 60);
223 JScrollPane scrollPane = new JScrollPane(contentArea,
224 ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
225 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
227 getContentPane().setLayout(new BorderLayout());
228 getContentPane().add(topPanel, BorderLayout.NORTH);
229 getContentPane().add(scrollPane, BorderLayout.CENTER);
232 *Tested with JDK/JRE version*:
233 ---------------------------------
234 Java version "1.5.0_11"
235 Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)
236 Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode)
238 *Thanks*
239 ---------------------------------
240 [2] Peter Graves - creator of ABCL
242 --------------------------------------
243 ** ABCL Lisp Helpers **
244 --------------------------------------
245 Example static method call "System.getenv('KEY')
246 (jstatic "getenv" (jclass "java.lang.System") "KEY")
248 Fields:
249 (jfield-raw "java.lang.Boolean" "TRUE")
251 --------------------------------------
252 ** Useful Java Swing Constructors **
253 Also see: [3] http://java.sun.com/javase/6/docs/api/javax/swing/JPanel.html
254 --------------------------------------
256 JTextField() / JTextField(String text, int columns)
257 JPanel()
258 JScrollPane() / JScrollPane(Component view) / JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
260 *Notes*
261 [4] ABCL is not forgiving with passing the wrong type to a java method. Make
262 sure the right type is passed to the right argument. ABCL returns generic errors:
264 Debugger invoked on condition of type JAVA-EXCEPTION:
265 #&lt;JAVA-EXCEPTION {4654F6}&gt;
267 [5] I defined some constants and parameters at the top of the code to reduce
268 some redundant code.
270 (defconstant j-string "java.lang.String")
272 (defparameter *new-jmenu-item* (jconstructor j-jmenuitem j-string))
274 |#</span>
275 <span class="comment-delimiter">;;</span><span class="comment">################################################
276 </span>
277 (<span class="keyword">defpackage</span> <span class="type">:swing-view</span>
278 (<span class="builtin">:use</span> <span class="builtin">:common-lisp</span> <span class="builtin">:java</span>))
279 (<span class="keyword">in-package</span> <span class="builtin">:swing-view</span>)
281 <span class="comment-delimiter">;;</span><span class="comment">----------------------------
282 </span><span class="comment-delimiter">;; </span><span class="comment">** Java Class String Constant Definitions **
283 </span><span class="comment-delimiter">;;</span><span class="comment">----------------------------
284 </span>(<span class="keyword">defconstant</span> <span class="variable-name">*default-path*</span> <span class="string">"file://./latin_text.txt"</span>)
285 (<span class="keyword">defconstant</span> <span class="variable-name">j-string</span> <span class="string">"java.lang.String"</span>)
286 (<span class="keyword">defconstant</span> <span class="variable-name">j-component</span> <span class="string">"java.awt.Component"</span>)
287 (<span class="keyword">defconstant</span> <span class="variable-name">j-container</span> <span class="string">"java.awt.Container"</span>)
288 (<span class="keyword">defconstant</span> <span class="variable-name">j-layout-manager</span> <span class="string">"java.awt.LayoutManager"</span>)
289 (<span class="keyword">defconstant</span> <span class="variable-name">j-borderlayout</span> <span class="string">"java.awt.BorderLayout"</span>)
290 (<span class="keyword">defconstant</span> <span class="variable-name">j-actionevent</span> <span class="string">"java.awt.event.ActionEvent"</span>)
291 (<span class="keyword">defconstant</span> <span class="variable-name">j-abstractaction</span> <span class="string">"javax.swing.AbstractAction"</span>)
292 (<span class="keyword">defconstant</span> <span class="variable-name">j-boxlayout</span> <span class="string">"javax.swing.BoxLayout"</span>)
293 (<span class="keyword">defconstant</span> <span class="variable-name">j-jbutton</span> <span class="string">"javax.swing.JButton"</span>)
294 (<span class="keyword">defconstant</span> <span class="variable-name">j-jframe</span> <span class="string">"javax.swing.JFrame"</span>)
295 (<span class="keyword">defconstant</span> <span class="variable-name">j-jmenu</span> <span class="string">"javax.swing.JMenu"</span>)
296 (<span class="keyword">defconstant</span> <span class="variable-name">j-jmenubar</span> <span class="string">"javax.swing.JMenuBar"</span>)
297 (<span class="keyword">defconstant</span> <span class="variable-name">j-jmenuitem</span> <span class="string">"javax.swing.JMenuItem"</span>)
298 (<span class="keyword">defconstant</span> <span class="variable-name">j-jpanel</span> <span class="string">"javax.swing.JPanel"</span>)
299 (<span class="keyword">defconstant</span> <span class="variable-name">j-jscrollpane</span> <span class="string">"javax.swing.JScrollPane"</span>)
300 (<span class="keyword">defconstant</span> <span class="variable-name">j-jtextarea</span> <span class="string">"javax.swing.JTextArea"</span>)
301 (<span class="keyword">defconstant</span> <span class="variable-name">j-jtextfield</span> <span class="string">"javax.swing.JTextField"</span>)
302 (<span class="keyword">defconstant</span> <span class="variable-name">j-scrollpaneconstants</span> <span class="string">"javax.swing.ScrollPaneConstants"</span>)
303 (<span class="keyword">defconstant</span> <span class="variable-name">j-uimanager</span> <span class="string">"javax.swing.UIManager"</span>)
305 (<span class="keyword">defparameter</span> <span class="variable-name">*scroll-h-always*</span> (jfield-raw j-scrollpaneconstants
306 <span class="string">"HORIZONTAL_SCROLLBAR_ALWAYS"</span>))
307 (<span class="keyword">defparameter</span> <span class="variable-name">*scroll-v-always*</span> (jfield-raw j-scrollpaneconstants
308 <span class="string">"VERTICAL_SCROLLBAR_ALWAYS"</span>))
310 (<span class="keyword">defparameter</span> <span class="variable-name">*bl-north*</span> (jfield j-borderlayout <span class="string">"NORTH"</span>)
311 <span class="string">"Definition for swing constants"</span>)
312 (<span class="keyword">defparameter</span> <span class="variable-name">*bl-east*</span> (jfield j-borderlayout <span class="string">"EAST"</span>)
313 <span class="string">"Definition for swing constants"</span>)
314 (<span class="keyword">defparameter</span> <span class="variable-name">*bl-center*</span> (jfield j-borderlayout <span class="string">"CENTER"</span>)
315 <span class="string">"Definition for swing constants"</span>)
316 (<span class="keyword">defparameter</span> <span class="variable-name">*bl-west*</span> (jfield j-borderlayout <span class="string">"WEST"</span>)
317 <span class="string">"Definition for swing constants"</span>)
318 (<span class="keyword">defparameter</span> <span class="variable-name">*bl-south*</span> (jfield j-borderlayout <span class="string">"SOUTH"</span>)
319 <span class="string">"Definition for swing constants"</span>)
320 (<span class="keyword">defparameter</span> <span class="variable-name">*box-y-axis*</span> (jfield j-boxlayout <span class="string">"Y_AXIS"</span>)
321 <span class="string">"Definition for swing constants"</span>)
322 (<span class="keyword">defparameter</span> <span class="variable-name">*box-x-axis*</span> (jfield j-boxlayout <span class="string">"X_AXIS"</span>)
323 <span class="string">"Definition for swing constants"</span>)
325 <span class="comment-delimiter">;;</span><span class="comment">----------------------------
326 </span><span class="comment-delimiter">;; </span><span class="comment">** Java method definitions **
327 </span><span class="comment-delimiter">;;</span><span class="comment">----------------------------
328 </span>(<span class="keyword">defparameter</span> <span class="variable-name">*method-set-layout*</span>
329 (jmethod j-container <span class="string">"setLayout"</span> j-layout-manager))
330 (<span class="keyword">defparameter</span> <span class="variable-name">*method-jmenu-add*</span> (jmethod j-jmenu <span class="string">"add"</span> j-jmenuitem))
331 (<span class="keyword">defparameter</span> <span class="variable-name">*method-jpanel-add*</span> (jmethod j-jpanel <span class="string">"add"</span> j-component))
332 (<span class="keyword">defparameter</span> <span class="variable-name">*method-container-add*</span> (jmethod j-container <span class="string">"add"</span> j-component))
333 (<span class="keyword">defparameter</span> <span class="variable-name">*method-container-add-2*</span> (jmethod j-container <span class="string">"add"</span>
334 j-component <span class="string">"java.lang.Object"</span>))
336 <span class="comment-delimiter">;; </span><span class="comment">Java constructor definitions
337 </span>(<span class="keyword">defparameter</span> <span class="variable-name">*new-jmenu-item*</span> (jconstructor j-jmenuitem j-string))
338 (<span class="keyword">defparameter</span> <span class="variable-name">*new-scroll-pane*</span>
339 (jconstructor j-jscrollpane j-component <span class="string">"int"</span> <span class="string">"int"</span>))
340 (<span class="keyword">defparameter</span> <span class="variable-name">*new-scroll-pane-2*</span> (jconstructor j-jscrollpane <span class="string">"int"</span> <span class="string">"int"</span>))
341 (<span class="keyword">defparameter</span> <span class="variable-name">*new-textarea*</span> (jconstructor j-jtextarea <span class="string">"int"</span> <span class="string">"int"</span>))
343 <span class="comment-delimiter">;;</span><span class="comment">----------------------------
344 </span><span class="comment-delimiter">;; </span><span class="comment">Function implementations
345 </span><span class="comment-delimiter">;;</span><span class="comment">----------------------------
346 </span>(<span class="keyword">defun</span> <span class="function-name">j-true</span> () (make-immediate-object t <span class="builtin">:boolean</span>))
347 (<span class="keyword">defun</span> <span class="function-name">j-false</span> () (make-immediate-object nil <span class="builtin">:boolean</span>))
349 (<span class="keyword">defun</span> <span class="function-name">to-java-string</span> (s)
350 (jnew (jconstructor <span class="string">"java.lang.String"</span> <span class="string">"java.lang.String"</span>) s))
352 (<span class="keyword">defun</span> <span class="function-name">init-swing</span> (jframe)
353 <span class="doc">"Define the frame properties. Add the button panel and menu"</span>
354 (<span class="keyword">progn</span> (setNativeLookUI)
355 (initTextAreaLayout (get-content-pane jframe))))
357 (<span class="keyword">defun</span> <span class="function-name">get-content-pane</span> (jframe)
358 <span class="doc">"Translated to natural language: Using the instance of
359 the JFrame object called jframe, invoke the getContentPane method
360 and return an instance of the Container class"</span>
361 (jcall (jmethod j-jframe <span class="string">"getContentPane"</span>) jframe))
363 (<span class="keyword">defun</span> <span class="function-name">new-borderlayout</span> ()
364 <span class="doc">"Create an instance of the border layout class"</span>
365 (jnew (jconstructor j-borderlayout)))
367 (<span class="keyword">defun</span> <span class="function-name">new-box-layout</span> (panel axis)
368 (jnew (jconstructor j-boxlayout j-container <span class="string">"int"</span>) panel axis))
370 (<span class="keyword">defun</span> <span class="function-name">path-textfield</span> ()
371 (jnew (jconstructor j-jtextfield j-string <span class="string">"int"</span>)
372 *default-path* 40))
374 (<span class="keyword">defun</span> <span class="function-name">initTextAreaLayout</span> (content-pane)
375 <span class="doc">"Attach the content text area widget and other components
376 @content-pane (java.awt.Container) - Container we are adding widgets
377 @see java.awt.Container"</span>
378 (<span class="keyword">let*</span> ((text-field (path-textfield))
379 (contentArea (jnew *new-textarea* 25 60 ))
380 (topPanel (jnew (jconstructor j-jpanel)))
381 (buttonPanel (jnew (jconstructor j-jpanel)))
382 (scrollPane (jnew *new-scroll-pane* contentArea
383 *scroll-v-always* *scroll-h-always*)))
384 (format t <span class="string">"INFO: content-pane obj:= [ ~a | ~a ]~%"</span> content-pane topPanel)
385 (jcall *method-set-layout* topPanel
386 (new-box-layout topPanel *box-y-axis*))
387 <span class="comment-delimiter">;; </span><span class="comment">Add TO the top panel; in java this will look like: topPanel.add(pathField)
388 </span> (jcall *method-jpanel-add* topPanel text-field)
389 (jcall *method-set-layout* content-pane (new-borderlayout))
390 (jcall *method-container-add-2* content-pane topPanel *bl-north*)
391 (jcall *method-container-add-2* content-pane scrollPane *bl-center*)))
393 (<span class="keyword">defun</span> <span class="function-name">setNativeLookUI</span> ()
394 <span class="doc">"Use the operating system native UI look and feel, do not use the Swing oriented look"</span>
395 (jstatic <span class="string">"setLookAndFeel"</span>
396 (jclass j-uimanager)
397 <span class="string">"com.sun.java.swing.plaf.windows.WindowsLookAndFeel"</span>))
398 (<span class="keyword">defun</span> <span class="function-name">createReaderFrame</span> ()
399 <span class="doc">" Create the simple reader frame "</span>
400 (<span class="keyword">let</span> ((simpleFrame (jnew (jconstructor j-jframe))))
401 (init-swing simpleFrame)
402 (jcall (jmethod j-jframe <span class="string">"pack"</span>) simpleFrame)
403 (jcall (jmethod j-jframe <span class="string">"setVisible"</span> <span class="string">"boolean"</span>)
404 simpleFrame (j-true))))
406 (<span class="keyword">defun</span> <span class="function-name">lisp-main</span> ()
407 <span class="doc">"Main entry point, create the jframe and attach the widget components then
408 start the jframe thread"</span>
409 (format t <span class="string">"INFO: creating panel objects~%"</span>)
410 (createReaderFrame))
412 #+abcl
413 (lisp-main)
415 <span class="comment-delimiter">;;</span><span class="comment">################################################
416 </span><span class="comment-delimiter">;; </span><span class="comment">End of Script
417 </span><span class="comment-delimiter">;;</span><span class="comment">################################################</span></pre>
418 </body>
419 </html>