4
$\begingroup$

Possible Duplicate:
Wrapping EventHandler by Table

I am running Mathematica 7. However, I am new to using Dynamic, DynamicModule, EventHandler, and the like.

I would like to create a Graphics object containing numDisks Disk objects, where numDisks is a positive integer. I would like each of the Disk objects to be Red, Green, or Blue. The default color is Red, but if a disk is clicked, that disk goes to the next color, cyclically (Red-->Green-->Blue-->Red-->...). Is it possible to accomplish this using a DynamicModule and multiple EventHandler declarations?

I have tried the following. This code generates numDisks disks in a row. When the user clicks anywhere within the Graphics box, the color of all three disks changes to the next color in the sequence.

radius = 1;
numDisks = 3;

DynamicModule[{col = Red},
 EventHandler[
  Graphics[
   Table[{Dynamic[col], Disk[{2.5*(i - 1), 0}, radius]}, {i, 1, 
     numDisks}],
   PlotRange -> All],
  {"MouseClicked" :> (col = 
      col /. {Red -> Green, Green -> Blue, Blue -> Red})}]
 ]

Three Disks

However, what if I would like each of the numDisks Disk objects to have its own color, which can be changed independently of that of all of the other Disk objects? Is this possible? Can this be accomplished somehow using multiple EventHandler declarations? Thanks for your time.

$\endgroup$
2
  • 1
    $\begingroup$ Possible duplicate: mathematica.stackexchange.com/q/13440/121 $\endgroup$
    – Mr.Wizard
    Jan 19, 2013 at 18:35
  • $\begingroup$ To the person who voted to reopen: please tell me why. I would be happy to reopen this if you can explain to me why it is not a duplicate. By my reading and by comparing the Accepted answers to both questions I think it is. $\endgroup$
    – Mr.Wizard
    Jan 19, 2013 at 22:59

1 Answer 1

5
$\begingroup$

You want to create an independent DynamicModule for each EventHandler. Otherwise, the single variable col will control the color for all of the disks, as you're witnessing. Your code can be rearranged as follows:

radius = 1;
numDisks = 3;

Graphics[Table[
  DynamicModule[{col = Red}, 
   EventHandler[{Dynamic[col], 
     Disk[{2.5*(i - 1), 0}, 
      radius]}, {"MouseClicked" :> (col = 
        col /. {Red -> Green, Green -> Blue, Blue -> Red})}]], {i, 1, 
   numDisks}], PlotRange -> All]

EDIT:

Okay...per your request in the comments, here's a variation which uses a single DynamicModule, but makes the col variable a list which is then referenced separately by the individual EventHandler constructs. The only thing that's tricky about this is that you have to inject the value of i from the Table inside of EventHandler and Dynamic using With.

radius = 1;
numDisks = 3;

DynamicModule[{col = Table[Red, {numDisks}]}, Column[{
   Graphics[
    Table[With[{i = i}, 
      EventHandler[{Dynamic[col[[i]]], 
        Disk[{2.5*(i - 1), 0}, 
         radius]}, {"MouseClicked" :> (col[[i]] = 
           col[[i]] /. {Red -> Green, Green -> Blue, 
             Blue -> Red})}]], {i, 1, numDisks}], PlotRange -> All],
   Dynamic[col]}]]

I wrapped this with a Column just to illustrate what the value of col is and the principle that you could access col from code outside of the graphic.

$\endgroup$
1
  • $\begingroup$ Thank you! This might be a separate question, but is it possible to somehow save the current color state of each Disk to a list? For example, suppose that I have three disks: (1), (2), and (3). Further suppose that I click the disks so that disk (1) becomes Red, (2) becomes Green, and (3) becomes Blue. Is it possible to save -- perhaps dynamically -- the current color states of (1), (2), and (3) to a list? $\endgroup$
    – Andrew
    Jan 19, 2013 at 18:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.