Skip to content

Commit 3d4b409

Browse files
committed
scala: JTable replaced by scala's Table
1 parent 3391e18 commit 3d4b409

File tree

2 files changed

+97
-113
lines changed

2 files changed

+97
-113
lines changed

RubyScript/src/org/knime/ext/jruby/RubyScriptNodeDialog.scala

Lines changed: 91 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import javax.swing.BoxLayout
99
import javax.swing.DefaultCellEditor
1010
import javax.swing.JFileChooser
1111
import javax.swing.JComboBox
12-
import javax.swing.JPanel
13-
import javax.swing.JTable
1412
import javax.swing.table.TableColumn
1513
import javax.swing.table.TableCellEditor
1614
import javax.swing.text.BadLocationException
@@ -20,7 +18,6 @@ import org.knime.core.data.DataTableSpec
2018
import org.knime.core.node._
2119
import org.knime.core.node.workflow.FlowVariable
2220

23-
import javax.swing.JScrollPane
2421
import java.awt.Font
2522

2623
import org.fife.ui.rtextarea._
@@ -34,6 +31,7 @@ import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator
3431

3532
import scala.swing._
3633
import scala.swing.event._
34+
import scala.swing.Table
3735

3836
/**
3937
* <code>NodeDialog</code> for the "JRuby Script" Node.
@@ -62,35 +60,33 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
6260

6361
private var spErrorMessage: ScrollPane = _
6462

65-
private var table: JTable = _
63+
private var table: Table = _
6664

6765
private var columnCounter: Int = 1
6866

6967
private var doAppendInputColumns: CheckBox = _
7068

71-
private var columnTables: Array[JTable] = _
69+
private var columnTables: Array[Table] = _
7270

7371
private val fileChooser = new JFileChooser()
7472

7573
createColumnSelectionTab()
7674

7775
createScriptTab()
7876

79-
implicit private def toTableModel(table: JTable):ScriptNodeOutputColumnsTableModel = {
80-
table.getModel.asInstanceOf[ScriptNodeOutputColumnsTableModel]
77+
implicit private def toTableModel(table: Table):ScriptNodeOutputColumnsTableModel = {
78+
table.model.asInstanceOf[ScriptNodeOutputColumnsTableModel]
8179
}
82-
8380
/**
8481
* Create column selection tab panel
8582
*/
8683
private def createColumnSelectionTab() {
87-
val outputPanel = new JPanel()
88-
outputPanel.setLayout(new BoxLayout(outputPanel, BoxLayout.Y_AXIS))
89-
val outputButtonPanel = new JPanel()
90-
val outputMainPanel = new JPanel(new BorderLayout())
91-
val newtableCBPanel = new JPanel()
84+
val outputPanel = new BoxPanel(Orientation.Vertical)
85+
val outputButtonPanel = new BoxPanel(Orientation.Horizontal)
86+
val outputMainPanel = new BorderPanel()
87+
val newtableCBPanel = new BorderPanel()
9288
doAppendInputColumns = new CheckBox("Append columns to input table spec")
93-
newtableCBPanel.add(doAppendInputColumns.peer, BorderLayout.WEST)
89+
newtableCBPanel.peer.add(doAppendInputColumns.peer, BorderLayout.WEST)
9490
val addButton = new Button("Add Output Column") {
9591
reactions += {
9692
case ButtonClicked(b) =>
@@ -107,36 +103,31 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
107103
val removeButton = new Button("Remove Output Column") {
108104
reactions += {
109105
case ButtonClicked(b) =>
110-
val selectedRows = table.getSelectedRows
106+
val selectedRows = table.selection.rows
111107
logger.debug("selectedRows = " + selectedRows)
112-
if (selectedRows.length > 0) {
113-
for (i <- selectedRows.length - 1 to 0) {
114-
logger.debug(" removal " + i + ": removing row " + selectedRows(i))
115-
table.removeRow(selectedRows(i))
116-
}
117-
}
108+
selectedRows.view.toSeq.reverse.foreach(el => {
109+
logger.debug(" removing row " + el)
110+
table.removeRow(el)
111+
})
118112
}
119113
}
120114

121-
table = new JTable()
122-
table.putClientProperty("terminateEditOnFocusLost", true)
123-
table.setAutoscrolls(true)
115+
table = new Table()
124116
val model = new ScriptNodeOutputColumnsTableModel()
125117
model.addColumn("Column name")
126118
model.addColumn("Column type")
127119
model.addRow("script output " + columnCounter, "String")
128120
columnCounter += 1
129-
table.setModel(model)
121+
table.model = model
130122

131-
def createButtonForRowsMoving(title: String, func: (Array[Int]) => (Int, Int)): Button = {
123+
def createButtonForRowsMoving(title: String, func: (Seq[Int]) => Seq[Int]): Button = {
132124
new Button(title) {
133125
reactions += {
134126
case ButtonClicked(b) =>
135-
val selectedRows = table.getSelectedRows
127+
val selectedRows = table.selection.rows
136128
logger.debug("selectedRows = " + selectedRows)
137-
if (selectedRows.length > 0) {
138-
val position = func(selectedRows)
139-
table.setRowSelectionInterval(position._1, position._2)
129+
if (selectedRows.size > 0) {
130+
table.selection.rows ++= func(selectedRows.toSeq)
140131
}
141132
}
142133
}
@@ -149,24 +140,28 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
149140
"Down",
150141
table.moveRowsDown)
151142

152-
outputButtonPanel.add(addButton.peer)
153-
outputButtonPanel.add(removeButton.peer)
154-
outputButtonPanel.add(Box.createHorizontalStrut(40))
155-
outputButtonPanel.add(upButton.peer)
156-
outputButtonPanel.add(downButton.peer)
157-
158-
outputMainPanel.add(table.getTableHeader, BorderLayout.PAGE_START)
159-
outputMainPanel.add(table, BorderLayout.CENTER)
160-
outputPanel.add(newtableCBPanel)
161-
outputPanel.add(outputButtonPanel)
162-
outputPanel.add(outputMainPanel)
163-
val typeColumn = table.getColumnModel.getColumn(1)
143+
outputButtonPanel.peer.add(addButton.peer)
144+
outputButtonPanel.peer.add(removeButton.peer)
145+
outputButtonPanel.peer.add(Box.createHorizontalStrut(40))
146+
outputButtonPanel.peer.add(upButton.peer)
147+
outputButtonPanel.peer.add(downButton.peer)
148+
149+
outputMainPanel.peer.add(table.peer.getTableHeader, BorderLayout.PAGE_START)
150+
outputMainPanel.peer.add(table.peer, BorderLayout.CENTER)
151+
152+
newtableCBPanel.maximumSize = newtableCBPanel.minimumSize
153+
outputButtonPanel.maximumSize = outputButtonPanel.minimumSize
154+
155+
outputPanel.peer.add(newtableCBPanel.peer)
156+
outputPanel.peer.add(outputButtonPanel.peer)
157+
outputPanel.peer.add(outputMainPanel.peer)
158+
val typeColumn = table.peer.getColumnModel.getColumn(1)
164159
val typeSelector: ComboBox[String] =
165160
new ComboBox[String](Seq("String", "Integer","Double"))
166161
typeSelector.makeEditable
167162
typeColumn.setCellEditor(new DefaultCellEditor(
168163
typeSelector.peer.asInstanceOf[JComboBox[String]]))
169-
addTab("Script Output", outputPanel)
164+
addTab("Script Output", outputPanel.peer)
170165
}
171166

172167
/**
@@ -210,7 +205,7 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
210205
swing.Component.wrap(spScript), spErrorMessage)
211206
scriptMainPanel.peer.add(splitPane.peer, BorderLayout.CENTER)
212207
val num = factory.getModel.getInputPortRoles.length
213-
columnTables = Array.ofDim[JTable](num)
208+
columnTables = Array.ofDim[Table](num)
214209
val inputColumnsPanel = new BorderPanel()
215210
inputColumnsPanel.peer.setLayout(
216211
new BoxLayout(inputColumnsPanel.peer, BoxLayout.PAGE_AXIS))
@@ -240,47 +235,39 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
240235
*/
241236
private def addColumnPane(label: String, index: Int): Panel = {
242237
val panel = new BorderPanel()
243-
val table = new JTable()
244-
table.putClientProperty("terminateEditOnFocusLost", true)
245-
table.setAutoscrolls(true)
246-
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN)
247-
val model = new ScriptNodeOutputColumnsTableModel()
248-
model.addColumn("Column name")
249-
model.addColumn("Column type")
250-
model.setReadOnly(true)
251-
table.setModel(model)
252-
table.addMouseListener(new MouseAdapter(){
253-
private var m_index: Int = _
254-
255-
override def mouseClicked(event: java.awt.event.MouseEvent) {
256-
if (event.getClickCount == 2) {
257-
val table = event.getSource.asInstanceOf[JTable]
258-
val p = event.getPoint
259-
val row = table.rowAtPoint(p)
260-
if (row >= 0) {
261-
var name = table.getModel.getValueAt(row, 0).toString
262-
if (name.length > 0) {
263-
name = name.replaceAll("[^\\p{Alnum}]", "_")
264-
.replaceAll("\\_+", "_")
265-
if (name.charAt(name.length - 1) == '_')
266-
name = name.substring(0, name.length - 1)
267-
scriptTextArea.insert(
268-
TEMPLATE_COLUMN_NAME.format(m_index, name),
269-
scriptTextArea.getCaretPosition)
238+
val table = new Table() {
239+
model = new ScriptNodeOutputColumnsTableModel() {
240+
addColumn("Column name")
241+
addColumn("Column type")
242+
setReadOnly(true)
243+
}
244+
autoResizeMode = (Table.AutoResizeMode.LastColumn)
245+
listenTo(mouse.clicks)
246+
reactions += {
247+
case e: MousePressed =>
248+
if (e.clicks == 2) {
249+
val table = e.source.asInstanceOf[Table]
250+
val row = table.peer.rowAtPoint(e.point)
251+
if (row >= 0) {
252+
var name = table.model.getValueAt(row, 0).toString
253+
if (name.length > 0) {
254+
name = name.replaceAll("[^\\p{Alnum}]", "_")
255+
.replaceAll("\\_+", "_")
256+
if (name.charAt(name.length - 1) == '_')
257+
name = name.substring(0, name.length - 1)
258+
scriptTextArea.insert(
259+
TEMPLATE_COLUMN_NAME.format(index, name),
260+
scriptTextArea.getCaretPosition)
261+
}
270262
}
271263
}
272-
}
273-
}
274-
275-
def init(index: Int): MouseAdapter = {
276-
m_index = index
277-
return this
278264
}
279-
}.init(index))
280-
val scrollPane = new JScrollPane(table)
281-
table.setFillsViewportHeight(true)
265+
}
266+
267+
val scrollPane = new ScrollPane(table)
268+
//table.setFillsViewportHeight(true)
282269
panel.peer.add(new Label(label).peer, BorderLayout.NORTH)
283-
panel.peer.add(scrollPane, BorderLayout.CENTER)
270+
panel.peer.add(scrollPane.peer, BorderLayout.CENTER)
284271
columnTables(index) = table
285272
panel
286273
}
@@ -304,37 +291,34 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
304291
*/
305292
private def addFlowVariablesPane(label: String): Panel = {
306293
val flowVariablesPanel = new BorderPanel()
307-
val table = new JTable()
308-
table.putClientProperty("terminateEditOnFocusLost", true)
309-
table.setAutoscrolls(true)
310-
val model = new ScriptNodeOutputColumnsTableModel()
311-
model.addColumn("Name")
312-
model.addColumn("Value")
313-
model.setReadOnly(true)
314-
table.setModel(model)
315-
table.addMouseListener(new MouseAdapter() {
316-
317-
override def mouseClicked(event: java.awt.event.MouseEvent) {
318-
if (event.getClickCount == 2) {
319-
val table = event.getSource.asInstanceOf[JTable]
320-
val p = event.getPoint
321-
val row = table.rowAtPoint(p)
322-
if (row >= 0) {
323-
scriptTextArea.insert(String.format(TEMPLATE_FLOW_VAR,
324-
table.getModel.getValueAt(row, 0).toString),
294+
val table = new Table() {
295+
model = new ScriptNodeOutputColumnsTableModel() {
296+
addColumn("Name")
297+
addColumn("Value")
298+
setReadOnly(true)
299+
}
300+
listenTo(mouse.clicks)
301+
reactions += {
302+
case event: MouseClicked =>
303+
if (event.clicks == 2) {
304+
val table = event.source.asInstanceOf[Table]
305+
val row = table.peer.rowAtPoint(event.point)
306+
if (row >= 0) {
307+
scriptTextArea.insert(String.format(TEMPLATE_FLOW_VAR,
308+
table.model.getValueAt(row, 0).toString),
325309
scriptTextArea.getCaretPosition)
310+
}
326311
}
327-
}
328312
}
329-
})
313+
}
330314
factory.getModel.getAvailableFlowVariables
331315
.values.foreach(
332316
varDescr => table.addRow(varDescr.getName, varDescr.getStringValue)
333317
)
334-
val scrollPane = new JScrollPane(table)
335-
table.setFillsViewportHeight(true)
318+
val scrollPane = new ScrollPane(table)
319+
//table.setFillsViewportHeight(true)
336320
flowVariablesPanel.peer.add(new Label(label).peer, BorderLayout.NORTH)
337-
flowVariablesPanel.peer.add(scrollPane, BorderLayout.CENTER)
321+
flowVariablesPanel.peer.add(scrollPane.peer, BorderLayout.CENTER)
338322
flowVariablesPanel
339323
}
340324

@@ -384,10 +368,10 @@ class RubyScriptNodeDialog(private var factory: RubyScriptNodeFactory)
384368
* @see org.knime.core.node.NodeDialogPane#saveSettingsTo(org.knime.core.node.NodeSettingsWO)
385369
*/
386370
protected def saveSettingsTo(settings: NodeSettingsWO) {
387-
val editingRow = table.getEditingRow
388-
val editingColumn = table.getEditingColumn
371+
val editingRow = table.peer.getEditingRow
372+
val editingColumn = table.peer.getEditingColumn
389373
if (editingRow != -1 && editingColumn != -1) {
390-
val editor = table.getCellEditor(editingRow, editingColumn)
374+
val editor = table.peer.getCellEditor(editingRow, editingColumn)
391375
editor.stopCellEditing()
392376
}
393377
val scriptSetting = scriptTextArea.getText

RubyScript/src/org/knime/ext/jruby/ScriptNodeOutputColumnsTableModel.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,25 +82,25 @@ class ScriptNodeOutputColumnsTableModel extends AbstractTableModel {
8282
s(j) = v
8383
}
8484

85-
def moveRowsUp(rows: Array[Int]):(Int,Int) = {
85+
def moveRowsUp(rows: Seq[Int]): Seq[Int] = {
8686
val limit = 0
87-
var range = Array(rows.head, rows.last)
87+
var range = rows
8888
if (rows.head > limit) {
8989
rows.foreach(i => swap(data, i, i - 1))
9090
fireTableDataChanged()
9191
range = range.map(i => if (i - 1 < limit) limit else i - 1)
9292
}
93-
(range(0), range(1))
93+
range
9494
}
9595

96-
def moveRowsDown(rows: Array[Int]): (Int, Int) = {
96+
def moveRowsDown(rows: Seq[Int]): Seq[Int] = {
9797
val limit = data.size - 1;
98-
var range = Array(rows.head, rows.last)
98+
var range = rows
9999
if (rows.last < limit) {
100100
rows.view.reverse.foreach(i => swap(data, i + 1, i))
101101
fireTableDataChanged()
102102
range = range.map(i => if (i + 1 > limit) limit else i + 1)
103103
}
104-
(range(0), range(1))
104+
range
105105
}
106106
}

0 commit comments

Comments
 (0)