[Java] java.lang.ArrayIndexOutOfBoundsException: -1

Maggiman

Cadet 3rd Year
Registriert
Sep. 2007
Beiträge
49
Hallo zusammen,

Ich arbeite momentan an einem Berufsschulprojekt. Dies ist ein Adressbuch welches sich die Daten aus einem XML Dokument holt und diese bei Neueinträgen / Änderungen in diesem wieder speichern soll.

Lesezugriff funktioniert schon einwandfrei, Schreibezugriff versuche ich momentan zu realisieren.

Bevor die Daten gelesen oder geschrieben werden landen sie erst einmal in einem Vector.

Wenn auf den Button "Neu" (für neue Einträge im Adressbuch) gedrückt wird soll erstmal ein Eintrag im Vector gemacht werden, die JList neu mit Daten befüllt werden und der letzte Eintrag selektiert werden. Danach soll man alle Felder ausfüllen, auf "Speichern" klicken, das Vector aktualisiert werden und alles im XML gespeichert werden. (soweit bin ich jedoch noch nicht)

Den neuen Eintrag im Vector hinzuzufügen klappt einwandfrei, jedoch entsteht beim "aktualisieren" folgende Exception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.get(Vector.java:696)
at view.CMainFrame.fillHandy(CMainFrame.java:240)
at view.CMainFrame.fillAdresse(CMainFrame.java:206)
at view.CMainFrame$2.valueChanged(CMainFrame.java:278)
at javax.swing.JList.fireSelectionValueChanged(JList.java:1765)
at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1779)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)
at javax.swing.DefaultListSelectionModel.removeSelectionIntervalImpl(DefaultListSelectionModel.java:559)
at javax.swing.DefaultListSelectionModel.clearSelection(DefaultListSelectionModel.java:403)
at javax.swing.JList.clearSelection(JList.java:2013)
at javax.swing.JList.setModel(JList.java:1646)
at javax.swing.JList.setListData(JList.java:1687)
at view.CMainFrame.SwitchEditorMode(CMainFrame.java:375)
at view.CMainFrame.actionPerformed(CMainFrame.java:292)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


Hier nun der Code meines "MainFrame". Ich habe die Zeilen die den Fehler verursachen rot gekennzeichnet.

Code:
package view;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;

import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.Adresse;
import model.AdresseListe;
import model.Validator;

import org.w3c.dom.Document;

import control.GUIDataConnector;

import data.XMLAccess;
import data.XMLFileLoader;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class CMainFrame extends javax.swing.JFrame implements ActionListener{
	private JList jlOverview;
	private JTextField txtNachname;
	private JLabel lblStadt;
	private JButton btnCancel;
	private JButton btnEdit;
	private JButton btnNeu;
	private JScrollPane jspOverview;
	private JButton btnDown;
	private JButton btnUp;
	private JLabel lblTelefon;
	private JLabel lblHandy;
	private JTextField txtHandy;
	private JTextField txtTelefon;
	private JTextField txtStadt;
	private JTextField txtPLZ;
	private JLabel lblPLZ;
	private JTextField txtStrasse;
	private JLabel lblStrasse;
	private JTextField txtVorname;
	private JLabel lblVorname;
	private JLabel lblNachname;
	private ListModel jlOverviewModel;
	private AdresseListe addL;
	private boolean newmode = false;
	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				CMainFrame inst = new CMainFrame();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public CMainFrame() {
		super();
		initGUI();
		loadData();
		fillOverview();
		fillAdresse();
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			getContentPane().setLayout(null);
			{
				lblNachname = new JLabel();
				getContentPane().add(lblNachname);
				lblNachname.setText("Nachname");
				lblNachname.setBounds(280, 19, 66, 14);
			}
			{
				txtNachname = new JTextField();
				getContentPane().add(txtNachname);
				txtNachname.setBounds(372, 15, 114, 21);
				txtNachname.setEditable(false);
			}
			{
				lblVorname = new JLabel();
				getContentPane().add(lblVorname);
				lblVorname.setText("Vorname");
				lblVorname.setBounds(280, 47, 66, 14);
			}
			{
				txtVorname = new JTextField();
				getContentPane().add(txtVorname);
				txtVorname.setBounds(372, 42, 114, 21);
				txtVorname.setEditable(false);
			}
			{
				lblStrasse = new JLabel();
				getContentPane().add(lblStrasse);
				lblStrasse.setText("Strasse");
				lblStrasse.setBounds(280, 73, 66, 14);
			}
			{
				txtStrasse = new JTextField();
				getContentPane().add(txtStrasse);
				txtStrasse.setBounds(372, 69, 114, 21);
				txtStrasse.setEditable(false);
			}
			{
				lblPLZ = new JLabel();
				getContentPane().add(lblPLZ);
				lblPLZ.setText("Postleitzahl");
				lblPLZ.setBounds(280, 99, 66, 14);
			}
			{
				txtPLZ = new JTextField();
				getContentPane().add(txtPLZ);
				txtPLZ.setBounds(372, 96, 114, 21);
				txtPLZ.setEditable(false);
			}
			{
				lblStadt = new JLabel();
				getContentPane().add(lblStadt);
				lblStadt.setText("Stadt");
				lblStadt.setBounds(280, 126, 66, 14);
			}
			{
				txtStadt = new JTextField();
				getContentPane().add(txtStadt);
				txtStadt.setBounds(372, 123, 114, 21);
				txtStadt.setEditable(false);
			}
			{
				lblTelefon = new JLabel();
				getContentPane().add(lblTelefon);
				lblTelefon.setText("Telefon");
				lblTelefon.setBounds(280, 153, 66, 14);
			}
			{
				txtTelefon = new JTextField();
				getContentPane().add(txtTelefon);
				txtTelefon.setBounds(372, 150, 114, 21);
				txtTelefon.setEditable(false);
			}
			{
				lblHandy = new JLabel();
				getContentPane().add(lblHandy);
				lblHandy.setText("Handy");
				lblHandy.setBounds(280, 180, 66, 14);
			}
			{
				txtHandy = new JTextField();
				getContentPane().add(txtHandy);
				txtHandy.setBounds(372, 177, 114, 21);
				txtHandy.setEditable(false);
			}
			{
				btnUp = new JButton();
				getContentPane().add(btnUp);
				btnUp.setText("Auf");
				btnUp.setBounds(5, 25, 55, 22);
				btnUp.addActionListener(this);
			}
			{
				btnDown = new JButton();
				getContentPane().add(btnDown);
				getContentPane().add(getJspOverview());
				getContentPane().add(getBtnNeu());
				getContentPane().add(getBtnEdit());
				getContentPane().add(getBtnCancel());
				btnDown.setText("Ab");
				btnDown.setBounds(6, 58, 54, 22);
				btnDown.addActionListener(this);
			}
			pack();
			this.setSize(522, 312);
			this.setResizable(false);
			this.setTitle("Adressbuch");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void fillAdresse() {
		fillHandy();
		fillTelefon();
		fillNachname();
		fillStadt();
		fillPLZ();
		fillVorname();
		fillStrasse();
	}
	
	public void fillStrasse() {
		this.txtStrasse.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrStrasse());
	}
	
	public void fillVorname() {
		this.txtVorname.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrVorname());
	}
	
	public void fillPLZ() {
		this.txtPLZ.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrPLZ());
	}
	
	public void fillStadt() {
		this.txtStadt.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrOrt());
	}
	
	public void fillNachname() {
		this.txtNachname.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrNachname());
	}
	
	public void fillTelefon() {
		this.txtTelefon.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrTel());
	}

	public void fillHandy() {
		this.txtHandy.setText(this.addL.get(this.jlOverview.getSelectedIndex()).getStrHdy());
	}
	
	public void loadData() {
		this.addL = new GUIDataConnector().getXmlacc().getNodeList("Adresse");
	}
	
	public void fillOverview(int i) {
		this.jlOverviewModel = new DefaultComboBoxModel(this.addL);
		this.jlOverview.setModel(jlOverviewModel);
		this.jlOverview.setSelectedIndex(i);
		this.jlOverview.validate();
	}
	
	public void fillOverview() {
		this.fillOverview(0);
	}
	
	private JScrollPane getJspOverview() {
		if(jspOverview == null) {
			jspOverview = new JScrollPane();
			jspOverview.setBounds(71, 12, 191, 260);
			{
				
				this.jlOverviewModel = 
					new DefaultComboBoxModel(
							new String[] { "Keine Daten gefunden!...." });
				jlOverview = new JList();
				jspOverview.setViewportView(jlOverview);
				jlOverview.setModel(jlOverviewModel);
				jlOverview.setBounds(358, 47, 192, 252);
				jlOverview.setPreferredSize(new java.awt.Dimension(188, 242));
				jlOverview.addListSelectionListener(new ListSelectionListener() {

					@Override
					public void valueChanged(ListSelectionEvent e) {
						// TODO Auto-generated method stub
						((CMainFrame)((JList)(e.getSource())).getParent().getParent().getParent()
								.getParent().getParent().getParent()).fillAdresse();
					}
					
				});
			}
		}
		return jspOverview;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String strAC = e.getActionCommand();
		int currIndex = this.jlOverview.getSelectedIndex();
		
		SwitchEditorMode(strAC);
		
		if(strAC=="Auf") {
			this.jlOverview.setSelectedIndex(currIndex-1);
		}
		if(strAC=="Ab") {
			this.jlOverview.setSelectedIndex(currIndex+1);
		}
		System.out.println(currIndex);
		
	}
	
	private JButton getBtnNeu() {
		if(btnNeu == null) {
			btnNeu = new JButton();
			btnNeu.setText("Neu");
			btnNeu.setBounds(280, 215, 66, 22);
			btnNeu.addActionListener(this);
		}
		return btnNeu;
	}
	
	private JButton getBtnEdit() {
		if(btnEdit == null) {
			btnEdit = new JButton();
			btnEdit.setText("Bearbeiten");
			btnEdit.setBounds(379, 215, 107, 22);
			btnEdit.addActionListener(this);
		}
		return btnEdit;
	}
	
	private JButton getBtnCancel() {
		if(btnCancel == null) {
			btnCancel = new JButton();
			btnCancel.setText("Abbrechen");
			btnCancel.setBounds(379, 248, 107, 22);
			btnCancel.setVisible(false);
			btnCancel.addActionListener(this);
		}
		return btnCancel;
	}
	
	private void EnableItemSwitching(boolean bEnable) {
		jlOverview.setEnabled(bEnable);
		btnUp.setEnabled(bEnable);
		btnDown.setEnabled(bEnable);
	}
	
	private void SetTextboxEditable(boolean b) {
		this.txtNachname.setEditable(b);
		this.txtVorname.setEditable(b);
		this.txtPLZ.setEditable(b);
		this.txtStadt.setEditable(b);
		this.txtStrasse.setEditable(b);
		this.txtHandy.setEditable(b);
		this.txtTelefon.setEditable(b);
	}
	
	private void SwitchEditorMode(String strAC) {
		if(strAC == "Abbrechen"){
			this.SetTextboxEditable(false);
			this.EnableItemSwitching(true);
			this.btnCancel.setVisible(false);
			this.btnEdit.setEnabled(true);
			this.btnNeu.setEnabled(true);
			
			if(newmode == true) {
				newmode = false;
				this.addL.RemoveLastAdresse();
				[COLOR="Red"]this.jlOverview.setListData(addL);[/COLOR]
			//	this.jlOverview.validate();
			//	this.jlOverview.setSelectedIndex(0);
			}
		}
		else if(strAC=="Neu"||strAC=="Bearbeiten"){
			EnableItemSwitching(false);
			if(strAC == "Neu") {
				newmode = true;
				this.SetTextboxEditable(true);
				this.btnEdit.setEnabled(false);
				this.btnNeu.setEnabled(false);
				this.btnCancel.setVisible(true);
				this.addL.AddEmptyAdresse();
				[COLOR="red"]this.jlOverview.setListData(addL);[/COLOR]
			//	this.jlOverview.setModel(this.jlOverviewModel);
				this.jlOverview.validate();
				this.jlOverview.setSelectedIndex(this.addL.size()-1);
			}
			else if(strAC == "Bearbeiten") {
				System.out.println(this.addL.size());
				this.SetTextboxEditable(true);
				this.btnNeu.setEnabled(false);
				this.btnEdit.setEnabled(false);
				this.btnCancel.setVisible(true);				
			}
		}
	}

}

Hier noch der Code meine AddresseListe (addL) Klasse:

Code:
package model;

import java.util.Vector;

public class AdresseListe extends Vector<Adresse> {
	
	private int iCurrRec;
	
	public AdresseListe() {
		this.iCurrRec = 0;
	}
	
	public AdresseListe(int cur) {
		this.iCurrRec = cur;
	}

	/**
	 * @return the iCurrRec
	 */
	public int getICurrRec() {
		return iCurrRec;
	}

	/**
	 * @param currRec the iCurrRec to set
	 */
	public void setICurrRec(int currRec) {
		iCurrRec = currRec;
	}
	
	public void AddEmptyAdresse() {
		Adresse a = new Adresse("","","","","","","");
	//	this.add(a);
		this.addElement(a);
		this.trimToSize();

	}
	
	public void RemoveLastAdresse() {
		this.remove(this.size()-1);
	}
}

Ich denke mal das dies alles an relevanten Code gewesen sein dürfte. Ich hoffe echt das ihr mir weiterhelfen könnt weil ich ziemlich ratlos bin und echt nich weiss woran das liegt.


Merkwürdigerweise wird der Fehler wenn man auf den Button "Neu" drückt nur beim ersten Mal (seit dem das Programm ausgeführt wird) erzeugt (außerdem wird der letzte Eintrag nicht selektiert). Wenn man dann auf Abbrechen drückt wird kein Fehler erzeugt. Danach ist es aber genau umgekehrt, wenn man auf Neu drückt kommt keine Exception mehr (der letzte hinzugefügte Eintrag wird auch selektiert), dafür aber jedes Mal wenn man auf abbrechen drückt!

Nun gut, ich steh echt aufm Schlauch und hoffe das ich mein Problem verständlich erläutert habe! Ich bitte um Eure Hilfe!


Viele Grüße,
Maggi
 
Zuletzt bearbeitet:
Ich habe mir mal eben die setListData() Methode aus der Klasse JList angesehen. Offenbar musst Du mit deren Umgang sehr vorsichtig sein:
Constructs a read-only ListModel from a Vector and calls setModel with this model.

Attempts to pass a null value to this method results in undefined behavior and, most likely, exceptions. The created model references the given Vector directly. Attempts to modify the Vector after invoking this method results in undefined behavior.
Es gibt also zwei mögliche Fehlerursachen:

1. Es wird null an setListData() übergeben. Das kannst Du ja einfach vorher mal überprüfen, indem Du folgenden Block vor dem Methodenaufruf einfügst:
Code:
if (this.addL == null) { System.out.println("AddressList ist NULL!"); }

2. (wahrscheinlicher) Der Fehler entsteht durch die mehrfache Verwendung des Vectors im Feld addL. Wie in der Beschreibung der setListData() Methode erwähnt, führt eine nachträgliche Veränderung dieses Vektors zu undefiniertem Verhalten, möglicherweise Exceptions. Du solltest in diesem Fall den Vector addL also nicht mit der setListData() Methode verwenden, sondern vorher mittels clone() Methode eine Kopie des Vectors ermitteln und diese an die Methode übergeben. So bleibt Dein addL-Feld weiterhin nutzbar.

Hoffe das hilft. :)
 
Hi,

danke für die schnelle Antwort! Werde mich dann mal dranhocken und deinem Rat nachgehen.
Werde natürlich schreiben ob es hingehauen hat oder nicht!

Vielen Dank nochmals!

Viele Grüße,
Maggi
 
So...

leider hat das mit clone() nicht geklappt, oder ich war einfach zu doof dafür. Auf jeden Fall wurde das Problem nun mit einem try und catch Block umgangen, die Exception wird abgefangen, das Programm läuft weiter..

Die Exception hat allem Anschein nach sowieso keinerlei Auswirkung auf die Funktionalität des Programms, funktioniert alles so wie es sollte.


Ich weiss das dies zwar nicht die eleganteste Möglichkeit ist, aber ich steh etwas unter Zeitdruck und muss schauen das ich weiterkomm ^^


Falls ihr dennoch irgendwelche Ideen bzgl. dem Problem haben solltet wäre ich dankbar, vielleicht könnte ich dies dann ja noch bis zum Abgabetermin beheben.



Viele Grüße und danke nochmals,
Maggi
 
Probier's vielleicht mal mit einem separaten ListModel für die JList. Ich würde einfach neben der eigentlichen Liste ein ListModel in einem Feld vorhalten, welches den Inhalt für die JList liefert. Dazu kannst Du im Constructor ein neues Modell erzeugen und an die Liste anbinden:
Code:
public CMainFrame()
{
  ...
  this.listContent = new DefaultListModel();
  this.listBox = new JList(this.listContent);
  ...
}
Natürlich muss dazu listContent als DefaultListModel und listBox als JList in der Klasse definiert sein.

Nun fügst Du neue Einträge direkt in das listContent-Feld ein. Das ListModel basiert auf Vector, so dass Du bequemen Zugriff auf die Elemente hast. Schau mal hier für die API: http://java.sun.com/javase/6/docs/api/javax/swing/DefaultListModel.html
 
Hallo Prypjat,
ich danke dir wiedereinmal für deine schnelle Antwort!
Sobald meine restlichen geplanten Funktionalitäten einigermaßen am Laufen sind werde ich mich wieder diesem Problem zuwenden und deinen Vorschlag ausprobieren!


Danke nochmals für die schnelle und kompetente Hilfe!

Natürlich werd ich dann bescheid geben wies hingehauen hat ^^

Viele Grüße,
Maggi
 
Zurück
Oben