3

我正在尝试使用 Scala/Swing 创建一个表,其中一个列由Buttons 填充。

我的出发点是Odersky 等人的书中的SCells 电子表格示例,特别是使用来控制每个单元格中的出现。rendererComponentComponent

不幸的是,虽然这成功创建了一个按钮,但该按钮不可点击。这是一个相当小且独立的示例:

import swing._
import swing.event._

class TableButtons extends ScrollPane {
  viewportView = new Table(2,2) {
    rowHeight = 25
    override def rendererComponent(isSelected: Boolean, hasFocus: Boolean,
                                   row: Int, column: Int): Component =
      if (column == 0) {
        new Label("Hello")
      } else {
        val b = new Button { text = "Click" }
        listenTo(b)
        reactions += {
          case ButtonClicked(`b`) => println("Clicked")
        }
        b
      }
  }
}

object Main extends SimpleSwingApplication {
  def top = new MainFrame {
    title = "Table button test"
    contents = new TableButtons
  }
}

当我运行它时,我得到一个有两列的表;第一个包含标签,第二个包含按钮,但按钮不可点击。

可能相关的问题:单元格(包括包含按钮的单元格)是可编辑的。禁用编辑的最佳方法是什么?

我已经看到了这个问题(和这个问题),并尝试按照那里的方法(使用Table.AbstractRenderer),但这也不起作用——而且对我来说,在该版本中对按钮点击做出反应的地方并不明显。(这种方法过时了吗?还是 Scala 书中的方法过于简单?)

感谢您的任何建议!

4

1 回答 1

3

您可以通过提供自定义表模型使列不可编辑。但是,您的单元格必须是可编辑的,因为这是编辑组件变为“活动”的唯一方式(重新绘制状态更改,接收鼠标事件)。

在正常渲染中(使用renderComponent),组件仅用于“标记”它,即表格只是调用paint组件。因此,在性能方面,您应该重用每个渲染组件的一个实例,而不是在每次调用中创建一个新的Label/ 。Button

因此,您需要覆盖该editor方法。不幸的是,它返回了一个 plain javax.swing.table.TableCellEditor,因此你必须降级到简单的javax.swing东西并失去所有 Scala 的优点......

以下几乎可以工作。奇怪的是,单击按钮时按钮消失了-不知道为什么:-(

import scala.swing._
import scala.swing.event._
import javax.swing.{AbstractCellEditor, JTable}
import javax.swing.table.TableCellEditor
import java.awt.{Component => AWTComponent}

 

class TableButtons extends ScrollPane {
  private val lb = new Label("")
  private val b  = new Button

  private val buttonEditor = new AbstractCellEditor with TableCellEditor {
    listenTo(b)
    reactions += {
      case ButtonClicked(`b`) => 
        println("Clicked")
        fireEditingStopped()
    }
    def getCellEditorValue: AnyRef = "what value?"
                               // ouch, we get JTable not scala.swing.Table ...
    def getTableCellEditorComponent(tab: JTable, value: AnyRef, isSelected: Boolean,
                                       row: Int, col: Int): AWTComponent = {
      b.text = "Click!"
      b.peer  // ouch... gotta go back to AWT
    }
  }

  viewportView = new Table(2, 2) {
    rowHeight = 25
    override def rendererComponent(isSelected: Boolean, hasFocus: Boolean,
                                   row: Int, column: Int): Component =
      if (column == 0) {
        lb.text = "Hello"
        lb
      } else {
        b.text = "Click?"
        b
      }

    override def editor(row: Int, col: Int): TableCellEditor =
      if (col == 1) buttonEditor else super.editor(row, col)
  }
}

 

val top = new Frame {
  title = "Table button test"
  contents = new TableButtons
  pack()
  visible = true
}

无论如何,请查看Oracle JTable 教程以了解渲染器和编辑器的复杂细节。

于 2011-12-27T10:18:02.953 回答