# JList - neuer Eintrag in ArrayList dadurch keine Anzeige der Objekte



## Ollek (19. Nov 2012)

Hallo,

ich schreibe gerade eine Anwendung in der man Systemdaten hinterlegen kann.

Ich habe 2 JLists in der Anwendung. 
Ich habe eine Liste auf der Eingabe-Maske für die Systeme und eine auf der Auswahl-Maske.
Beide benutzen das gleiche Model. Meine Daten halte ich über eine Singleton-Klasse für alle greifbar.

Leider tritt der Fehler nicht immer auf. Sondern nur manchmal bei einer Aktion. Es geschieht aber immer beim Eintragen eines neues Systems. Ich trage das System ein und wechsel dann aus der Eingabe-Maske in die Auswahl-Maske. Dort finde ich dann kein System mehr in der Liste. Ich habe mal mit nem System.out. geprüft, ob das Model noch Objekte in der Liste hat. Die waren da, aber die wurden nicht mehr angezeigt, sondern ich hatte einen weißen Hintergrund in der JList wo eigentlich die Systeme angezeigt werden sollten.

Ich hoffe die Beschreibung ist verständlich, sollten Fragen sein um mir bei meinem Problem zu helfen, fragen 

Hier mal die Klassen, die bei dem Problem mitwirken.

SystemOverview ist die Eingabe-Maske.

