我刚刚遇到一个奇怪的问题,其中IndexOutOfBoundException
引发AbstractCellEditor
导致Exception
尝试索引不存在的行。删除最后一行后出现问题。删除最后一行后,每次可能点击该表都会抛出相同的Exception
,直到添加新行。我真的不知道为什么会这样。
在下文中,陈述了scala
和产生异常的小Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 4 >= 4
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.setValueAt(Unknown Source)
at javax.swing.JTable.setValueAt(Unknown Source)
at javax.swing.JTable.editingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.fireEditingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.stopCellEditing(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(Unknown Source)
at java.awt.AWTEventMulticaster.mousePressed(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
示例:
package test.TableTest
import scala.swing.BorderPanel
import scala.swing.BorderPanel.Position.Center
import scala.swing.MainFrame
import scala.swing.ScrollPane
import java.awt.BorderLayout
import java.awt.Dimension
import scala.swing.GridBagPanel
import scala.swing.TextField
import scala.swing.Button
import scala.swing.Table
import java.awt.GridBagConstraints._
import java.awt.Color
import java.awt.Dimension
import javax.swing.table.DefaultTableModel
import scala.collection.mutable.ListBuffer
import scala.swing.Table.AbstractRenderer
import javax.swing.Icon
import javax.swing.ImageIcon
import scala.swing.event.ButtonClicked
import javax.swing.BorderFactory
import javax.swing.AbstractCellEditor
import javax.swing.table.TableCellEditor
import scala.swing.Label
import javax.swing.JTable
import java.awt.{ Component => AWTComponent }
import java.util.EventObject
import scala.swing.SimpleSwingApplication
object TableTest extends SimpleSwingApplication {
setSystemLookAndFeel()
def top = new MainFrame {
val trackingControl = new TrackingControl
this.title_=("Table IndexOutOfBound-Example")
val components = new BorderPanel {
import BorderPanel.Position._
add(trackingControl, Center)
}
this.contents_=(components)
this.preferredSize = new Dimension(300,600)
this.pack
}
def setSystemLookAndFeel() {
import javax.swing.UIManager
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName)
}
}
class TrackingControl extends GridBagPanel {
val searchField = new TextField {
preferredSize_=(new Dimension(200, 22))
}
val searchButton = new Button {
text = "GO"
reactions += {
case e: ButtonClicked =>
if (!searchField.text.isEmpty())
fireAddToQuery(searchField.text)
}
}
val queryTable = new Table {
private val buttonRenderer = new AbstractRenderer[Any, Label](new Label) {
override def configure(table: Table, isSelected: Boolean, hasFocus: Boolean, a: Any, row: Int, column: Int) {
component.text = "Del"
}
}
private val buttonEditor = new AbstractCellEditor with TableCellEditor {
val label = new Label
label.text = "Del"
override def getCellEditorValue: AnyRef = "Del"
override def getTableCellEditorComponent(tab: JTable, value: AnyRef, isSelected: Boolean,
row: Int, col: Int): AWTComponent = {
fireRemoveFromQuery(row)
label.peer
}
}
model = new DefaultTableModel(Array[Object]("Tag", "Delete"), 0)
showGrid = false
peer.getTableHeader().disable()
peer.getColumnModel().getColumn(1).setMaxWidth(searchButton.preferredSize.width)
peer.getColumnModel().getColumn(1).setMinWidth(searchButton.preferredSize.width)
override def rendererComponent(isSelected: Boolean, focused: Boolean, row: Int, column: Int) = {
column match {
case 1 => buttonRenderer.componentFor(this, isSelected, hasFocus, null, row, column)
case _ => super.rendererComponent(isSelected, focused, row, column)
}
}
override def editor(row: Int, column: Int) = {
column match {
case 1 => buttonEditor
case _ => null
}
}
}
add(searchField, constraints(0, 0, anchor = GridBagPanel.Anchor.NorthWest))
add(searchButton, constraints(1, 0, anchor = GridBagPanel.Anchor.NorthEast))
add(queryTable, constraints(0, 1, gridwidth = 2, fill = GridBagPanel.Fill.Both, weighty = 1))
def fireAddToQuery(tag: String): Unit = {
queryTable.model.asInstanceOf[DefaultTableModel].addRow(Array[Object](tag))
}
def fireRemoveFromQuery(row: Int): Unit = {
queryTable.model.asInstanceOf[DefaultTableModel].removeRow(row)
}
def constraints(x: Int, y: Int,
gridwidth: Int = 1, gridheight: Int = 1,
weightx: Double = 0.0, weighty: Double = 0.0,
fill: GridBagPanel.Fill.Value = GridBagPanel.Fill.None,
anchor: GridBagPanel.Anchor.Value = GridBagPanel.Anchor.Center): Constraints = {
val c = new Constraints
c.gridx = x
c.gridy = y
c.gridwidth = gridwidth
c.gridheight = gridheight
c.weightx = weightx
c.weighty = weighty
c.fill = fill
c.anchor = anchor
c
}
}
代码:
{{1}}
点击" Del"可以删除一行。在第二栏。
你有什么想法导致这个索引错误吗?
答案 0 :(得分:0)
我弄清楚问题是什么。
在
override def getTableCellEditorComponent(tab: JTable, value: AnyRef, isSelected: Boolean,
row: Int, col: Int): AWTComponent = {
fireRemoveFromQuery(row)
label.peer
}
我在编辑处于活动状态时删除了该行。我必须在删除行之前取消编辑。
这是表格的剪裁工作:
val queryTable = new Table {
model = new DefaultTableModel(Array[Object]("Tag", "Delete"), 0)
showGrid = false
peer.getTableHeader().disable()
peer.getColumnModel().getColumn(1).setMaxWidth(searchButton.preferredSize.width)
peer.getColumnModel().getColumn(1).setMinWidth(searchButton.preferredSize.width)
val buttonEditor = new AbstractCellEditor with TableCellEditor {
var curRow = 0
val button = new Button
button.text= "Del"
button.peer.setBorderPainted(false)
button.peer.setContentAreaFilled(false)
button.peer.setOpaque(false)
listenTo(button)
reactions += {
case e: ButtonClicked => {
cancelCellEditing()
fireRemoveFromQuery(curRow)
}
}
override def isCellEditable(arg0: EventObject) = true
override def getCellEditorValue() = "Del"
override def getTableCellEditorComponent(arg0: JTable, arg1: Any, arg2: Boolean, row: Int, col: Int) = {
curRow = row
button.peer
}
}
override def editor(row: Int, column: Int) = {
column match {
case 1 => buttonEditor
case _ => null
}
}
}