Eve Application Development

Michael L Brereton - 02 January 2008, http://www.ewesoft.com/

 

Beginners Guide - Contents

<< Previous: Handles And Tasks

>> Next: Images and Pictures

Dynamic Controls

Eve Application Development

Dynamic Controls

Hiding/Showing Controls

The SingleContainer Control

The MultiPanel Interface

The MultiCardPanel Interface

The CardPanel

The TabbedPanel

 

Containers such as Panel and CellPanel are not meant to be easily changed after being displayed. Although this is possible, it can be quite complicated. If you need to change a Control or set of Controls you should either use a SingleContainer or use one of the containers that implement MultiPanel.

Hiding/Showing Controls

It is possible to hide and reveal controls programmatically, while adjusting the size of the containing Window appropriately. To hide a Control and its children call hide(boolean update) on the Control. You can then call unhide(boolean update) to show the Control again. For every call of hide() there must be a matching call of unhide(). Two calls of hide() will require two calls of unhide() to get the Control to reappear.

 

When a Control is hidden or unhidden the relayout() method is invoked on a parent of the Control if the update parameter is true (this should usually be set true). The parent Container that is used defaults to the containing Frame for the Control (determined by getFrame() at runtime)  but this can be changed to a different parent using the method void setHiddenParent(boolean startHidden, Container parent). This method indicates whether the Control should be initially hidden (if startHidden is true) and which parent is to be used for hiding the Control (if it is null it will default to getFrame()). If the hide parent is not the Frame for the Control, then the containing Window will not be resized to adjust to the new layout.

 

The example below illustrates how hide() and unhide() work.

 

package evesamples.ui;
 
import eve.ui.*;
import eve.ui.event.*;
/**
 * This class tests the HideControl class.
 */
//####################################################
public class DynamicPanel extends Form{
     
     private Input searchFor, replaceWith;
     private Button moreDetails, search;
     private CellPanel details;
     private boolean showingDetails;
     private CheckBox matchCase, wholeWord, regularEx, wrapSearch;
     private final String less = " Less Details ";
     private final String more = " More Details ";
     public DynamicPanel()
     {
             title = "Search and Replace";
             InputStack is = new InputStack();
             is.inputLength = 30;
             searchFor = is.addInput("Search For:","Anything");
             replaceWith = is.addInput("Replace With:","Nothing");
             addLast(is).setCell(HSTRETCH);
             //
             details = is = new InputStack();
             is.columns = 2;
             matchCase = is.addCheckBox("Match Case");
             wholeWord = is.addCheckBox("Whole Words");
             regularEx = is.addCheckBox("Regular Expression");
             wrapSearch = is.addCheckBox("Wrap Search");
             is.setText("Search Options");
             addLast(details).setCell(HSTRETCH);
             //
             // Set the details to be initially hidden.
             //
             details.setHiddenParent(true,null);
             //
             addButton(moreDetails = new Button(more));
             moreDetails.modify(NoFocus,0);
             showingDetails = false;
             addButton(search = new Button("Search"));
             //
             doButtons(DEFCANCELB);
     }
     public void onControlEvent(ControlEvent ev)
     {
             if (ev.type == ControlEvent.PRESSED){
                     if (ev.target == moreDetails){
                            if (showingDetails){
                                    moreDetails.setText(more);
                                    details.hide(true);
                            }else{
                                    moreDetails.setText(less);
                                    details.unhide(true);
                            }
                            showingDetails = !showingDetails;
                     }
             }
             super.onControlEvent(ev);
     }
}
 
//####################################################

 

This is how the Form looks when created. The details.setHiddenParent(true,null); line tells the Form that the details control should initially be hidden, and that the parent for unhiding the control should be the full Frame of the Form at runtime (because the parent parameter was null).

 

 

 

After pressing the “More Details” button the Form is updated and the Window is resized to look like this:

 

 

The SingleContainer Control

This is a container that you add a single control to but which will allow that control to be changed dynamically on-screen. You add the first control and change the displayed control using the setControl() methods. That single control can, of course itself be a container, and so you can effectively add and remove any number of controls dynamically by placing them all in a Panel which you then place in a SingleContainer.

 

The example below shows how to use a SingleContainer using an Editor as the base Form. The Editor class will be explained in a later chapter.

 

package evesamples.ui;
 
