New Window System Design Document
Version: 1.2, March 26, 2003
Author: Peter Zavadsky,
Sun Microsystems/NetBeans
- Abstract:
- Following document describes design of new window system which reflects
new finishing WindowSystem
UI specification. It also solves problem of older implementation described
in redesign document.
- Document History:
- [03/20/2003] : version 1.0 : {First version of the document}
- [03/24/2003] : version 1.1: {Added some details about idividual components}
- [03/26/2003] : version 1.2: {Changed model representation from binary
to n-branch tree}
Contents:
1. Overview
Picture No.1 Window System implementation structure.
The picture shows design of internal structure of new window system implementation.
It consist from central unit, model, view, controller and persistence. The
central unit is a master part and the rest ones are just slaves to the master
one. Only central unit have an access to other slave parts and has a notion
about their existence. Every slave part is independent from each other and
just works as the central unit requests (e.g. view), or informs the central
unit about relevant changes (e.g. controller). None of the slave part is allowed
to make an active changes to the central unit (and of course not to other
slave parts), they can just inform about some changes.
2. Central Unit
Central unit is the heart of window system implementation. It is the control
unit of entire window system. It manages API calls properly, i.e the way updates
model, and request view to change GUI afterwards. It also updates model according
to user changes passed via controller, to keep the model in consistent state.
It also requests loading/saving of window system to persistence. Also manages
lazy loading (more precisely creation of window system components). The lazy
creation is always done, the way first is updated model, then is requested
view to reflect the change. It takes care that all requests to view are scheduled
into AWT thread.
Central unit also implements API, both open one (which is exposed in openide),
and innner one which is used internally by window system actions (and DnD
framework). Centra unit will have also additional advanced tasks like coallescing
more subsequent model updates into one request to view (while view is working
the rest requests should be coallesced).
Rules for Central Unit
- Central Unit is the control unit, responsible for providing appropiate
commnunications between all other parts of window system.
- It implements API, both open and inner one.
- it is responsible for updating model according to API calls, persistene
changes and user changes, to reflect the current state of window system
- It is consequentelly responsible for sending request to view part,
and guarranties that all those requests are schduled into AWT thread.
- It communicates with persistence level, and accoding to that updates
model and sends appropiate requests to view.
- it also responds user changes passed in by controller to model
- it controls loading and saving to persistence.
3. Model
Model is the part which represents data according the window system presents
GUI to user. The model represents consistent state of window system, or more
precisely the state which has to be shown to user. It is thread safe, i.e.
the model itself takes care about proper synchronization, and makes proper
udates of itself that way it keeps valid state.
The model has also an ability to create view format (so called model snapshot)
of itself (again in thread safe manner), which is then used in view. The snapshot
provides just visible components to view. The snapshot is created on Central
unit request.
Model is internaly devided to parts which keeps data of window manager,
like main window bounds, toolbar config, and also sub model of modes. This
part is important since it is the most (and almost only one) a bit complicated
part of model. It represents split panes and is represented by n-branch tree
where each leaf node belongs to mode (or editor area as the only exception
- the editor area is again represented by similar tree), each node with the
children represents split.
The rest parts of model are mode representations which keeps data like type
of mode, top component belonging to that mode (both open and closed) etc.
Rules for Model
- Model doesn't know about any other part of window system implementation.
- Its purpose is keep the data in thread safe manner and create model
snapshot, relevant for both view and persistence, but controlled by central
unit.
Actual model representation
Currently the model is represented by two classes in org.netbeans.core.windows.model
package. Those are WindowSystemModel, which corresponds to WindowManagerConfig
and ModeModel which corresponds to ModeConfig. Usually the data are stored
in model in one independent field, e.g. like bounds of main window is independent
from any other property.
Up to now only difference is a representation of split pane strucuture in
model which represents positions in split of all modes. The difference is
necessary due to a nature of such a model. The position on split model is
defined by each mode, and that definition could clash with the already current
state, or with other mode definitions. Therefore the model has to handle such
cases appopriatelly (accoding to defined policy -> possible weight field
in mode config file). It means that change in constrains of one mode can
affect also other modes in split structure, that wat their actual constraints
are changed too. Thus the constrains of mode which designate the mode position
in split pane structure is dependent from other ones, and has to be represented
by special structure in model. That structure is a n-branch tree, where each
leaf represents mode (there is one exception -> editor area), and each
non-leaf mode represents a split. See the picure No. 2.
Editor area is itself represented again as a n-branch tree.
Note the similar possible clash which could happen with constraints could
also happen with so called split weights (the appropirate name is finding).
Model has to update them properly according defined policy (possible weights
of modes).
No 2. N-branch (each model split element can have more than two components!)
sub tree structure representing splitted modes.
Note that split could be vertical or horizontal respectivelly. It is designated
by the constraint of it child LEFT, RIGHT or TOP, BOTTOM. This model keeps
constrains of mode (which designate loaction in the split structure), e.g.
Mode1 has constrains [LEFT, TOP], Editor(Document) Area has [RIGHT, LEFT].
Also note that similar way will be stored relative size of mode, see at
the array around each mode node. E.g. For Edirot Area array [75, 80] will
mean that if it will be present in split1 (Mode3 is invisible, thus split3
is hidden) it wants to take 75% of the split pane (split1), if in split2
it wants to take 75% of that area.
Note: The n-branch representation means that when two splits [dividers]
are in a row, for user it has to behave like split with three subcomponents,
therefore the model will use this kind of structure. The fact it will be
actually shown using two nested JSplitPane components is a implementation
detail which neither user shouldn notice [from resizin style] nor client
programmer [when configuring xml config files or using API respectivelly].
BInary tree structure will be passed as a model snaphost to view, which is
convenient for the view. See the pic No 3
No 3. Explanation of n-tree branch split. For user are modes M1,M2,M3 at
same level of split. It is also represented in model that way. Just due to
a lack of such n-branch swing component we represent this case at GUI level
using two JSplitPanes. But during resizing one of them (i.e. Split2 in this
cas) has to be taken measures so also the above split (Split1) is resized
proportionally, so the user has the real feel modes M1,M2,M3 are at the same
level.
4. View
Takes care about GUI, i.e. its creation and manipulation. View responses
to the requests from Central Unit. Central Unit passed in in view convenient
format (snapshot of model valid for that request). It is then responsible
to show GUI in accordingly to that snapshot. The central unit in the request
always will inform view about type of change. View doesn't have a direct access
to model, but just via interface (it will define kind of getter plus the
snapshot) can retrieve model values which are valid for that request.
Rules for View
- View doesn't access model directly, it uses the structure (model snapshot)
provided by central unit, which are valid data for currently processing task.
- It doesn't sens any requuests to central unit, it is just responsible
for processing request comming from the central unit.
Format of model passed into view by central unit
The format will describe the valid data values for the specific request
(which view has to process). The format is so called snaphot of model. The
ordinary data values (like main window bounds, selected topcomponent etc.)
will be just copies of those model values.
Only exception is the split representation (currently the class format is
named ModesSnapshot and is in org.netbeans.core.windows package).
Have a look at pic. No 2, which represents current model state. Imagine
Mode1 and Editor Area are visisble (constains visible windows [=TopComponents])
and Mode2 and Mode3 are invisible. The GUI is supposed to look like the one
in the picture No 4.
No 4. GUI outlook.
Therefore it is for view appopriate to get represented structure as shows
picture No 5.
No 5. Split strutcure to show in view convenient format
According this structure view will be able to show the modes in correct
positions.
There remains one issue, i.e. the location of split divider. The loaction
is computed from the split weights array. In our example it is that mode1
takes 25% and editor area 75% of the size of split pane.
5. Controller
This is the smallest part, which only task is to inform central unit about
changes made by user whic require update of model. Note that this updating
of model is not followed by view change request and that is the significant
differrence between other processings (like API calls, persistence changes).
It is vice-versa process.
Controller will be impelented more tightly to view and especially its GUI
representation (GUI components).
Rules for Controller
- Controller may not activelly access/update model part, it just informs
the central unit.
- It may not access view part, only thing it will be aware about is
the GUI component, which changes provided by user are relevant for model
update.
6. Persistence
Persistence part takes care about writing and reading data from structure
in filesystem. There is defined format for communication with central unit,
which keeps the data which were read/are going to be stored into/from filesystem
(calling them configuration data).
It also informs central unit, when some config data (i.e. its file) was
added/removed (model enablement/disablement).
Communication with central unit
There is defined communication interface between persistence and central
unit:
- requests of loading/saving from central unit.
There are 2 methods in PersistenceManager, their signatures are: WindowManagerConfig
loadWindowSystem(); and void saveWindowSystem(WindowManagerConnfig);
- central unit needs to be informed about adding/removing configurations
(typically as module gets enbled/disabled)
There are 4 methods in WindowManagerImpl: void modeConfigAdded(ModeConfig);
void modeConfigRemoved(ModeConfig); void topComponentConfigAdded(TopComponentConfig);
void topComponentConfigRemoved(TopComponentConfig);
- persistence offers method for retrieving serialized TopComponent using
specified ID (the one specified in TopComponentConfig structure): TopComponent
getTopComponentForID(String ID);
- defined are structures for passing the persistence data (all reside
in org.netbeans.core.windows package):
- WindowManagerConfig it corresponds to .wsmgr file, contains
data used at WindowManagerImpl level (like main window bouds, toolbarConfigName,
activeMode..), and also list of references to ModeConfig structures.
- ModeConfig
it corresponds to one .wsmode file, contains data used at ModeImpl level (like
constrains, bounds of mode, type [editor - view], selected topComponent, and
also list of references to TopComponentConfig.
- TopComponentConfig it corresponds to one .wstcref
file, contains TopComponent data, its ID (which is used for actual deserializing
of TopComponent) and state. There could appear more of them.
Rules for Persistence
- Persistence part may not access any other classes beside it its package
(org.netbeans.core.layers) and those defined in the communication interface
(that will be specified by some interface).
- Handling of I/O errors. Persistence may not throw IO errors to central
unit. It is its job to handle them properly. It means log them in some understandable
format, and when corrupted files are detected, those are needed either to
be repaired (by some default configs) or deleted, the actuall reaction will
depend on the specific situation.
7. Auxilliaries
Here belongs window system actions, and DnD framework. Actions and DnD use
the API (both open and internal) exposed by central unit. Their implementation
is independent of the internal winsys implementation. But are important, since
they mean
8. Open Issues
It is not decided yet how to represent or allow so called window (TopComponent)
sets. E.g. when starting debugging more than one windows are opened, and again
when the debugging is stopped all those windows are closed.
See more in UI specification. FIrst has to be defined exact behaviours of
such components belonging to such set according to some changes of them. It
is still open issue in UI spec.
9. Summary
For current status and individual tasks see Issue:
http://www.netbeans.org/issues/show_bug.cgi?id=29836
Please put questions or comments directly into that issue directly
or at [nbdev] netbens developers mailing
list.