1

我正在尝试实现一个简单的应用程序,在该应用程序中我可以在 Textfield 中编写一个项目,然后输入一个按钮,该按钮反过来通过将该项目插入组合框中来做出反应。

但是,我面临一个问题,即 scala 组合框摆动不可变(我猜)?

有没有办法使用 scala swing 使组合可变?

import scala.swing._
import scala.swing.event._
import scala.swing.BorderPanel.Position._

object ReactiveSwingApp extends SimpleSwingApplication {
  def top = new MainFrame {
    title = "Reactive Swing App"

    val button = new Button {
      text = "Add item" 
    }   
    var textfield = new TextField {
      text = "Hello from a TextField"
    }

    var items = List("Item 1","Item 2","Item 3","Item 4")
    val combo = new ComboBox(items)

    contents = new BorderPanel {
      layout(new BoxPanel(Orientation.Vertical) {
          contents += textfield 
          contents += button
          contents += combo   
          border = Swing.EmptyBorder(30, 30, 10, 30)
      }) = BorderPanel.Center
    }

    listenTo(button, textfield)
    reactions += {
      case ButtonClicked(button) =>
        // var items1 = textfield.text :: items  <- how can a read Item be inserted
    }
  }
}
4

2 回答 2

2

你是对的,Scala-SwingComboBox包装器JComboBox有一个不允许添加或删除的静态模型。不幸的是,Scala-Swing 中有很多功能不如底层 Java-Swing 组件。

然而,好消息是每个 Scala-Swing 组件都有一个 Java-Swingpeer字段,您可以使用它来修补缺失的位。我认为最简单的方法是创建一个薄包装器javax.swing.DefaultComboBoxModel,例如:

class ComboModel[A] extends javax.swing.DefaultComboBoxModel {
  def +=(elem: A) { addElement(elem) }
  def ++=(elems: TraversableOnce[A]) { elems.foreach(addElement) }
}

然后你的构造变成

val combo = new ComboBox(List.empty[String])
val model = new ComboModel[String]
model ++= items
combo.peer.setModel(model)  // replace default static model

而你的反应

reactions += {
  case event.ButtonClicked(button) =>
    model += textfield.text
}
于 2013-03-28T19:46:14.017 回答
0

在“0___”,你测试过你的代码吗?它似乎有一些不匹配的问题。我正在使用 scala 2.10。

实际上有一种方法可以解决这个问题,而不必处理 ComboBoxModel。这是一个简短的例子:

class ComboBox(items: Array[String])
extends scala.swing.Component with java.awt.event.ActionListener with Publisher{

  override lazy val peer = new JComboBox(items)

  def +=(item: String) = peer.addItem(item)
  def -=(item: String) = peer.removeItem(item)
  def item = peer.getSelectedItem.asInstanceOf[String]
  def reset{peer.setSelectedIndex(0)}
  //additional methods

  //since its peer val is now a JComboBox

  peer.addActionListener(this)
  def actionPerformed(e: ActionEvent){
    //how to react once the selection changes
  }

  //since its also a scala.swing.Component extender
  listenTo(mouse.clicks) //and all the rest of the Publishers
  reactions += {
    case e: MouseClicked => //do something awesome
  }

  /* Also one could additionally extend the scala.swing.Publisher Trait
   * to be able to publish an event from here.
   */
  publish(MyEvent(item))
}

case class MyEvent(item: String) extends Event
于 2013-09-01T22:59:20.953 回答