Как вставить (работающую) кнопку в Swing Table в Scala? - PullRequest
3 голосов
/ 26 декабря 2011

Я пытаюсь использовать Scala / Swing для создания таблицы, один из столбцов которой заполнен Button s.

Моя отправная точка - это таблица из книги Одерского и др., В частности, rendererComponent для управления Component, появляющимся в каждой ячейке *. 1010 *

К сожалению, хотя при этом кнопка создается успешно, кнопка не активна. Вот разумно минимальный и самостоятельный пример:

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 слишком упрощен?)

Спасибо за любой совет!

1 Ответ

3 голосов
/ 27 декабря 2011

Вы можете сделать столбец не редактируемым, указав собственную модель таблицы.Однако ваша ячейка должна быть редактируемой, потому что это единственный способ, которым компонент редактирования становится «живым» (перерисовывает изменения состояния, получает события мыши).

При обычном рендеринге (с использованием renderComponent) компонентиспользуется только для «печати», т. е. таблица просто вызывает paint для компонента.Таким образом, с точки зрения производительности вы должны повторно использовать один экземпляр каждого компонента рендеринга вместо создания нового Label / Button в каждом вызове.

Итак, вам необходимо переопределить editorметод.К сожалению, он возвращает простой 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 учебник для сложной информации о средствах визуализации и редакторах.

...