Subscribe Bookmark RSS Feed

Arranging lists of controls within a window


I want to create a window in JMP 9 containing an array of different types of controls as shown in the example below.

tb1 = text box(" Elementary "); tb2 = text box(" Intermediate "); tb3 = text box(" Advanced ");

bb1 = border box(tb1); bb1 << set background color("orange") << sides(15);

bb2 = border box(tb2); bb2 << set background color("yellow") << sides(15);

bb3 = border box(tb3); bb3 << set background color("cyan")   << sides(15);

bblist = {};

insert into(bblist, bb1);

insert into(bblist, bb2);

insert into(bblist, bb3);

cb1 = check box(""); cb2 = check box(""); cb3 = check box("");

cblist = {};

insert into(cblist, cb1);

insert into(cblist, cb2);

insert into(cblist, cb3);

ab1 = button box("Chapter 1 References", << underline style(1));

ab2 = button box("Chapter 2 References", << underline style(1));

ab3 = button box("Chapter 3 References", << underline style(1));

ablist = {};

insert into(ablist, ab1);

insert into(ablist, ab2);

insert into(ablist, ab3);

mw = new window("My Window",

       panel box("Controls",

              lineup box(ncol(3),

                     bblist[1], cblist[1], ablist[1],

                     bblist[2], cblist[2], ablist[2],

                     bblist[3], cblist[3], ablist[3]




However, instead of just the three rows I've created above, I don't know in advance how many rows of controls I'm going to need: the actual number will be determined earlier in the script, which is why I've inserted them into a set of lists as I go, which can be as short or as long as I want.  How can I modify the final new window creation command so that it will take in several lists of an unspecified (but equal) length, and get it to set out the various elements in the layout shown?  I've tried an assortment of "for" loops and "eval list"s inside the "new window" command without success, but I still feel this ought to be very easy: I just can't see it.

Many thanks

[PS: Since posting this, I've just spotted a related discussion between "Volf", "Stig" and myself about 18 months ago at, and realised I could apply the solution I came up with then, which was to create the "new window" command in text, using a "for" loop to add as many list elements as I need in the middle of it, and then eval(parse(...)) the end result, or alternatively use Stig's dynamic functions in some way.  I still feel there ought to be an easier way in this instance however - can anybody see one?]

Message was edited by: David Rose


Super User


Jun 23, 2011

I played around with the << append command but got unsatisfactory results:

tb1 = Text Box( "Elementary" );

tb2 = Text Box( "Intermediate" );

tb3 = Text Box( "Advanced" );

tb4 = Text Box( "Expert" );

bb1 = Border Box( tb1 );

bb1 << set background color( "orange" ) << sides( 15 );

bb2 = Border Box( tb2 );

bb2 << set background color( "yellow" ) << sides( 15 );

bb3 = Border Box( tb3 );

bb3 << set background color( "cyan" ) << sides( 15 );

bb4 = Border Box( tb4 );

bb4 << set background color( "green" ) << sides( 15 );

bblist = {};

Insert Into( bblist, bb1 );

Insert Into( bblist, bb2 );

Insert Into( bblist, bb3 );

Insert Into( bblist, bb4 );

cb1 = Check Box( "" );

cb2 = Check Box( "" );

cb3 = Check Box( "" );

cb4 = Check Box( "" );

cblist = {};

Insert Into( cblist, cb1 );

Insert Into( cblist, cb2 );

Insert Into( cblist, cb3 );

Insert Into( cblist, cb4 );

ab1 = Button Box( "Chapter 1 References", <<underline style( 1 ) );

ab2 = Button Box( "Chapter 2 References", <<underline style( 1 ) );

ab3 = Button Box( "Chapter 3 References", <<underline style( 1 ) );

ab4 = Button Box( "Chapter 4 References", <<underline style( 1 ) );

ablist = {};

Insert Into( ablist, ab1 );

Insert Into( ablist, ab2 );

Insert Into( ablist, ab3 );

Insert Into( ablist, ab4 );

mw = New Window( "My Window",

    pb = Panel Box( "Controls",

        lb = Lineup Box( N Col( 3 ), bblist[1], cblist[1], ablist[1], )



For( i = 2, i <= N Items( bblist ), i++,

//    lb << append(bblist, cblist, ablist);

    pb << append( Lineup Box( N Col( 3 ), bblist[i], cblist[i], ablist[i] ) )


You'll probably have to bite the bullet and generate a big text string dynamically and execute it with eval(parse())


Super User


Jun 23, 2011

If Line Up Box supported a list argument or an "Insert db" command it would've been easier. An alternative to iteratively cunstruct and parse a big string for the entire window, one can build a list of display box expressions that can be parsed into any parent display box. Maybe the string method has better performance but I think lists are convenient and you don't have to bother as much with those escape characters. Here's an example:

levels = {" Elementary ", " Intermediate ", " Advanced ", " Expert ", " ὕβρις "};

lub_list = {};

For( i = 1, i <= N Items( levels ), i++, //Build list of displayboxes

  Insert Into( lub_list, Substitute( Expr( Border Box( Text Box( levels[i] ),

          <<set background color( i + 2 ), <<sides( 15 ) ) ), Expr( i ), i ) );

  Insert Into( lub_list, Substitute( Expr( Check Box( "" ) ), Expr( i ), i ) );

  Insert Into( lub_list, Substitute( Expr( Button Box( "Chapter " || Char( i ) || " References",

          <<underline style( 1 ) ) ), Expr( i ), i ))


// Unfortunately LineUpBox does not accept list argument, hence this awkward hack

lub = Parse( "lineupbox(ncol(3), " || Regex( Char( lub_list ), "\{(.*)\}", "\1" ) || ")" );

New Window( "Select level", lub );

Many thanks for the above suggestions, and for the time taken creating the above examples.  Not for the first time I've noted that it would be a good idea to understand regular expressions better than I do at the moment, and use of the "substitute" function (which I'd never used before) came up in another context very recently, so getting to grips with that has also been a useful takeaway.  However it's done it's evidently not a trivial matter, and it's gratifying to know that I hadn't missed an obvious trick here.  Because it was easy both to script and check the syntax I've gone down the eval(parse()) route in this instance, but I can imagine more complex situations in which the above approach would be preferable.

Once again, many thanks.