```
public class SystemOverview extends JPanel {

	private JList lstSystem;
	private JTextField tfName;
	private JTextField tfHostname;
	private JTextField tfUser;
	private JPasswordField passwordField;
	private JPanel pnlNorth;
	private JButton btnHinzufgen;
	private JButton btnLschen;
	private JButton btnAbbrechen;
	private JButton btnSpeichern;
	private JPanel pnlAddAndDelete;
	private JPanel pnlCancAndSave;
	private JPanel cards;
	private boolean isNew;
	private JListModel model;
	private DataStorage dataManagement = DataStorageSingleton.getInstance();
	
	public SystemOverview(JPanel cards) {
		this.cards = cards;
		this.isNew = false;
		this.model = new JListModel();
		init();
	}

	private void init() {
		setLayout(new BorderLayout(0, 0));
		
		lstSystem = new JList();
		lstSystem.setPreferredSize(new Dimension(220, 500));
		lstSystem.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		lstSystem.setModel(model);
		lstSystem.addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(ListSelectionEvent event) {
				if (lstSystem.getSelectedIndex() == -1) {
			        //No selection.
					btnSpeichern.setEnabled(false);
					btnLschen.setEnabled(false);
			          
				} else {
					if(!btnSpeichern.isEnabled()){
						btnSpeichern.setEnabled(true);
					}else if(!btnLschen.isEnabled()){
						btnLschen.setEnabled(true);
					}
					
					enabledTextfields(true);
					
					int index = lstSystem.getSelectedIndex();
					System system = model.getSystemAt(index);
					tfName.setText(system.getName());
					tfHostname.setText(system.getHostname());
					tfUser.setText(system.getUser());
					passwordField.setText(system.getPassword());
				}
				
			}
		});
		add(lstSystem, BorderLayout.WEST);
		
		JPanel pnlSystemOptions = new JPanel();
		add(pnlSystemOptions, BorderLayout.CENTER);
		GridBagLayout gbl_pnlSystemOptions = new GridBagLayout();
		gbl_pnlSystemOptions.columnWidths = new int[]{0, 0, 0};
		gbl_pnlSystemOptions.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_pnlSystemOptions.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
		gbl_pnlSystemOptions.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		pnlSystemOptions.setLayout(gbl_pnlSystemOptions);
		
		JLabel lblName = new JLabel("Name");
		lblName.setAlignmentY(0.0f);
		GridBagConstraints gbc_lblName = new GridBagConstraints();
		gbc_lblName.insets = new Insets(10, 10, 5, 10);
		gbc_lblName.anchor = GridBagConstraints.LINE_START;
		gbc_lblName.gridx = 0;
		gbc_lblName.gridy = 0;
		pnlSystemOptions.add(lblName, gbc_lblName);
		
		tfName = new JTextField();
		tfName.setEnabled(false);
		lblName.setLabelFor(tfName);
		GridBagConstraints gbc_tfName = new GridBagConstraints();
		gbc_tfName.insets = new Insets(10, 1, 5, 10);
		gbc_tfName.fill = GridBagConstraints.HORIZONTAL;
		gbc_tfName.gridx = 1;
		gbc_tfName.gridy = 0;
		pnlSystemOptions.add(tfName, gbc_tfName);
		tfName.setColumns(10);
		
		JLabel lblHostname = new JLabel("Hostname");
		GridBagConstraints gbc_lblHostname = new GridBagConstraints();
		gbc_lblHostname.anchor = GridBagConstraints.LINE_START;
		gbc_lblHostname.insets = new Insets(10, 10, 5, 10);
		gbc_lblHostname.gridx = 0;
		gbc_lblHostname.gridy = 1;
		pnlSystemOptions.add(lblHostname, gbc_lblHostname);
		
		tfHostname = new JTextField();
		tfHostname.setEnabled(false);
		lblHostname.setLabelFor(tfHostname);
		GridBagConstraints gbc_tfHostname = new GridBagConstraints();
		gbc_tfHostname.insets = new Insets(10, 0, 5, 10);
		gbc_tfHostname.fill = GridBagConstraints.HORIZONTAL;
		gbc_tfHostname.gridx = 1;
		gbc_tfHostname.gridy = 1;
		pnlSystemOptions.add(tfHostname, gbc_tfHostname);
		tfHostname.setColumns(10);
		
		JLabel lblUser = new JLabel("User");
		GridBagConstraints gbc_lblUser = new GridBagConstraints();
		gbc_lblUser.anchor = GridBagConstraints.LINE_START;
		gbc_lblUser.insets = new Insets(10, 10, 5, 10);
		gbc_lblUser.gridx = 0;
		gbc_lblUser.gridy = 2;
		pnlSystemOptions.add(lblUser, gbc_lblUser);
		
		tfUser = new JTextField();
		tfUser.setEnabled(false);
		GridBagConstraints gbc_tfUser = new GridBagConstraints();
		gbc_tfUser.insets = new Insets(10, 0, 5, 10);
		gbc_tfUser.anchor = GridBagConstraints.LINE_START;
		gbc_tfUser.fill = GridBagConstraints.HORIZONTAL;
		gbc_tfUser.gridx = 1;
		gbc_tfUser.gridy = 2;
		pnlSystemOptions.add(tfUser, gbc_tfUser);
		tfUser.setColumns(10);
		
		JLabel lblPasswort = new JLabel("Passwort");
		GridBagConstraints gbc_lblPasswort = new GridBagConstraints();
		gbc_lblPasswort.anchor = GridBagConstraints.LINE_START;
		gbc_lblPasswort.insets = new Insets(10, 10, 5, 10);
		gbc_lblPasswort.gridx = 0;
		gbc_lblPasswort.gridy = 3;
		pnlSystemOptions.add(lblPasswort, gbc_lblPasswort);
		
		passwordField = new JPasswordField();
		passwordField.setEnabled(false);
		lblPasswort.setLabelFor(passwordField);
		GridBagConstraints gbc_passwordField = new GridBagConstraints();
		gbc_passwordField.insets = new Insets(10, 0, 5, 10);
		gbc_passwordField.anchor = GridBagConstraints.LINE_START;
		gbc_passwordField.fill = GridBagConstraints.HORIZONTAL;
		gbc_passwordField.gridx = 1;
		gbc_passwordField.gridy = 3;
		pnlSystemOptions.add(passwordField, gbc_passwordField);
		
		pnlNorth = new JPanel();
		add(pnlNorth, BorderLayout.NORTH);
		GridBagLayout gbl_pnlNorth = new GridBagLayout();
		gbl_pnlNorth.columnWidths = new int[]{0, 33, 187, 191, 0};
		gbl_pnlNorth.rowHeights = new int[]{35, 0};
		gbl_pnlNorth.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		gbl_pnlNorth.rowWeights = new double[]{0.0, Double.MIN_VALUE};
		pnlNorth.setLayout(gbl_pnlNorth);
		
		pnlAddAndDelete = new JPanel();
		FlowLayout flowLayout = (FlowLayout) pnlAddAndDelete.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		GridBagConstraints gbc_pnlAddAndDelete = new GridBagConstraints();
		gbc_pnlAddAndDelete.anchor = GridBagConstraints.LINE_START;
		gbc_pnlAddAndDelete.insets = new Insets(0, 0, 0, 10);
		gbc_pnlAddAndDelete.gridx = 0;
		gbc_pnlAddAndDelete.gridy = 0;
		pnlNorth.add(pnlAddAndDelete, gbc_pnlAddAndDelete);
		
		btnHinzufgen = new JButton("Hinzuf\u00FCgen");
		btnHinzufgen.setIcon(new ImageIcon(SystemOverview.class.getResource("/icons/add1-16.png")));
		btnHinzufgen.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				isNew = true;
				btnSpeichern.setEnabled(true);
				enabledTextfields(true);
				clearContent();
			}
		});
		pnlAddAndDelete.add(btnHinzufgen);
		
		btnLschen = new JButton("L\u00F6schen");
		btnLschen.setIcon(new ImageIcon(SystemOverview.class.getResource("/icons/delete16.png")));
		btnLschen.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System system = (System) model.getSystemAt(lstSystem.getSelectedIndex());
				model.removeElement(system);
				clearContent();
				enabledTextfields(false);
				lstSystem.repaint();
			}
		});
		btnLschen.setEnabled(false);
		pnlAddAndDelete.add(btnLschen);
		
		pnlCancAndSave = new JPanel();
		FlowLayout flowLayout_1 = (FlowLayout) pnlCancAndSave.getLayout();
		flowLayout_1.setAlignment(FlowLayout.RIGHT);
		GridBagConstraints gbc_pnlCancAndSave = new GridBagConstraints();
		gbc_pnlCancAndSave.fill = GridBagConstraints.HORIZONTAL;
		gbc_pnlCancAndSave.anchor = GridBagConstraints.EAST;
		gbc_pnlCancAndSave.gridx = 3;
		gbc_pnlCancAndSave.gridy = 0;
		pnlNorth.add(pnlCancAndSave, gbc_pnlCancAndSave);
		
		btnAbbrechen = new JButton("Abbrechen");
		btnAbbrechen.setHorizontalAlignment(SwingConstants.RIGHT);
		btnAbbrechen.setIcon(new ImageIcon(SystemOverview.class.getResource("/icons/cancel16.png")));
		btnAbbrechen.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent event) {
				CardLayout carddLayout = (CardLayout) cards.getLayout();
				carddLayout.show(cards, "Hauptansicht");
			}
		});
		pnlCancAndSave.add(btnAbbrechen);
		
		btnSpeichern = new JButton("Speichern");
		btnSpeichern.setHorizontalAlignment(SwingConstants.RIGHT);
		btnSpeichern.setIcon(new ImageIcon(SystemOverview.class.getResource("/icons/save.png")));
		btnSpeichern.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				String name = tfName.getText().trim();
				String hostname = tfHostname.getText().trim();
				String user = tfUser.getText().trim();
				String password = generateUsablePassword(passwordField.getPassword());
				 
				if(name.isEmpty() || hostname.isEmpty() || user.isEmpty() || password.isEmpty()){
					JOptionPane.showMessageDialog(cards, "Es müssen alle Felder ausgefüllt sein, um Speichern zu können.", "Speichern nicht möglich.", JOptionPane.ERROR_MESSAGE);
				}else{
					if(isNew){
						isNew = false;
						System system = new System(name, hostname, user, password);
						model.addElement(system);
						lstSystem.setSelectedIndex(model.getIndexOfElement(system));
					}else{
						model.getSystemAt(lstSystem.getSelectedIndex()).setName(name);
						model.getSystemAt(lstSystem.getSelectedIndex()).setHostname(hostname);
						model.getSystemAt(lstSystem.getSelectedIndex()).setUser(user);
						model.getSystemAt(lstSystem.getSelectedIndex()).setPassword(password);
					}
					lstSystem.repaint();
				}
			}
		});
		btnSpeichern.setEnabled(false);
		pnlCancAndSave.add(btnSpeichern);
	}
	
	protected String generateUsablePassword(char[] cPassword) {
		String password = "";
		for(char c : cPassword){
			password = password + c;
		}
		return password;
	}

	/**
	 * Content der Felder wird geleert 
	 */
	private void clearContent(){
		tfHostname.setText("");
		tfName.setText("");
		tfUser.setText("");
		passwordField.setText("");
	}
	
	/**
	 * Felder werden freigegeben oder gesperrt für Eingaben
	 * 
	 * @param enabled
	 */
	protected void enabledTextfields(boolean enabled){
		tfName.setEnabled(enabled);
		tfHostname.setEnabled(enabled);
		tfUser.setEnabled(enabled);
		passwordField.setEnabled(enabled);
	}

}
```

