r2 - 22 Mar 2006 - 11:37:15 - ScottLawrenceYou are here: TWiki >  LIAS Web  >  PresentationMaterials > SeminarSeries > LlamaGuiPresentation
Tags:
create new tag
, view all tags
Written for the Mar 22 LIAS Seminar on Llama Gui.

Start Presentation

Slide 1: Llama Gui

Llama GUI

ScottLawrence

2006 March 22






LIAS.LlamaGuiPresentation

http://tinyurl.com/zahq9

LlamaGUI.mp3: This presentation's audio.

Slide 2: Background

  • Java is a cross-platform language
  • Write once...
  • GUI libraries/classes: Swing, AWT
  • Both require lots of support code
  • A button can be 8 lines or more for each button
  • PLUS setup code for the layout manager
  • Have to deal with layout managers, widgets, callbacks

Slide 3: Burrito

  • December 2004...
  • SOFIA AOR Editor + WASP ADP Gui = Frazzled Scott
  • Use first AOR Editor version as prototype
  • Distill both products down to requirements
  • How are they similar
  • Most of those "8 lines" for a button are nearly identical to eachother
  • Most of the AOR Editor was: Label - field - units

Slide 4: Result

  • Simple XML structure with most defaults implicit
    • no need to have everywhere: grayed="false" etc.
  • Use various layout managers "under the covers"
  • Use XML Nesting to determine structure
  • Those "8 lines" are all in the parser
  • Runtime configurability
  • App can be run on multiple platforms
  • Encapsulate everything that is pure GUI code in one place

Slide 5: Supported GUI Elements

  • Structure:
    • Menus, Panels, Tabs, Scroll Panes, Borders, Columns
  • Widgets:
    • Button, Radio Button, Check Button
    • Text box, Text area
    • Slider, Image display, Combo Boxes
  • Compound:
    • File Chooser
    • Accept/Cancel button Groupings

  • units and range checking on applicable widgets
  • default value/content for widgets

  • conditionals - runtime-definable

  • "LGJPanel" class that maintains it all
    • retrieval of widgets, set/get contents, etc.

Slide 6: Comparison Example - layout manager

    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c  = new GridBagConstraints();
    Insets i = new Insets( 4, 1, 1, 4 ); // s, w, e, n

    JPanel pane = new JPanel();
    pane.setBorder(BorderFactory.createEmptyBorder( 1,5,1,5 ));
    //pane.setLayout(new GridLayout(0, 1, 5, 5));
    pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS )); 
    JPanel summaryPane = new JPanel();
    summaryPane.setBorder( BorderFactory.createCompoundBorder(
                    BorderFactory.createTitledBorder( "Summary" ),
                    BorderFactory.createEmptyBorder( 1,5,1,5 )));
                                                
    // set up the layout
    gridbag = new GridBagLayout();
    c = new GridBagConstraints();
    c.insets = i;
    summaryPane.setLayout( gridbag );

This simply sets up a layout onto which widgets are placed.

There is no analog in LlamaGui for this, since the layout is implicit.

Slide 7: Comparison Example - Swing - adding two widgets

    // Title
       // label  (uses 'widgethelper' class, not shown)
    summaryPane.add( wh.newLabel( gridbag, c, "Obs. Title", 0 ));
       // text
    title_text = new JTextField( 40 );
    wh.setupWidgetPositionWide( gridbag, c, title_text, 0 );
    gridbag.setConstraints( title_text, c );
    title_text.setEditable( false );
    title_text.setText( "the title" );
    summaryPane.add( title_text );
    this.widgetMap.put( "/AOR/SummaryInformation/ObservationTitle", title_text );

    // Obj Name
       // label (uses 'widgethelper' class, not shown)
    summaryPane.add( wh.newLabel( gridbag, c, "Object Name", 2 ));
       // text
    objname_text = new JTextField( 40 );
    objname_text.setEditable( false );
    objname_text.setText( "an object" );
    wh.setupWidgetPositionWide( gridbag, c, objname_text, 2 );
    gridbag.setConstraints( objname_text, c );
    summaryPane.add( objname_text );
    this.widgetMap.put( "/AOR/SummaryInformation/ObjectName", objname_text );

  • I stored the widget pointers in widgetMap, for referencing later
    • no need for a billion globals
    • easier to maintain
    • parser of the data file mapped to widget names one-for-one

Slide 8: Comparison Example - LlamaGui - adding two widgets

