Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[JAVA] Error bij verwijderen row uit JTable

Pagina: 1
Acties:

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Ik krijg een ArrayIndexOutOfBoundsException voor de row die ik wil verwijderen + 1.
Als ik bijvoorbeeld row nummer 4 verwijder, krijg ik een ArrayIndexOutOfBoundsException: 5 >= 5.

Echter, ik krijg niet altijd die error. Bij het verwijderen van de laatste row krijg ik nooit een error, maar bij het verwijderen van rows in het midden krijg ik vaak een error.

Dit is me code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
JComboBox actionComboBox = new JComboBox();
JTable jTable = new JTable();
DefaultTableModel tableModel = new DefaultTableModel();

actionComboBox.addItem("Delete");

tableModel.addColumn("Kolom 1");
tableModel.addColumn("Kolom 2");
jTable.setModel(tableModel);

TableColumn actionColumn = jTable.getColumnModel().getColumn(1);
actionColumn.setCellEditor(new DefaultCellEditor(actionComboBox));

actionColumn.setCellRenderer(new DefaultTableCellRenderer() {
  @Override
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
      tableModel.removeRow(row);
    }
    return this;
  }
}); 

actionComboBox.setRenderer(new DefaultListCellRenderer() {
  @Override
  public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
    if (value instanceof String) {
      setText((String)value);
    }
    return this;
  }
});


De error:
Afbeeldingslocatie: http://www.few.vu.nl/~jpstout/java_error.jpg

  • paulh
  • Registratie: Juli 1999
  • Laatst online: 10-11 10:50
Ik neem aan dat je weet dat lijsten bij 0 beginnen met tellen?

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 09:31
Rows in een TableModel zijn 0-based wegens de onderliggende array implementatie.
Als jij de 5e rij die de JTable weergeeft wilt verwijderen dan moet je removeRow() dus aanroepen met index 5-1, dus 4. Wanneer er maar 5 rows in het TableModel zitten en je roep removeRow() aan met 5 als argument, dan probeert ie de row op de 6e index positie te verwijderen, maar de array beschikt maar over 5 index posities. Op dat moment wordt die ArrayIndexOutOfBounds exceptie gegooit.

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Stapt ge dan nooit met een debugger door u code? Om op dat moment de stack te bekijken...

Going for adventure, lots of sun and a convertible! | GMT-8


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Het row-1 verhaal is niet wat mis is.
Het row nummer wat ik verwijder met removeRow(nummer), heb ik verkregen via
Java:
1
getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

De parameter "int row" begint zelf bij 0 te tellen.

Als dit ook het probleem zou zijn, zou het verwijderen altijd fout moeten gaan. Echter, het verwijderen van de laatste row gaat altijd goed. Het verwijderen van de een na laatste gaat altijd fout. Het verwijderen van rows in het midden gaat soms fout. Met fout bedoel ik de error in de startpost.

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 09:15

NetForce1

(inspiratie == 0) -> true

waarschijnlijk komt dat omdat je in het verwijderen in je cellrenderer doet. Het algoritme dat de rijen paint gaat uit van een aantal rijen (zoals dat er bij de start van het algoritme is), waarbij jij dat aantal dan halverwege gaat zitten wijzigen. Je moet dus zorgen dat je het verwijderen iig niet in de paint-sequence doet, maar in de action listener van een knop oid.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
NetForce1 schreef op donderdag 13 maart 2008 @ 19:28:
waarschijnlijk komt dat omdat je in het verwijderen in je cellrenderer doet. Het algoritme dat de rijen paint gaat uit van een aantal rijen (zoals dat er bij de start van het algoritme is), waarbij jij dat aantal dan halverwege gaat zitten wijzigen. Je moet dus zorgen dat je het verwijderen iig niet in de paint-sequence doet, maar in de action listener van een knop oid.
Dit klinkt erg aannemelijk.

Wat kan ik nu het beste doen? Ik zou een soort (action)listener moeten hebben die het opvangt als er een optie in de combobox wordt aangeklikt.

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 09:15

NetForce1

(inspiratie == 0) -> true

Idd, je moet dus een ActionListener (of een ChangeListener) op je combo box hangen.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
De vraag is echter hoe ik dan nog steeds kan weten om welke row nummer het gaat?
Want als de ActionListener wordt aangeroepen nadat er een keuze is gemaakt in de combobox, kan ik niet meer achterhalen vanaf welke row dat kwam?

Mij lijkt dan de enige optie dat wanneer de getTableCellRendererComponent() wordt aangeroepen daar in een klasse variabele het row nummer zet? En die weer inlees in de ActionListener van de combobox?

Of iemand een beter idee?

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 09:15

NetForce1

(inspiratie == 0) -> true

Als de row ook geselecteerd wordt op het moment dat je een keuze maakt in je combobox kun je die informatie uit het selection model van de tabel halen. Als dat niet werkt kun je bijv. de ActionListener opstarten met een row nummer, nadeel is wel dat je dan voor elke row dus een nieuwe listener op moet starten, maargoed zo zwaar is dat allemaal ook weer niet.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Het werkt nu. Goede tip om het row nummer uit het selection model te halen. Later kwam ik erachter dat je die ook gewoon uit de jTable zelf kunt halen.

Ik kreeg nog wel een error bij het verwijderen van de laatste row, dit kwam blijkbaar doordat de cell nog ge-edit werd voor het verwijderen. (link)

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
JComboBox actionComboBox = new JComboBox();
JTable jTable = new JTable();
DefaultTableModel tableModel = new DefaultTableModel();

actionComboBox.addItem("Delete");

tableModel.addColumn("Kolom 1");
tableModel.addColumn("Kolom 2");
jTable.setModel(tableModel);

TableColumn actionColumn = jTable.getColumnModel().getColumn(1);
actionColumn.setCellEditor(new DefaultCellEditor(actionComboBox));

actionComboBox.addActionListener(new java.awt.event.ActionListener() {
  public void actionPerformed(java.awt.event.ActionEvent evt) {
    Object ob = actionComboBox.getSelectedItem();
    if (ob instanceof String) {
      String strAction = (String)actionComboBox.getSelectedItem();
      if (strAction.equals("Delete")) {
        delRow(jTable.getSelectedRow());
      }
    }
  }
});

delRow (int row) {
  jTable.editingCanceled(null);
  tableModel.removeRow(row);
}


De setCellRenderer() hoef je dus niet te gebruiken hiervoor.

  • NetForce1
  • Registratie: November 2001
  • Laatst online: 09:15

NetForce1

(inspiratie == 0) -> true

Als ik me niet vergis wordt de cell editor pas getekend op het moment dat je op die cel klikt. Als je tot die tijd iets anders wil tonen in die cell is dat niet erg, anders moet je daar nog wat voor verzinnen. Je kunt er ook voor kiezen om de actie combobox buiten je table te halen, en die dan te laten opereren op alle geselecteerde rijen.
Maar om die error op te lossen hebben we toch echt een stacktrace nodig, en dan liever geen screenshot van de dos prompt, maar gewoon de text kopieren.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"

Pagina: 1