FileSettings - Hier können die Systeme ausgewählt werden.

```
public class FileSettings extends JPanel {
	
	private JComboBox cbSystem;
	private JComboBox cbFileFormat;
	private JTextField tfFilename;
	private JTextField tfSystem;
	private SQLOperations dbOp;
	private StatementEditor stmtEditor;
	private String strSaveDir = System.getProperty("user.dir");
	private ExportHelper exportSettings = ExportHelper.getInstance();
	private Config conf = Config.getInstance();
	private JProgressBar progressBar;
	private JTextField tfSaveDirectory;
	private DataTable table;
	private JPanel pnlStatus;
	private ReadWriteDataLoader readWriteDataLoader;
	private JButton btnSave;
	private JButton btnPreview;
	private ReadDataLoader readDataLoader;
	protected JList lstSystem;
	private de.ernstings.model.System choosedSystem;
	protected JListModel model;
	

	public FileSettings(StatementEditor stmtEditor, DataTable table){
		this.dbOp  = new SQLOperations();
		this.stmtEditor = stmtEditor;
		this.table = table;
		init();
	}

	private void init() {
		
		GridBagLayout gbl = new GridBagLayout();
		this.setLayout(gbl);
		this.setPreferredSize(new Dimension(500, 120));
				
		GridBagConstraints gbc;
		
		gbc = new GridBagConstraints(
				0, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0);
		this.add(new JLabel("System: "), gbc);
		
		// Texfield System
		gbc = new GridBagConstraints(
				1, 0, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0);
		tfSystem = new JTextField("", 20);
		this.add(tfSystem, gbc);
		
		//Seperator
		gbc = new GridBagConstraints(
				2, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 15, 0, 15), 0, 0);
		this.add(new JSeparator(SwingConstants.VERTICAL), gbc);
		
		// Dateiname Label
		gbc = new GridBagConstraints(
				3, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0);
		this.add(new JLabel("Dateiname:"), gbc);
						
		// Texfield Dateiname
		gbc = new GridBagConstraints(
				4, 0, 1, 1, 1, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 10), 0, 0);
		tfFilename = new JTextField("CSVExport", 15);
		this.add(tfFilename, gbc);
		
		// Dateiformat Label
		gbc = new GridBagConstraints(
				5, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0);
		this.add(new JLabel("Format:"), gbc);
		
		// Formatauswahl ComboBox
		gbc = new GridBagConstraints(
				6, 0, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0);
		String[] arrFileFormat = {"CSV", "LST"};
		cbFileFormat = new JComboBox(arrFileFormat);
		cbFileFormat.setPrototypeDisplayValue("XXXX");
		this.add(cbFileFormat, gbc);
		
		// System JList
		gbc = new GridBagConstraints(
				0, 1, 2, 3, 1, 1, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0);
		model = new JListModel();
		lstSystem = new JList(model);
		lstSystem.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		lstSystem.setVisibleRowCount(15);
		lstSystem.setLayoutOrientation(JList.VERTICAL);
		lstSystem.addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (lstSystem.getSelectedIndex() == -1) {
					
				}else{
					int index = lstSystem.getSelectedIndex();
					choosedSystem = model.getSystemAt(index);
					tfSystem.setText(choosedSystem.getName());
				}
			}
		});
		JScrollPane listScroller = new JScrollPane(lstSystem);
		this.add(listScroller, gbc);
		
		//Seperator
		gbc = new GridBagConstraints(
				2, 1, 1, 3, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 15, 0, 15), 0, 0);
		this.add(new JSeparator(SwingConstants.VERTICAL), gbc);
		
		// Speichern unter Label
		gbc = new GridBagConstraints(
				3, 1, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0);
		this.add(new JLabel("Speichern unter: "), gbc);
		
		// Verzeichnis in dem gespeichert werden soll aussuchen
		gbc = new GridBagConstraints(
				4, 1, 2, 1, 2, 0, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0);
		tfSaveDirectory = new JTextField(System.getProperty("user.dir"));
		this.add(tfSaveDirectory, gbc);
		
		// Verzeichnis ändern Button
		gbc = new GridBagConstraints(
				6, 1, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0);
		JButton btnSaveDir = new JButton("ändern..");
		btnSaveDir.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				strSaveDir = openFileChooser();
				tfSaveDirectory.setText(strSaveDir);				
			}
		});
		this.add(btnSaveDir, gbc);

		
		// SPEICHERN BUTTON
		gbc = new GridBagConstraints(
				0, 4, 1, 1, 0, 0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(5, 5, 5, 10), 0, 0);
		btnSave = new JButton("Speichern", createImageIcon("/icons/save.png"));
		btnSave.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				String sqlQuery = stmtEditor.getText().trim().toLowerCase();
				if(isSQLQueryValid(sqlQuery)){
					if(!tfSystem.getText().isEmpty()){
						exportSettings.setFilename(tfFilename.getText().trim());
						if(new File(strSaveDir + exportSettings.getFilename()).exists())
							JOptionPane.showConfirmDialog(null, exportSettings.getFilename() +"  besteht bereits.\n\rMöchten Sie sie ersetzen?", "Ersetzen bestätigen", JOptionPane.YES_NO_OPTION);
						progressBar.setIndeterminate(true);
						readWriteDataLoader.setActive(true);
					}else{
						showInvalidSQLQueryMessage("Es wurde kein System ausgewählt.\n\rBitte ein System auswählen, auf dem das Statement ausgeführt werden soll.");
					}
				}else{
					showInvalidSQLQueryMessage("Es wurde kein gültiger SQL Query eingetragen.\n\rBitte gültigen SQL Query eingeben");
				}
			}
		});
		this.add(btnSave, gbc);
				
		
		// VORSCHAU Button
		gbc = new GridBagConstraints(
				1, 4, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 0, 5, 10), 0, 0);
		btnPreview = new JButton("Vorschau", createImageIcon("/icons/preview.png"));
		btnPreview.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				String sqlQuery = stmtEditor.getText().trim().toLowerCase();
				if(isSQLQueryValid(sqlQuery)){
					if(!tfSystem.getText().isEmpty()){
						exportSettings.setFilename(tfFilename.getText().trim());
						readDataLoader.setActive(true);
					}else{
						showInvalidSQLQueryMessage("Es wurde kein System ausgewählt.\n\rBitte ein System auswählen, wo das Statement ausgeführt werden soll.");
					}
				}else{
					showInvalidSQLQueryMessage("Es wurde kein gültiger SQL Query eingetragen.\n\rBitte gültigen SQL Query eingeben");
				}
			}
		});
		this.add(btnPreview, gbc);
		
		gbc = new GridBagConstraints(
				3, 4, 1, 1, 0, 0, GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0);
		this.add(new JLabel("Status:"), gbc);
		
		progressBar = new JProgressBar();
		progressBar.setStringPainted(true);
				
		gbc = new GridBagConstraints(
				4, 4, 3, 1, 1, 1, GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0);
		this.add(progressBar, gbc);
		
		// Thread zum Updaten der ProgressBar
		UpdateProgress progress = new UpdateProgress();
		progress.start();
		
		// Thread für Datenbankabfrage und Schreiben in Datei
		readWriteDataLoader = new ReadWriteDataLoader();
		readWriteDataLoader.start();
		
		// Thread für eifnache Datenbankabfrage
		readDataLoader = new ReadDataLoader();
		readDataLoader.start();
		
	}
	
	/**
	 * Dialog zur Auswahl eines Verzeichnisses
	 * 
	 * @return
	 */
	private String openFileChooser(){
		JFileChooser fc = new JFileChooser();
		fc.setCurrentDirectory(new File(strSaveDir));
		
		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		
		int returnValue = fc.showOpenDialog(null);
		if(returnValue == JFileChooser.APPROVE_OPTION){
			File directory;
			directory = fc.getSelectedFile();
			return directory.getPath();
		}
		return System.getProperty("user.dir");
		
	}
	
	/** Returns an ImageIcon, or null if the path was invalid. */
	protected ImageIcon createImageIcon(String path) {
	    URL imgURL = getClass().getResource(path);
	    if (imgURL != null) {
	        return new ImageIcon(imgURL);
	    } else {
	        System.err.println("Couldn't find file: " + path);
	        return null;
	    }
	}
	
	/**
	 * Überprüft ob der eingegebene String eine gültigkeit
	 * für ein SQL Query besitzt
	 * 
	 * @param sqlQuery
	 * @return
	 */
	private boolean isSQLQueryValid(String sqlQuery){
		if(sqlQuery.isEmpty()){
			return false;
		}else if(!sqlQuery.contains("select")){
				return false;
		}else if(!sqlQuery.contains("from")){
				return false;
		}else {
			return true;
		}
	}
	
	/**
	 * Aktiviert/Deaktivert die Buttons
	 * @param enabled
	 */
	public void setButtonsEnabled(boolean enabled){
		this.btnPreview.setEnabled(enabled);
		this.btnSave.setEnabled(enabled);
	}
	
	/**
	 * Zeigt eine JOPtionPane an,
	 * die den User auf kein gültigen SQL Query 
	 * hinweist
	 */
	private void showInvalidSQLQueryMessage(String message){
		JOptionPane.showMessageDialog(null, message, "FEHLER", JOptionPane.ERROR_MESSAGE);
	}
```