The equivalent of this in LlamaGui (with the exception of wrapper XML...)

    <Text label="Obs. Title"
          ref="/AOR/SummaryInformation/ObservationTitle">the title</Text>
    <Text label="Object Name"
          ref="/AOR/SummaryInformation/ObjectName">an object</Text>

  • Internally, a similar map is used, but you access them via support functions

Slide 9: Example - LlamaGui - support code

Setting up the GUI:

    LGJParser theParser = new LGJParser();

    if( theParser.initPanelFromFile( "gui.xml", "gloop", this ) == false ) {
            theParser.printErrorDump( System.out );
            System.exit( 0 );
    }

    LGJPanel thePanel = theParser.getLGJPanel();
    // wrap it in a scroll pane for the heck of it
    frame.getContentPane().add( new JScrollPane( thePanel ));

Handling button presses:

    public void actionPerformed( java.awt.event.ActionEvent e )
    {
        // menu options and such...
        if(    e.getActionCommand().equals( "But1" ) ) {
            System.out.println( "Button was pressed!" );
            thePanel.setWidgetText( "field 1", "Pressed!" );
        }
    }

Here's an XML file that can be loaded in via the above code:

    <LlamaGui>
        <Panel id="gloop">
            <Text ref="field 1" label="one">This is field 1</Text>
            <Button ref="But1" label="Button!">Press Me Here</Button>
        </Panel>
    </LlamaGui>

Slide 10: Example - Menus and conditionals

  • Lets the system decide segments of XML to use at runtime

    <LlamaGui>
        <MenuBar id="menus">
            <Parameter istrue="not OS X">
                <Menu ref="/menu1" label="File" mnem="F">
                    <MenuItem ref="app/reconnect" label="Reconnect"/>
                    <Separator/>
                    <MenuItem ref="quit" label="Quit"/>
                </Menu>
            </Parameter>
            <Parameter istrue="OS X">
                <Menu ref="/menu1" label="Connection" mnem="F">
                    <MenuItem ref="app/reconnect" label="Reconnect"/>
                    <Separator/>
                    <MenuItem ref="quit" label="Quit"/>
                </Menu>
            </Parameter>
            <HorizontalGlue/>
            <Menu ref="/help" label="Help">
                <MenuItem ref="/help/help" alt="H" label="Help"/>
                <MenuItem ref="/help/about" label="About..."/>
            </Menu>
        </MenuBar>
    </LlamaGui>

Slide 11: Example - Menu support code

    LGJParser theParser = new LGJParser();
    boolean onOSX = true;  /* set this elsewhere */

    if( onOSX )   theParser.setParamString( "OS X", "true" );
    if( !onOSX )  theParser.setParamString( "not OS X", "true" );

    if( theParser.initPanelFromFile( "gui.xml", "gloop", this ) == false ) {
            theParser.printErrorDump( System.out );
            System.exit( 0 );
    }

    LGJMenuBar theMenubar = theParser.getLGJMenuBar();
    frame.setJMenuBar( theMenuBar );

So, you can see that adding menus, and conditional sections is easy to do, although a little messy.

  • can't really do "else" easily
  • this is 'good enough' for now.

Slide 12: DEMO - ADP Gui

