如何在 scala.swing.Table 中添加 ComboBox 作为单元格编辑器?
How to add ComboBox as a cell editor in scala.swing.Table?
我正在尝试为 Scala Swing 应用程序的第二列中的每个单元格添加 ComboBox 作为列单元格编辑器,但很难做到。下面的代码显示了我到目前为止所做的尝试,请帮助我更改代码以完成任务。
import swing._
import javax.swing.JComboBox
import javax.swing.table.AbstractTableModel
import javax.swing.DefaultCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
class MyModel(var cells: Array[Array[Any]], val columns: Array[Any] ) extends AbstractTableModel {
def getRowCount(): Int = cells.length
def getColumnCount(): Int = columns.length
def getValueAt(row: Int, col: Int): AnyRef = cells(row)(col).asInstanceOf[AnyRef]
override def getColumnClass(column: Int) = getValueAt(0, column).getClass
override def isCellEditable(row: Int, column: Int) = if (column == 0) false else true
override def setValueAt(value: Any, row: Int, col: Int) {
cells(row)(col) = value
fireTableCellUpdated(row, col)
}
override def getColumnName(column: Int): String = columns(column).toString
}
//////////////////////////////////////////////////////////////////////////////////////////////////
class TestTable extends ScrollPane {
final val columns: Array[Any] = Array[Any]( "Column1", "Column2" )
final val Col1Data: Array[Any] = Array[Any]( "Col1_Data",
"Col2_Data", "Col3_Data", "Col4_Data", "Col5_Data", "Col6_Data"
)
var modelarr = Array.ofDim[Any](Col1Data.length, columns.length)
for (i <- 0 until Col1Data.length) {
modelarr(i)(0) = Col1Data(i)
// Have tried to set it to 1/"Value2"
modelarr(i)(1) = "Value2"
}
val table = new Table( modelarr, columns ) {
val mymodel = new MyModel(modelarr, columns)
model = mymodel
val Col1 = peer.getColumnModel.getColumn( 1 )
val cb = new JComboBox[String](Array("Value1", "Value2", "Value3"))
Col1.setCellEditor( new DefaultCellEditor( cb ) )
}
viewportView = table
}
//////////////////////////////////////////////////////////////////////////////////////////////////
object MyCombo extends SimpleSwingApplication {
override def main(args: Array[String]) = super.main(args)
var mytable = new TestTable
def top = new MainFrame {
title = "Table Test"
contents = mytable
}
}
更新:
刚发现类似问题:How to embed a (working) Button in a Swing Table in Scala?将尝试建议的方法。
感谢 Nickal 的提示。我自己的解决方案是原始代码的修改版本,并仅在此处发布更改。
修改后的导入块:
import scala.swing._
import scala.swing.Swing._
import javax.swing._
import javax.swing.table.{TableCellEditor, AbstractTableModel}
import java.awt.{Component => AWTComponent}
添加了两个特征以能够在新的 class 中混合 java classes:
//////////////////////////////////////////////////////////////////////////////////////////////////
trait AbstractCellEditorTrait extends AbstractCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
trait TableCellEditorTrait extends TableCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
class comboboxEditor(val currentValue: AnyRef) extends AbstractCellEditorTrait with TableCellEditorTrait {
private val cb = new ComboBox(Array("Value1", "Value2", "Value3"))
cb.selection.item = currentValue.toString
def getCellEditorValue: AnyRef = cb.selection.item.asInstanceOf[AnyRef]
def getTableCellEditorComponent(tab: JTable, value: AnyRef, isSelected: Boolean, row: Int, col: Int): AWTComponent = {
cb.peer.asInstanceOf[AWTComponent]
}
}
修改代码,在 TestTable
class 中设置单元格编辑器(以 val Col1 = peer.g
开头的 3 行代码替换为以下代码):
override def editor(row: Int, col: Int): TableCellEditor = {
if (col == 1)
new comboboxEditor(mymodel.getValueAt(row, col))
else
super.editor(row, col)
}
基于e_z的代码,我为通用代码分离出一个BaseEditor
摘要class,因为最终我需要还实施 isCellEditable
。在 BaseEditor
的 sub-class 中,您需要一个 editor
的实例,它是您的组件并实现 getCellEditorValue
.
abstract class BaseEditor extends AbstractCellEditor with TableCellEditor {
protected val editor: Component // scala.swing.Component
override def isCellEditable(e: EventObject): Boolean= {
if (super.isCellEditable(e)) {
e match {
case me: java.awt.event.MouseEvent => me.getClickCount >= 2
case ke: java.awt.event.KeyEvent =>
// F2 not working, for some reason keypress arrives as ActionEvent
ke.getKeyCode == java.awt.event.KeyEvent.VK_F2
case ae: java.awt.event.ActionEvent => false // ignore for now
case x => false // otherwise ignore
}
} else false
}
def getTableCellEditorComponent(table: JTable, value: AnyRef,
selected: Boolean, row: Int, col: Int): AWTComponent= {
editor.peer.asInstanceOf[AWTComponent]
}
}
// example extending BaseEditor and custom StringData object
case class StringData(s: String)
class TextFieldEditor(current: StringData) extends BaseEditor {
protected val editor= new TextField(current.s)
def getCellEditorValue: AnyRef= StringData(editor.text)
}
我正在尝试为 Scala Swing 应用程序的第二列中的每个单元格添加 ComboBox 作为列单元格编辑器,但很难做到。下面的代码显示了我到目前为止所做的尝试,请帮助我更改代码以完成任务。
import swing._
import javax.swing.JComboBox
import javax.swing.table.AbstractTableModel
import javax.swing.DefaultCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
class MyModel(var cells: Array[Array[Any]], val columns: Array[Any] ) extends AbstractTableModel {
def getRowCount(): Int = cells.length
def getColumnCount(): Int = columns.length
def getValueAt(row: Int, col: Int): AnyRef = cells(row)(col).asInstanceOf[AnyRef]
override def getColumnClass(column: Int) = getValueAt(0, column).getClass
override def isCellEditable(row: Int, column: Int) = if (column == 0) false else true
override def setValueAt(value: Any, row: Int, col: Int) {
cells(row)(col) = value
fireTableCellUpdated(row, col)
}
override def getColumnName(column: Int): String = columns(column).toString
}
//////////////////////////////////////////////////////////////////////////////////////////////////
class TestTable extends ScrollPane {
final val columns: Array[Any] = Array[Any]( "Column1", "Column2" )
final val Col1Data: Array[Any] = Array[Any]( "Col1_Data",
"Col2_Data", "Col3_Data", "Col4_Data", "Col5_Data", "Col6_Data"
)
var modelarr = Array.ofDim[Any](Col1Data.length, columns.length)
for (i <- 0 until Col1Data.length) {
modelarr(i)(0) = Col1Data(i)
// Have tried to set it to 1/"Value2"
modelarr(i)(1) = "Value2"
}
val table = new Table( modelarr, columns ) {
val mymodel = new MyModel(modelarr, columns)
model = mymodel
val Col1 = peer.getColumnModel.getColumn( 1 )
val cb = new JComboBox[String](Array("Value1", "Value2", "Value3"))
Col1.setCellEditor( new DefaultCellEditor( cb ) )
}
viewportView = table
}
//////////////////////////////////////////////////////////////////////////////////////////////////
object MyCombo extends SimpleSwingApplication {
override def main(args: Array[String]) = super.main(args)
var mytable = new TestTable
def top = new MainFrame {
title = "Table Test"
contents = mytable
}
}
更新:
刚发现类似问题:How to embed a (working) Button in a Swing Table in Scala?将尝试建议的方法。
感谢 Nickal 的提示。我自己的解决方案是原始代码的修改版本,并仅在此处发布更改。
修改后的导入块:
import scala.swing._
import scala.swing.Swing._
import javax.swing._
import javax.swing.table.{TableCellEditor, AbstractTableModel}
import java.awt.{Component => AWTComponent}
添加了两个特征以能够在新的 class 中混合 java classes:
//////////////////////////////////////////////////////////////////////////////////////////////////
trait AbstractCellEditorTrait extends AbstractCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
trait TableCellEditorTrait extends TableCellEditor
//////////////////////////////////////////////////////////////////////////////////////////////////
class comboboxEditor(val currentValue: AnyRef) extends AbstractCellEditorTrait with TableCellEditorTrait {
private val cb = new ComboBox(Array("Value1", "Value2", "Value3"))
cb.selection.item = currentValue.toString
def getCellEditorValue: AnyRef = cb.selection.item.asInstanceOf[AnyRef]
def getTableCellEditorComponent(tab: JTable, value: AnyRef, isSelected: Boolean, row: Int, col: Int): AWTComponent = {
cb.peer.asInstanceOf[AWTComponent]
}
}
修改代码,在 TestTable
class 中设置单元格编辑器(以 val Col1 = peer.g
开头的 3 行代码替换为以下代码):
override def editor(row: Int, col: Int): TableCellEditor = {
if (col == 1)
new comboboxEditor(mymodel.getValueAt(row, col))
else
super.editor(row, col)
}
基于e_z的代码,我为通用代码分离出一个BaseEditor
摘要class,因为最终我需要还实施 isCellEditable
。在 BaseEditor
的 sub-class 中,您需要一个 editor
的实例,它是您的组件并实现 getCellEditorValue
.
abstract class BaseEditor extends AbstractCellEditor with TableCellEditor {
protected val editor: Component // scala.swing.Component
override def isCellEditable(e: EventObject): Boolean= {
if (super.isCellEditable(e)) {
e match {
case me: java.awt.event.MouseEvent => me.getClickCount >= 2
case ke: java.awt.event.KeyEvent =>
// F2 not working, for some reason keypress arrives as ActionEvent
ke.getKeyCode == java.awt.event.KeyEvent.VK_F2
case ae: java.awt.event.ActionEvent => false // ignore for now
case x => false // otherwise ignore
}
} else false
}
def getTableCellEditorComponent(table: JTable, value: AnyRef,
selected: Boolean, row: Int, col: Int): AWTComponent= {
editor.peer.asInstanceOf[AWTComponent]
}
}
// example extending BaseEditor and custom StringData object
case class StringData(s: String)
class TextFieldEditor(current: StringData) extends BaseEditor {
protected val editor= new TextField(current.s)
def getCellEditorValue: AnyRef= StringData(editor.text)
}