3

I'm currently trying to create a a grid of information in Racket using the Racket Graphical Interface Tooling. The only real table that is available is the list-box% (link to reference)

To fill the table I need to use:

 (send a-list-box set choices ...) → void?
      choices : (listof label-string?)

choices being list being a list of each column. The problem is that I have a variable amount of collumns. My current data is formated like (list (list 1 2 3) (list 4 5 6)). The goal is te execute this command: (send table set (list 1 2 3) (list 4 5 6)

What I already tried

I made a function witch gives me this output: "(list 1 2 3) (list 4 5 6)" The idea was to then execute this string command using:

(send table set (eval (call-with-input-string "(list 1 2 3) (list 4 5 6)" read)

I also tried this:

(eval (call-with-input-string "(send table set (list 1 2 3) (list 4 5 6))" read) But this gives me an error table: undefined; cannot reference an identifier before its definition

If you don't see a problem but now an other way to display a grid of data in racket using the build in GUI, please share. Thanks

Test Code

`#lang racket
(require racket/gui/base)

(define frame (new frame% 
                  [label "myTable"]
                  [width 800]
                  [height 600]
                  ))

(define table (new list-box%
                 [parent frame]
                 [choices (list )]
                 [label "Test"]
                 [style (list 'single 'column-headers 'variable-columns)]
                 [columns (list "C1" "C2" "C3")]))

(define data (list (list "1" "2" "3")
                   (list "4" "5" "6")
                   (list "6" "8" "9")))


(send table set (list-ref data 0) (list-ref data 1) (list-ref data 2));--> Works but needs to be aple to handle variable lengtho of data
;(apply send table set data) ;--> ERROR: send: bad syntax

;(map (lambda (element)
;             (send table set element)) ;--> ERROR: set in list-box%: column count doesn't match argument count  column count: 3  argument count: 1
;     data)

(send frame show #t)`
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Timbo925
  • 281
  • 4
  • 16

3 Answers3

2

Looks like send/apply is what you want.

(send/apply table set data)
stchang
  • 2,555
  • 15
  • 17
1
(define your-listbox-var (new list-box%
                      (label "")
                      (parent YOUR MAIN FRAME OR NULL)
                      (choices '("" "" "") )
                      (style (list 'single ; je kunt ze nog veranderen
                                   'variable-columns
                                   'column-headers))
                      (columns (list "Column1" "Column2" "Column3" ))))

If you define your variabele in this way, and if you call

(send your-listbox-var set  (list 1 2 3)  (list 1 2 3))

AFTER the definition of variabele, it will work.

Asqan
  • 4,319
  • 11
  • 61
  • 100
  • 1
    The problem is in my code I get the data as `(define data (list (list 1 2 3) (list 1 2 3))` If I then do `(send table set data)` it wont work. I need to get all the lists out of the data variable but can't find a way to do this. – Timbo925 May 20 '13 at 13:01
  • you have to send the lists separately. In your case; '(send table set (car data) (cadr data))' – Asqan May 20 '13 at 15:00
1

Try this:

(define data '((1 2 3) (4 5 6)))
(apply send table set data) ; same as (send table set '(1 2 3) '(4 5 6))

Use apply when your input arguments arrive in a list of unknown size and the procedure accepts a variable number of parameters. For a simpler example:

(define data '(1 2 3))
(apply + data) ; same as (+ 1 2 3)
=> 6

You can imagine that apply "removes" the extra parenthesis around its last argument, so that this: (apply + '(1 2 3)) becomes this: (+ 1 2 3).

UPDATE

Given that send is a macro and not a procedure as I had incorrectly assumed, the above won't work. I came up with a solution I'm not proud of, using eval (which is evil) and list splicing - I hope someone can suggest a cleaner solution, but this will work:

(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
(eval `(send table set ,@'data) ns)
Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Doesn't work. Getting bad syntax error for send. I added a piece of test file code to the first post where I'm testing possible solutions. apply seems like a good idea so will try to fix the error – Timbo925 May 20 '13 at 14:01
  • 1
    Ugh, that happens because `send` it's not a procedure, but a macro. Then `apply` won't work, and a macro must be used in its place – Óscar López May 20 '13 at 14:05
  • Ok so I need to write my own macro to do this? What should this macro do? Never did it so I'll start reading the documentation. – Timbo925 May 20 '13 at 15:06
  • Thanks for the trouble. For the moment I fixed it by using a big `cond` witch manually does executes the the `(send ...)` for a list not bigger then 10. Not very pretty and not good code but works for now. – Timbo925 May 20 '13 at 15:51
  • 2
    @Timbo925 I figured out a workaround, using `eval`. See my updated answer. – Óscar López May 20 '13 at 16:54
  • To avoid the `eval` you can use `dynamic-send`. – Diego Sevilla Aug 23 '13 at 23:02