JListModel - Das Model was beide verwenden.

```
public class JListModel extends AbstractListModel {
	
	private ArrayList<System> values;
	
	public JListModel(){
		this.values = DataStorageSingleton.getInstance().getEnvironment().getSystems();
	}
	
	public void addElement(System obj) {
		values.add(obj);
	    fireIntervalAdded(obj, values.size()-1, values.size()-1);
	}
	
	public void removeElement(System system){
		fireIntervalRemoved(values, values.indexOf(system), values.indexOf(system));
		values.remove(system);
	}

	public int getSize() {
		return values.size();
	}
	
	public Object getElementAt(int index) {
		return values.get(index).getName();
	}
	
	public System getSystemAt(int index){
		return values.get(index);
	}
	
	public int getIndexOfElement(System system){
		return values.indexOf(system);
	}

}
```

DataStorageSingleton - Klasse,  die es ermöglicht von überall auf die ArrayList mit den Daten zuzugreifen.

```
public class DataStorageSingleton implements DataStorage {
	
	private static DataStorageSingleton instance = null;
	private Environment environment;
	private Document document;
	
	public static DataStorageSingleton getInstance(){
		
		if(instance == null){
			instance = new DataStorageSingleton();
		}
		
		return instance;
	}

	@Override
	public Environment getEnvironment() {
		return this.environment;
	}

	@Override
	public void updateEnvironment(Environment environment) {
		this.environment = environment;
	}

	@Override
	public Document getDocument() {
		return document;
	}

	@Override
	public void updateDocument(Document document) {
		this.document = document;
	}
}
```

