2

I've been trying to create an Option dialog that isn't limited to two or three choices (Option.YesNo or Option.YesNoCancel), but I've been unable to find a way to use anything but these built-in options. Specifically, the following refuses to accept anything that I can put for optionType:

    object Choices extends Enumeration {
      type Choice = Value
      val red, yellow, green, blue = Value
    }
        val options = List("Red", "Yellow", "Green", "Blue")
        label.text = showOptions(null,
                    "What is your favorite color?",
                    "Color preference",
                    optionType = Choices.Value,
                    entries = options, 
                    initial = 2) match {
          case Choice.red => "Red"
          case Choice.yellow => "Yellow"
          case Choice.green => "Green"
          case Choice.blue => "Blue"
          case _ => "Some other color"
        }
David Matuszek
  • 1,263
  • 1
  • 16
  • 30

2 Answers2

1

Yes, it's one of the many design bugs in Scala-Swing. You can write your own showOptions method:

import swing._
import Swing._
import javax.swing.{UIManager, JOptionPane, Icon}

def showOptions[A <: Enumeration](
                parent: Component = null, 
                message: Any, 
                title: String = UIManager.getString("OptionPane.titleText"),  
                messageType: Dialog.Message.Value = Dialog.Message.Question, 
                icon: Icon = EmptyIcon, 
                entries: A,
                initial: A#Value): Option[A#Value] = {
  val r = JOptionPane.showOptionDialog(
                  if (parent == null) null else parent.peer,  message, title, 0, 
                  messageType.id, Swing.wrapIcon(icon),  
                  entries.values.toArray[AnyRef], initial)
  if (r < 0) None else Some(entries(r))
}

val res = showOptions(message = "Color", entries = Choices, initial = Choices.green)

If you want to pass in strings instead, change to entries: Seq[Any], initial: Int, use entries(initial) in the call, and just return r of Int.

0__
  • 66,707
  • 21
  • 171
  • 266
  • That works. I ended up using JOptionPane directly, since I'm more familiar with it. Still, I can't help but wonder if it's really a bug or if I just haven't found the right incantation to make showOptions accept my argument types. – David Matuszek Dec 07 '13 at 02:56
  • It is a bug, because it interprets the result in terms of the `OptionPane.Result` enumeration which will fail for any indices exceeding this enumeration. – 0__ Dec 07 '13 at 03:13
0

optionType isn't for passing in a Scala type, and actually I'm not sure what its purpose is in this API. But you can just set optionType = Options.YesNoCancel, and that should work, I think.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
  • 1
    Options.YesNoCancel works for three of the choices, but crashes on the fourth. – David Matuszek Dec 06 '13 at 19:57
  • Can you be more specific? What happens? – Robin Green Dec 06 '13 at 19:58
  • After using up the three available responses (Result.Yes, Result.No, Result.Cancel), the only remaining thing I can match is _. So after those I use "case _ =>". I can map the three valid responses onto "red", "yellow", "green", but if I click blue, I get "java.util.NoSuchElementException: key not found: 3" instead of my final case. – David Matuszek Dec 06 '13 at 20:49
  • Ah yes. This does seem like a bug in scala-swing. The `showOptions` method really doesn't seem to have been properly designed. – Robin Green Dec 06 '13 at 20:52