CLIM mail archive
[Prev][Next][Index][Thread]
Initializing application frames
Date: Wed, 18 Dec 1991 01:24+0200
From: seth@gandalf.hrl.hac.com
I'm a bit confused about how to initialize my application frames.
I'm displaying a static set of data in various panes which are
scrollable. I've defined an application frame and written an
:after initialize-instance method to present the data in the
apropriate panes. The scrollbars don't seem to get activated
until I resize the frame and in fact, sometimes the menus are messed
up as well. The only alternative I can see is to defined a display
function for each pane and let it do the presenting. This seems
wasteful (is there a clever way to do it?).
Configuration: MCL 2.0b1p3 w/ CLIM 1.0 from ILA on a MAC IIci.
Thanks,
Seth Goldman
seth@gandalf.hrl.hac.com
(310) 317-5693
You should note that an :after initialize-instance method is
in terms of CLIM a rather low level approach, because it
act directly on the CLOS object representing the new frame.
I suggest that you use CLIM facilities to solve your problem.
In case that your CLIM documentation doesn't say anything about that,
here's the appropriate chapter of Symbolics' CLIM Documentation.
Markus Fischer
Symbolics Systemhaus GmbH
Consulting Services
Frankfurt, Germany
Copyright for the part of the documenation:
(C) 1991 - 1981 Symbolics, Inc.
8 New England Executive Park, East
Burlington, MA 01803
Initializing CLIM Application Frames
There are several ways to initialize an application frame:
1. The value of an application frame's slot can be initialized using
the1 0:initform slot option in the slot's specifier in the
clim:define-application-frame form.1 0This technique is suit-
able1 0if the slot's initial value does not depend on the values of
other1 0slots, calculations based on the values of initialization ar-
guments,1 0or other information which can not be determined until
after the1 0application frame is created.1 0See the macro
clos:defclass to learn about slot-specifiers.
2. For initializations which depend on information which may not be
available until the application frame has been created, an :after
method can be defined for clos:initialize-instance on the1 0ap-
plication frame's class.1 0Note that the special variable
clim:*application-frame* is not bound to the application since
the application is not yet running.1 0The macro1 0clim:with-frame-
state-variables cannot be used in this1 0context, either.1 0You
may use clos:with-slots,1 0clos:with-accessors, or any slot
readers or accessors which have1 0been defined.
3. A :before method for clim:run-frame-top-level on the1 0ap-
plication's frame is probably the most versatile place to perform
application frame initialization.1 0This method will not be executed
until the application starts running.1 0clim:*application-frame*
will be bound to the application frame, and you can use
clim:with-frame-state-variables in this context.
4. If the application frame employs its own top-level function, then
this function can perform initialization tasks at the beginning of
its1 0body.1 0This top-level function may call1 0clim:default-frame-
top-level to achieve the standard behavior1 0for application
frames.
Of course, these are only suggestions.1 0There might be other tech-
niques1 0which might be more appropriate for your application.1 0Of
those listed, the1 0:before method on clim:run-frame-top-level is
probably the best1 0for most circumstances.
Although application frames are CLOS classes, do not use
clos:make-instance to create them.1 0To instantiate an application
frame, always use clim:make-application-frame.1 0This function
provides important initialization arguments specific to application
frames which clos:make-instance does not.1 0clim:make-
application-frame passes any keyword value pairs1 0which it does
not handle itself on to clos:make-instance.1 0Thus, it1 0will respect
any initialization options which you give it, just as1 0clos:make-
instance would.
Here is an example of how an application frame's behavior might be
modified by inheritance from a superclass.
Suppose we wanted our application to record all of the commands
which1 0were performed while it was executing.1 0This might be useful in
the1 0context of a program for the financial industry where it is impor-
tant to1 0keep audit trails for all transactions.1 0As this is a useful func-
tionality1 0that might be added to any of a number of different appli-
cations, we1 0will separate it out into a special class which implements
the desired1 0behavior.1 0This class can then be used as a superclass for
any1 0application which should keep a log of its actions.
The class has an initialization option :pathname which specifies the
name of the log file.1 0It has a slot named transaction-stream
whose1 0value is a stream opened to the log file when the application
is running.
2(defclass transaction-recording-mixin ()
0 2((transaction-pathname :type pathname
0 2 :initarg :pathname
0 2 :reader transaction-pathname)
0 2 (transaction-stream :accessor transaction-stream)))
0 We use an :around method on clim:run-frame-top-level which
opens1 0a stream to the log file, and stores it in the transaction-
stream slot.1 0unwind-protect is used to clear the value of the slot
when the stream1 0is closed.
2(defmethod clim:run-frame-top-level :around
0 2 ((frame transaction-recording-mixin))
0 2 (with-slots (transaction-pathname transaction-stream) frame
0 2 (with-open-file (stream transaction-pathname
0 2 :direction :output)
0 2 (unwind-protect
0 2 (progn
0 2 (setq transaction-stream stream)
0 2 (call-next-method))
0 2(setq transaction-stream nil)))))
0 This is where the actual logging takes place.1 0The command loop in
clim:default-frame-top-level calls1 0clim:execute-frame-
command to execute a command.1 0Here we1 0add a :before method
which will log the command.
2(defmethod clim:execute-frame-command :before
0 2 ((frame transaction-recording-mixin) command)
0 2 (format (transaction-stream frame)
0 2 "~&Command: ~a" command))
0 It is now an easy matter to alter the definition of an application to
add1 0the command logging behavior.1 0Here is the definition of the puz-
zle1 0application frame from the CLIM demos suite (from the file
"SYS:CLIM;DEMO;PUZZLE.LISP").1 0Our modifications are shown in
3italics0.1 0We use the superclasses argument to specify that the puzzle
application frame should inherit from
transaction-recording-mixin.1 0Because we are using the superclass
argument, we must also explicitly1 0include clim:application-frame
which was defaultly included when1 0the superclasses argument was
empty.
2(define-application-frame puzzle
0 2 (3transaction-recording-mixin application-fra
me2)
0 2 ((puzzle :initform (make-array '(4 4))
0 2 :accessor puzzle-puzzle))
0 2 3(:default-initargs :pathname "puzzle-log.text")
0 2 (:panes ((title :title)
0 2 (menu :command-menu)
0 2 (display :application
0 2 :default-text-style '(:fix :bold :very-large)
0 2 :incremental-redisplay T
0 2 :display-function draw-puzzle))))
0 Also note the use of
2(:default-initargs :pathname "puzzle-log.text")
0 to provide a default value for the log file name if the user doesn't
specifty one.
The user might run the application by executing
2(clim:run-frame-top-level
0 2 (clim:make-application-frame 'puzzle
0 2 :parent (clim:open-root-window :sheet)
0 2 :pathname "my-puzzle-log.text"))
0 Here the :pathname initialization argument was used to override the
default name for the log file (as was specified by the :default-
initargs1 0clause in the above application frame definition) and to use
the name1 0"my-puzzle-log.text" instead.1
0,,
References:
Main Index |
Thread Index