import eve.fx.Insets;
import eve.sys.Locale;
import eve.ui.*;
import eve.ui.data.Editor;
import eve.util.mVector;
 
public class TestSingleContainer extends Editor{
 
 
     Panel one, two, three;
     SingleContainer single;
//   ===================================================================
     public TestSingleContainer()
//   ===================================================================
     {
             title = "Testing Single Container";
             Panel p = new Panel();
             p.defaultTags.set(Panel.TAG_INSETS,new Insets(2,2,0,0));
             p.setText("Testing the panel");
             Label l;
             p.addNext(l = new MessageArea("Hello\nGood to meet you."));
             l.alignment = l.anchor = RIGHT;
             p.addLast(new Button("There!"));
             p.addNext(l = new MessageArea("How\nNice to see you,\nI trust you are well"));
             l.alignment = CENTER; l.anchor = LEFT;
             p.addLast(new Button("are you doing?")).setTag(TAG_INSETS,new Insets(4,4,4,4));
             p.addLast(new Button("I'm alone"));
             one = p;
             single = new SingleContainer();
             single.setControl(one);
             addLast(single);
             addNext(addField(new Button("One"),"uno")).setCell(HSTRETCH);
             addNext(addField(new Button("Two"),"dos")).setCell(HSTRETCH);
             addNext(addField(new Button("Three"),"tres")).setCell(HSTRETCH);
             two = new CellPanel();
             p = two;
             p.addLast(new Button("are you doing?")).setTag(TAG_INSETS,new Insets(4,4,4,4));
             p.addLast(new Button("I'm alone"));
             three = getLocaleList();
     }
//   ===================================================================
     public void action(String name,Editor ed)
//   ===================================================================
     {
             if (name.equals("uno")) {
                     ed.getWindow().setTitle("First set!");
                     single.setControl(one,true);
             }
             if (name.equals("dos")) {
                     ed.getWindow().setTitle("Second set!");
                     single.setControl(two,true);
             }
             if (name.equals("tres")) {
                     ed.getWindow().setTitle("Third set!");
                     single.setControl(three,true);
             }
     }
 
//   -------------------------------------------------------------------
     static Panel getLocaleList()
//   -------------------------------------------------------------------
     {
             int [] ids = Locale.getAllIDs(0);
             String [] locales = new String[ids.length];
             Locale locale = new Locale();
             for (int i = 0; i<ids.length; i++){
                     locale.set(ids[i]);
                     locales[i] = locale.toString();
             }
             List list = new List(10,40,false);
             mVector.addAll(list.items,locales);
             return new ScrollBarPanel(list);
     }
 
}
 

 

The MultiPanel Interface

Containers which implement this interface allow you to change the control it displays between a set of controls that you add via addItem(Control c, String tabName, String longName). The tabName specifies the on-screen display name for that control. For a tabbed display, this will be displayed in the tab. The longName is an optional name (it may be null) for display in special circumstances and gives a more detailed description of the control being added.

 

The Control being added may itself be placed in another container before being added as an item to the MultiPanel – this is completely up to the implementing MultiPanel. The various select() methods are used to switch between the added controls.

The MultiCardPanel Interface

This is an extension of the MultiPanel interface and it can only be implemented by controls that use a CardPanel as the underlying dynamic control display. It allows for the specifying of more advanced data (such as icons for individual items) and for providing access to the underlying CardPanel.

 

There are two MultiCardPanel implementations provided: a CardPanel and a TabbedPanel.

The CardPanel

This is a MultiCardPanel that can only have its displayed control changed programmatically via the select() methods. That is, the CardPanel provides no user controls to switch between the added controls.

 

The CardPanel is usually used as the main implementation of a MultiPanel – the only extra controls needed is a control or set of controls to allow the user to switch between the available items.

 

The CardPanel, by default, will place all added controls in a ScrollBarPanel, thereby ensuring that its contents will always be fully accessible. However if you do not wish this to happen you can set the autoScroll field to be false.

The TabbedPanel

This is a MultiCardPanel that actually uses a CardPanel for its implementation. In fact you can access its contained CardPanel through the cardPanel field (you would need to do this if you want to switch off the autoScroll feature). It then uses a set of tabs as the user method for switching between the various added controls.

 

The Eve TabbedPanel actually provides significant functionality and flexibility. An entire Chapter on the TabbedPanel class will be done for the advanced UI programming tutorial.