0

I'm attempting Exercise 22.3.3 from HtDP but do not know how to retrieve the label of the button that was clicked. I get this message draw-message: expected <string> as second argument, given: (instantiate (class ...) ...) which seems to suggest that I need a string but I'm getting an instance of a class. Is the answer in the callback? If so, how do I de-structure it?


This is what I have so far:

(define pad1
  '((1 2 3)
    (4 5 6)
    (7 8 9)
    (\# 0 *)))

(define pad2 
  '((1 2 3  +)
    (4 5 6  -)
    (7 8 9  *)
    (0 = \. /)))

(define (title t)
  (make-message t))

(define display
  (make-message ""))

(define (pad->gui p)
  (cond
    [(empty? p) empty]
    [else (cons (button-maker (first p))
                (pad->gui (rest p)))]))

;; make buttons out of a list
(define (button-maker a-list)
  (cond
    [(empty? a-list) empty]
    [(number? (first a-list))(cons (make-button (number->string (first a-list)) call-back)
                                   (button-maker (rest a-list)))]
    [(symbol? (first a-list))(cons (make-button (symbol->string (first a-list)) call-back)
                                   (button-maker (rest a-list)))]))

(define (call-back b)
  (draw-message display ...))


(create-window
 (append (list (list (title "Virtual Phone")))
         (list (list display))
         (pad->gui pad1)))

If I understand things correctly, each button will call call-back when it is pressed. This in turn should call display which will update the text. However, I do not understand how to retrieve the caller's label. e.g. if the button "9" is pressed, it will call call-back. But how do I retrieve the value "9"? This is what I'm unsure about.

soegaard
  • 30,661
  • 4
  • 57
  • 106
Greenhorn
  • 411
  • 1
  • 6
  • 14

1 Answers1

3

Correct. The draw-message function consumes a 'window' and a 'string', which is documented in figure 62 in the same section. You seem to be applying it to a 'button object'. Also see example 2 in the same section, which looks like this:

(define a-text-field
  (make-text "Enter Text:"))

(define a-message
  (make-message "`Hello World' is a silly program."))

(define (echo-message e)
  (draw-message a-message (text-contents a-text-field)))

(define w (create-window
           (list (list a-text-field a-message)
                 (list (make-button "Copy Now" echo-message)))))

See how echo-messsage changes the display when you click the 'copy now' button.

Hint: since you have one callback per button, you know exactly which string to send to the display from which button callback.

Correction: Example 1 in the book is broken. Use

 (define u
  (create-window (list (list (make-button "Close" (lambda (x) (hide-window u)))))))

instead.

erjiang
  • 44,417
  • 10
  • 64
  • 100
  • Matthias, I see you are one of the book's authors; thank you for making time to respond, and also for an excellent resource for learning Racket/Scheme. I've amended my question above, please take a look at it and if you could, see where I have gone wrong. BTW, `lambda` is not introduced until Section 24 so the corrected example 1 won't work unless language has been set to Advanced or higher. – Greenhorn Jan 06 '11 at 15:55
  • I think [Collection of Great Applications and Programs using Macros](http://stackoverflow.com/q/4548768/298282) may be interesting for you, too. – YasirA Jan 06 '11 at 17:28