Hi, I've spent some time in the last couple of weeks going through the Furi code, so what follows are just some preliminary observations. On the whole, I'm very impressed - it's pretty good and extensible.
1. The main UI classes are the MainFrame and BaseFrame classes: BF provides the basic support for a UI and then MainFrame adds all of the Furi-specific components.
2. UI actions are managed through the Furi.properties file. Essentially, Furi is designed to have pluggable action classes that you associate to each UI component when the applications starts-up. This makes adding menu items and functions a snap.
All of the Action classes extend the ActionBase class by overwriting the actionPerformed and refresh methods. The former is the real action method: refresh just helps the Action button or menu item know whether it is enabled or not.
3. Dialog boxes are associated with some but not all of the actions. These all extend JDialog.
4. UI items such as buttons, textfields, and tables have ActionListeners attached to them. These are usually Handler classes that call some MainFrame method that performs the action logic. Most handlers also call refreshAllActions - this calls the refresh method of each Action class.
So much for the UI: now come the interesting bits!
4. On startup, Furi intializes several Manager classes: these manage the various main functions of Furi. There is a single instance of each, created by the ServiceManager on start-up. The Managers work with Worker classes to handle requests. The SendManager is responsible for queeing outbound messages and it spawns SendWorker threads as required.
5. Worker classes all implement the runnable interface in order that each Worker can be spawned in its own Thread. For example, a ReadWorker will typically process a request by performing a handshake with a remote host (represented by the Host class) and then processing the request using its processIncomingData method. Most of the time the Listener class is responsible for listening for connections and handing off the Host to a ReadWorker instance. Each Host comes with its input stream (to read the request) and output stream (to write the response).
6. The message classes are used to encapsulate messages: header information is provided in the MsgHeader class (includng the Host), and the header is used to retrieve the body of the message in the form of a byte array.
Possibly the single biggest improvement that could be made is organizational: providing a better package structure would help. The MainFrame class is huge - one change I made was to pull the Handlers out into their own class. I've also pulled the Actions, Dialog, and TableModels into their own packages to make it easier see the forest for the trees.
Hope this helps. Martin |