Ich hoffe ihr könnt mir hier weiterhelfen, ich habe lang genug nach dem Fehler gesucht.. Eventuell deswegen schon blind geworden. Ich glaube es hängt damit zusammen, dass ich kein repaint auf die JList habe bei der Auswahl-Maske.

Gruß


----------



## KrokoDiehl (19. Nov 2012)

Beim Überfliegen ist mir aufgefallen, dass du zwar Events aus dem JList-Model heraus feuerst, aber das 
	
	
	
	





```
source
```
-Objekt (erster Parameter in 
	
	
	
	





```
fireXXX()
```
) ist das Modell, nicht der neue Eintrag. Ich nehme an dass die Events deswegen von der JList ignoriert werden.


----------



## Ollek (19. Nov 2012)

public void removeElement(System system){
		fireIntervalRemoved(system, values.indexOf(system), values.indexOf(system));
		values.remove(system);
	}

Trotz dieser Umsetzung tritt der Fehler immer noch auf.
Jetzt gerade habe ich noch gesehen, dass ich nen System hinzugefügt habe, die Liste dieses aber nicht angezeigt hat. Dafür aber alle anderen.

Also irgendwo scheint es noch zu buggen ???:L;(


----------



## bERt0r (19. Nov 2012)

Nimm einfach ein DefaultListModel.


----------



## KrokoDiehl (19. Nov 2012)

Ich meinte etwas anderes Ollek:


```
public void removeElement(System system){
    values.remove(system);
    // hier das MODELL (=this) als Eventsource angeben
    fireIntervalRemoved(this, values.indexOf(system), values.indexOf(system));
}
```

Außerdem ist das mit dem Index falsch, weil indexOf() ja nichts mehr liefert wenn es schon entfernt wurde, besser also:


```
int index = values.indexOf(system);
if (index >= 0) {
    values.remove(index);
    fireIntervalRemoved(this, index, index);
}
```


----------



## Ollek (19. Nov 2012)

Wenn ich nen DefaultListModel nehme, dann kann ich mir doch nicht von einem Objekt eine Eigenschaft anzeigen lassen oder?

Denn System ist ja nen Objekt.


----------



## Ollek (19. Nov 2012)

KrokoDiehl hat gesagt.:


> Ich meinte etwas anderes Ollek:
> 
> 
> ```
> ...



Okay. Habe ich probiert. Leider tritt das Problem weiterhin auf ;(


----------



## KrokoDiehl (19. Nov 2012)

Hast du es in der Hinzufügen-Methode denn ebenso gemacht? 

Etwas wie:

```
public void addElement(System obj) {
    if (values.add(obj)) {
        int index = values.size() -1;
        fireIntervalAdded(this, index, index);
    }
}
```

UND werden die neuen Systeme auch nur über das ListModel hinzugefügt? Denn nur dann werden auch diese Events ausgelöst. Wenn du weiter "hinten" am DataStorage die Liste änderst merkt es das ListModel ja nicht direkt.
Aber soweit ich das sehe ist das über die ActionListener an "Speichern" und "Löschen" durchaus geregelt.


----------



## bERt0r (19. Nov 2012)

Ollek hat gesagt.:


> Wenn ich nen DefaultListModel nehme, dann kann ich mir doch nicht von einem Objekt eine Eigenschaft anzeigen lassen oder?
> 
> Denn System ist ja nen Objekt.



So ziemlich alles in Java ist ein objekt. Ein DefaultListModel kann alles (und mehr) was du in deinem Model machst. Du kannst es parameterisieren: 
	
	
	
	





```
DefaultListModel<System> model=new DefaultListModel<System>();
```
System ist übrigens ein ganz ganz fürchterlicher Name für eine eigene Klasse. Die Klasse java.lang.System ist nach Object so ziemlich die zentralste Klasse in Java. Du machst dir damit doch nur das Leben schwer wegen all der Verwechslungen.
Hier noch der obligatorische Link:  How to Use Lists (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

PS: Dieser ganzen fire kram nimmt dir das DefaultListModel übrigens ab.


----------



## Ollek (19. Nov 2012)

KrokoDiehl hat gesagt.:


> Hast du es in der Hinzufügen-Methode denn ebenso gemacht?
> 
> Etwas wie:
> 
> ...



Also beim Start werden die Systeme aus einer ArrayList geladen und entsprechende System-Objekte werden erstellt. Danach ist es nur noch möglich über die Eingabe-Maske einzutragen. 

Hab es in beiden Methoden angepasst. Schaue aber morgen nochmal genau nach!


----------



## Ollek (19. Nov 2012)

bERt0r hat gesagt.:


> So ziemlich alles in Java ist ein objekt. Ein DefaultListModel kann alles (und mehr) was du in deinem Model machst. Du kannst es parameterisieren:
> 
> 
> 
> ...



Also ich habe bei dem System eine Methode getName(). Der Name des Systems soll angezeigt werden.
Wie kann ich das denn realisieren? Dann sollte ich das DefaultLisModel nehmen, wenn sowas Möglich ist.

Das mit dem System stimmt. Dass muss ich morgen mal machen. Mir fiel aber kein gescheiter Name ein.


----------



## bERt0r (19. Nov 2012)

Achso das meinst du. Entweder du machst eine Methode toString in deiner System Klasse die den Namen zurückgibt oder du machest einen ListCellRenderer auf die JList. Beides ist weit weniger Arbeit als ein eigenes Model und macht nicht so viele Probleme.
Du kannst dir auch ein eigenes Model machen, aber eben nicht von AbstractListModel sondern vom DefaultListModel erben.


----------



## Ollek (20. Nov 2012)

bERt0r hat gesagt.:


> So ziemlich alles in Java ist ein objekt. Ein DefaultListModel kann alles (und mehr) was du in deinem Model machst. Du kannst es parameterisieren:
> 
> 
> 
> ...



Morgen,
also 

```
DefaultListModel<System> model=new DefaultListModel<System>();
```
ist nicht möglich.

Und ich kann der JList auch keine List bzw. ArrayList übergeben, das war auch der Grund warum ich mir nen eigenes Model geschrieben habe. Eventuell nen eigene Model machen und von DefaultListMOdel ableiten?


Habe die Systemklasse nun in DB2System umbenannt.. Danke.


----------



## KrokoDiehl (20. Nov 2012)

Morgen auch.
Aus meiner Sicht ist es sogar sauberer vom AbstractListModel zu erben, weil man sich hier um die Datentypen und Listenänderungen (add/remove/...) selbst kümmern kann. Natürlich ist das DefaultListModel eine einfache und schnellere Lösung und hat damit durchaus ihre Anwendungsgebiete.
Für mich jedoch ist die abstrakte Implementierung zumeist die erste Anlaufstelle, da sie alle allgemeinen Tätigkeiten des Modells (add/remove Listener usw.) bereitstellt aber die eigentliche Datenhaltung dem Entwickler überlässt.

Ich habe hier ein Minimalbeispiel und das funktioniert so wie es soll, im Grunde ist dort alles an Information drin, was man für deinen Fall benötigt.


```
public final class ListModelExample {

    @SuppressWarnings("serial")
    private static final class MyListModel extends AbstractListModel<String> {

        private final List<String> strings = new ArrayList<>();
        
        public void add(String str) {
            if (strings.add(str)) {
                int index = strings.size()-1;
                this.fireIntervalAdded(this, index, index);
            }
        }
        
        public void remove(int index) {
            strings.remove(index);
            this.fireIntervalRemoved(this, index, index);
        }
        
        @Override
        public int getSize() {
            return strings.size();
        }

        @Override
        public String getElementAt(int index) {
            return strings.get(index);
        }
    }
    
    
    public static void main(String[] args) {
        final AtomicInteger counter = new AtomicInteger(0);
        
        final JList<String> list = new JList<>(new MyListModel());
        
        final JButton btnAdd = new JButton("Neu");
        btnAdd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                ((MyListModel) list.getModel()).add(String.format(
                        "%d. neuer Eintrag", counter.incrementAndGet()));
            }
        });
        
        final JButton btnRemove = new JButton("Löschen");
        btnRemove.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                int i = list.getSelectedIndex();
                if (i >= 0) {
                    ((MyListModel) list.getModel()).remove(i);
                }
            }
        });
        
        final JFrame frame = new JFrame("Test Liste");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(new JScrollPane(list), BorderLayout.CENTER);
        frame.add(btnAdd, BorderLayout.WEST);
        frame.add(btnRemove, BorderLayout.EAST);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