ADP Gui app screenshot

   <LlamaGUI>
   ...
   <Tabs>
       <Tab label="Imgs" ref="/Images/tab">
      <Columns>
          <Col>
         <ImageView bgcolor="LIGHTGRAY" type="single"
               label="waiting for image data..." 
               w="270" h="160"
               ref="/Images/Image1"/>
         <Columns>
             <Col>
            <ComboBox ref="/Images/Image1 Sel"
                 label="" stretch="false">
                <Option>- pause -</Option>
                <Option>SWIR</Option>
                <Option>MWIR</Option>
                <Option selected="true">LWIR</Option>
                <Option>Terrapix</Option>
                <Option>GEO</Option>
                <Option>Fire</Option>
            </ComboBox>
             </Col>
             <Col>
            <Text ref="/Images/Image1 Sequence" editable="false"
                  label="Seq" w="5">0</Text>
             </Col>
             <Col>
            <Text ref="/Images/Image1 Temp" editable="false"
               w="5">?</Text>
             </Col>
         </Columns>
          </Col>
          <Col>
         <ImageView bgcolor="GRAY" type="single"
               label="waiting for image data..." 
               w="270" h="160"
               ref="/Images/Image2"/>
         <Columns>
             <Col>
            <ComboBox ref="/Images/Image2 Sel"
                 label="" stretch="false">
                <Option>- pause -</Option>
                <Option>SWIR</Option>
                <Option selected="true">MWIR</Option>
                <Option>LWIR</Option>
                <Option>Terrapix</Option>
                <Option>GEO</Option>
                <Option>Fire</Option>
            </ComboBox>
             </Col>
             <Col>
            <Text ref="/Images/Image2 Sequence" editable="false"
                  label="Seq" w="5">0</Text>
             </Col>
             <Col>
            <Text ref="/Images/Image2 Temp" editable="false"
               w="5">?</Text>
             </Col>
         </Columns>
          </Col>
      </Columns>
      <Columns>
          <Col>
         <ImageView bgcolor="DARKGRAY" type="single"
               label="waiting for image data..." 
               w="270" h="160"
               ref="/Images/Image3"/>
         <Columns>
             <Col>
            <ComboBox ref="/Images/Image3 Sel"
                 label="" stretch="false">
                <Option>- pause -</Option>
                <Option selected="true">SWIR</Option>
                <Option>MWIR</Option>
                <Option>LWIR</Option>
                <Option>Terrapix</Option>
                <Option>GEO</Option>
                <Option>Fire</Option>
            </ComboBox>
             </Col>
             <Col>
            <Text ref="/Images/Image3 Sequence" editable="false"
                  label="Seq" w="5">0</Text>
             </Col>
             <Col>
            <Text ref="/Images/Image3 Temp" editable="false"
               w="5">?</Text>
             </Col>
         </Columns>
          </Col>
          <Col>
         <ImageView bgcolor="CYAN" type="single"
               label="waiting for image data..." 
               w="270" h="160"
               ref="/Images/Image4"/>
         <Columns>
             <Col>
            <ComboBox ref="/Images/Image4 Sel"
                 label="" stretch="false">
                <Option>- pause -</Option>
                <Option>SWIR</Option>
                <Option>MWIR</Option>
                <Option>LWIR</Option>
                <Option selected="true">Terrapix</Option>
                <Option>GEO</Option>
                <Option>Fire</Option>
            </ComboBox>
             </Col>
             <Col>
            <Text ref="/Images/Image4 Sequence" editable="false"
                  label="Seq" w="5">0</Text>
             </Col>
             <Col>
            <Text ref="/Images/Image4 Temp" editable="false"
               w="5">?</Text>
             </Col>
         </Columns>
          </Col>
      </Columns>
       </Tab>

       <Tab label=" Big " ref="/Big/tab">
          <ImageView type="single"
            label="waiting for image data..." 
            w="500" h="340"
            ref="/Big/Image"/>
      <Columns>
          <Col>
         <ComboBox ref="/Big/Image Sel"
              label="Band:" stretch="false">
             <Option>- pause -</Option>
             <Option>SWIR</Option>
             <Option>MWIR</Option>
             <Option>LWIR</Option>
             <Option>Terrapix</Option>
             <Option>GEO</Option>
             <Option>Fire</Option>
         </ComboBox>
          </Col>
          <Col>
         <Text ref="/Big/Image Sequence" editable="false"
               label="Sequence" w="5">0</Text>
          </Col>
          <Col>
         <Text ref="/Big/Image Temp" editable="false"
            w="5">?</Text>
          </Col>
      </Columns>
       </Tab>

   </Tabs>
   ...
   </LlamaGUI>

Slide 13: Advantages

  • VERY fast prototyping of GUI layouts
  • The prototype is the usable final product
  • The layout and structure of the GUI is easily changed
  • The GUI layout is stored in an xml file, in the jar

  • One 'engine' for your application
  • Multiple front ends for it
    • even in the same file

  • Llama Config class for loading/saving basic data, settings

Slide 14: Design issues

  • conditionals are messy
  • "Columns" are inconvenient - think HTML Tables...
    <Columns>
    <Col>
        ...
    </Col><Col>
        ...
    </Col>
    </Columns>
  • There's gotta be a better way than that...
  • No macro system for even shorter simplifications

Overall though, I think it's advantageous to use it for making Java GUIs.

Slide 15: Integration with the WASP ADP Gui application

ADP Gui app organization

Additional materials used for this presentation are available at http://www.cis.rit.edu/~sdlpci/seminars/

toggleopenShow attachmentstogglecloseHide attachments
Topic attachments
I Attachment Action Size Date Who Comment
pngpng adpgui200603.png manage 95.4 K 01 Feb 2007 - 11:57 ScottLawrence ADP Gui app organization
pngpng ADPGuiDemo.png manage 33.6 K 01 Feb 2007 - 11:57 ScottLawrence ADP Gui app screenshot
wavmp3 LlamaGUI.mp3 manage 7603.8 K 01 Feb 2007 - 11:57 ScottLawrence The presentation as MP3 format
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r2 < r1 | More topic actions
 
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback