How to embed a (working) Button in a Swing Table in Scala?

淺唱寂寞╮ 提交于 2019-12-06 03:43:23

You can make a column ineditable by providing a custom table model. However, your cell must be editable, because that is the only way the editing component becomes 'live' (repaints state changes, receives mouse events).

In the normal rendering (using renderComponent), the component is only used to 'stamp' it, i.e. the table just calls paint on the component. Thus, performance-wise, you should re-use one instance of each rendering component, instead of creating a new Label / Button in every call.

So, you need to override the editor method. Unfortunately it returns a plain javax.swing.table.TableCellEditor, and thus you must step down to the plain javax.swing stuff and loose all the Scala goodness...

The following almost works. Strangely, the button disappears when clicking on it -- have no idea why :-(

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
}

In any case, check the Oracle JTable tutorial for the intricate details of renderers and editors.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!