```

[EDIT]Hm, das mit den Spoiler-Tags wollte bei mir nicht funktionieren... also habt ihr nun viel zum scrollen ;-)[/EDIT]

Wenn die 
	
	
	
	





```
fireXXX()
```
-Methoden die JList nicht aktualisieren, liegt das ggfs. an etwas anderem? Manchmal liegt es auch am Threading, wenn z.B. die fireXXX nicht im EDT ausgeführt werden. Allerdings sehe ich nicht wie es in deinem Code der Fall sein könnte.


----------



## Ollek (20. Nov 2012)

Deswegen bin ich auch den Weg über das AbstractListModel gegangen.

Aber ich habe die anpassungen, die du mir geraten hast umgesetzt. Aber immer noch eine Besserung.

Ist es eventuell das Problem, dass ich das Model 2 x mal NEW initalisiere? 
Das dürfte doch eigentlich kein problem sein, oder? Alle Listeners werden doch über die fireXXX informiert.

Was mir gerade beim Testen bzw, rekonstruieren aufgefallen ist, dass wenn ich mir in der Auswahl-Maske die JList mal genauer anschaue und sehe am Ende ist noch ein "freier" Platz und dann eine EIntragung vornehme, dann funktioniert diese. Wenn die JList komplett ausgefüllt ist und kein freier Platz am Ende ist, dann erhalte nach der Eintragung nur noch eine weiße Liste ohne Einträge drin.

Ich stelle mal Screenshots rein, damit ihr das bildlich nachverfolgen könnt. :autsch:
EintragungListeLeer zeigt den prozess, wie es aussieht wenn keine Liste mehr da ist und EintragungListeNochDa zeigt wie eine erfolgreiche Eintragung aussieht.

Ich hoffe das hilft uns weiter..


----------



## Michael... (20. Nov 2012)

Ollek hat gesagt.:


> dass ich das Model 2 x mal NEW initalisiere?


Warum, wenn beide JList das selbe Model verwenden sollen?


----------



## Ollek (20. Nov 2012)

Michael... hat gesagt.:


> Warum, wenn beide JList das selbe Model verwenden sollen?



Dachte das wäre kein Problem.
Dann müsste ich das Model an einem Ort initalisieren und an die beiden Masken über den konstruktor übergeben, richtig?


----------



## Michael... (20. Nov 2012)

Ollek hat gesagt.:


> Dachte das wäre kein Problem.
> Dann müsste ich das Model an einem Ort initalisieren und an die beiden Masken über den konstruktor übergeben, richtig?


Ja, wenn beide Objekte das selbe Model verwenden sollen, dann musst Du ihnen auch dieses geben. Nur weil Dieter Bohlen und ich einen roten Ferrari haben, fahren wir ja auch nicht im selben Auto. ;-)


----------



## Ollek (20. Nov 2012)

Ich glaube das war der Anstupser, der gefehlt hat 

Ich habe jetzt ein Model für beide JLists in meiner GUI Klasse erstellt und übergebe dieses an die entsprechenden Klassen. Habe rauf und runter gestetet, löschen und hinzufügen.. Funktioniert einwandfrei.

Danke für deinen tollen Vergleich mit dem Ferrari :toll:

Dank an alle die mitgeholfen haben.


----------

