Swing表rendererComponent中的scala.MatchError

时间:2014-07-08 11:58:36

标签: swing scala

当我尝试使用自定义渲染组件向表中添加新行时,我面临scala.MatchError: 0 (of class java.lang.Integer)

import java.awt.Dimension

import scala.swing.BorderPanel
import scala.swing.Button
import scala.swing.Component
import scala.swing.Panel
import scala.swing.Table
import javax.swing.table.DefaultTableModel
import scala.swing.Label

object MatchErrorInTable {

  def initPanel() : Panel = {
    val tableModel = new DefaultTableModel(Array[Object]("col1", "col2"), 0)
    val panel = new BorderPanel
    class MyRenderer extends Label {
      def prepare(o: String) {
          text = "foo"
      }
    }
    val tcr = new Table.AbstractRenderer[String, MyRenderer](new MyRenderer) {
      def configure(t: Table, sel: Boolean, foc: Boolean, o: String, row: Int, col: Int) = {
        component.prepare(o)
      }
    }
    val table = new Table(0, 2) {
      override protected def rendererComponent(sel: Boolean, foc: Boolean, row: Int, col: Int): Component  = {
        col match {
          case 1 => tcr.componentFor(this, sel, foc, "bar", row, col)
        }
      }
    }
    table.model = tableModel
   val addButton = Button("add") {
      tableModel.addRow(Array[Object]("text", null))
   }

    panel.layout(table) = BorderPanel.Position.Center
    panel.layout(addButton) = BorderPanel.Position.South
    panel
  }

  def main(args: Array[String]) {
    val mainFrame = new MainFrame()
    mainFrame.preferredSize = new Dimension(800, 600)
    mainFrame.contents = initPanel
    mainFrame.visible = true

  }
}

例外:

Exception in thread "AWT-EventQueue-0" scala.MatchError: 0 (of class java.lang.Integer)
    at com.mm.calendar.MatchErrorInTable$$anon$1.rendererComponent(MatchErrorInTable.scala:29)
    at scala.swing.Table$$anon$2$$anon$10.getTableCellRendererComponent(Table.scala:116)
    at scala.swing.Table$$anon$2$$anon$10.getTableCellRendererComponent(Table.scala:114)
    at javax.swing.JTable.prepareRenderer(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
    at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
    at javax.swing.plaf.ComponentUI.update(Unknown Source)
    at javax.swing.JComponent.paintComponent(Unknown Source) 

我如何在rendererComponent中获得java.lang.Integer?

我主要是基于我的解决方案:
Idiomatic table cell renderers in Scala

我使用的是2.11.1版本。

1 个答案:

答案 0 :(得分:0)

如果你添加另一个

      case _ => tcr.componentFor(this, sel, foc, "foo", row, col)

作为def rendererComponent中匹配的后退,它至少可以无异常地工作。

模型中有两列,实际列索引为零和一;这些传递给rendererComponent


要获得完整的演示:

import swing._
import javax.swing.table.DefaultTableModel

object MatchErrorInTable {

  def initPanel(): Panel = {
    val tableModel = new DefaultTableModel(Array[Object]("col1", "col2"), 0)
    val panel = new BorderPanel
    class MyRenderer extends Label {
      def prepare(o: String) {
        text = o // changed
      }
    }
    val tcr = new Table.AbstractRenderer[String, MyRenderer](new MyRenderer) {
      def configure(t: Table, sel: Boolean, foc: Boolean, o: String, row: Int, col: Int) = {
        component.prepare(o)
      }
    }
    val table = new Table(0, 2) {
      override protected def rendererComponent(sel: Boolean, foc: Boolean, row: Int, col: Int): Component = {
        col match {
          case 0 => tcr.componentFor(this, sel, foc, tableModel.getValueAt(row, 0).toString, row, col) // changed
          case 1 => tcr.componentFor(this, sel, foc, tableModel.getValueAt(row, 1).toString, row, col) // changed
        }
      }
    }
    table.model = tableModel
    val addButton = Button("add") {
      tableModel.addRow(Array[Object]("text 1", "text 2")) // changed
    }

    panel.layout(table) = BorderPanel.Position.Center
    panel.layout(addButton) = BorderPanel.Position.South
    panel
  }

  def main(args: Array[String]) {
    val mainFrame = new Frame()
    mainFrame.preferredSize = new Dimension(800, 600)
    mainFrame.contents = initPanel()
    mainFrame.visible = true

  }
}

这样,您添加到模型中的值将显示在表格中。 当然,在这个片段中,两个case语句没有多大意义;在这种情况下,match不是必需的,因为您总是使用相同的渲染器组件。