Swing JTable - Zeile löschen mit AbstractTableModel

Ollek

Bekanntes Mitglied
Hallo,

ich habe mir ein eigenes TableModel geschrieben, dieses erbt von AbstractTableModel.
Leider stoppt es bei mir, beim löschen einer Zeile aus dem Table.
Ich habe die Daten die in der Tabelle sind in einer ArrayList gespeichert.
Wird nun ein "Job" selektiert und es wird auf den "LÖschen-Button" geklickt, gibt der Controller den Command zum löschen an das Model weiter. Der Job wird zwar gelöscht, aber es wird eine Exception geworfen.

Exception:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$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)

Hier mal das Model:
Java:
public class JobTableModel extends AbstractTableModel {
	
	//Columns Number.
    public static final int    JOB_SEL_COL = 0;                                   
    public static final int    JOB_NAME_COL = 1;
    public static final int    JOB_FOLDERS_COL = 2;
    public static final int    JOB_DATE_COL = 3;
	
    private String[] columnNames = new String[]{"Upload", "Job Name", "Unterverzeichnisse", "Datum" };
	private ArrayList<Job> jobList;
	private ArrayList<Job> jobListSeleted;
	private ArrayList<TableModelListener> tableListener = new ArrayList<TableModelListener>();
	
	public JobTableModel(){
		super(); 
		this.jobList = new ArrayList<Job>();
		this.jobListSeleted = new ArrayList<Job>();
		this.addTableModelListener(new TableModelListener() {
			
			@Override
			public void tableChanged(TableModelEvent e) {
				int column = e.getColumn();
				int row = e.getFirstRow();
				//aktuellen Job holen
				Job job = (Job) getValueAt(row);
				if(job.isUpload()){
					jobListSeleted.add(job);
					System.out.println("JOB Seleted");
				}else{
					jobListSeleted.remove(job);
				}
			}
		});
	}
	
	
	@Override
	public int getColumnCount() {
		return columnNames.length;
	}

	@Override
	public int getRowCount() {
		return jobList.size();
	}
	
	/**
	 * Aktualisiert die Daten im TableModel
	 * nachdem diese in der Tabelle geändert 
	 * wurden
	 */
	public void setValueAt(Object value, int row, int col){
		
		Job job = jobList.get(row);	
		
		switch(col){
		case JOB_SEL_COL: job.setUpload((Boolean)value); break;
		case JOB_NAME_COL: job.setName((String)value); break;
		case JOB_FOLDERS_COL: value.toString(); break;
		case JOB_DATE_COL: job.setDate((String)value); break;
		}
		fireTableCellUpdated(row, col);
	}

	/**
	 * Gibt den Wert, welcher sich in den 
	 * übergebenen Parametern befindet zurück
	 * 
	 */
	@Override
	public Object getValueAt(int row, int column) {
		Job job = jobList.get(row);
		
		String folders = "";
		if(job.getSourceFolders().length > 0){
			for (String folder : job.getSourceFolders()) {
				if(folders.isEmpty())
					folders += folder;
				else
					folders += "\n" + folder;
			}
		}
		
		switch(column){
		case JOB_SEL_COL: return job.isUpload();
		case JOB_NAME_COL: return job.getName();
		case JOB_FOLDERS_COL: return folders;
		case JOB_DATE_COL: return job.getDate();
		default: return new Object();
		}
	}
	
	/**
	 * Gibt das Object zurück, was sich
	 * in der übergebenen Zeile befindet
	 *  
	 * @param row
	 * @return
	 */
	public Object getValueAt(int row){
		return jobList.get(row);
	}
	
	public String getColumnName(int iColumn){
		return columnNames[iColumn];
	}
	
	// passendes Format in der Spalte wird angezeigt
	public Class getColumnClass(int columnIndex){
		switch(columnIndex){
			case 0: 	return Boolean.class;
			default: 	return String.class;
		}
	}
	
	public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        return col == 0;
    }
	
	public ArrayList<Job> getSelectedJobs() {
		System.out.println("JobTableModel.getSelectedJobs() " + jobListSeleted.size());
		return jobListSeleted;
	}

	public void setSelectedJobs(ArrayList<Job> arrlSelectedJobs) {
		this.jobListSeleted = arrlSelectedJobs;
	}
	
	public ArrayList<Job> getJobList() {
		return jobList;
	}
	

	/**
	 * Fügt einen Job in die
	 * ArrayList des Models hinzu
	 * 
	 * @param job
	 */
	public void addJob(Job job){
		jobList.add(job);
		this.fireTableDataChanged();
	}

	/**
	 * Löscht einen bestehen Job aus
	 * der ArrayList des Models
	 * 
	 * @param job
	 */
	public void removeJob(Job job) {
		this.jobListSeleted.clear();
		int jobIndex = -1;
		for(Job aktJob : jobList){
			if(aktJob.getName().equals(job.getName())){
				jobIndex = jobList.indexOf(aktJob);
				System.out.println("JOB gefunden: " + job.getName());
			}				
		}
		jobList.remove(jobIndex);
		
		fireTableRowsDeleted(jobIndex, jobIndex);
	}
}

Übergabe des Commands vom Controller
Java:
public void removeJob(Job job) {
		view.getTable().getModel().removeJob(job);
		
}

Ich habe es auch schon mit fireTableDataChanged() in der removeJob(Job job) Methode probiert, ebenfalls eine Exception.

Leider komme ich nicht weiter.
 

KrokoDiehl

Top Contributor
Kann es sein dass der Job, der gelöscht werden soll nicht gefunden wird und daher der jobIndex = -1 ist? In dem fall darfst du kein
Code:
fireTableRowsDeleted()
machen weil nämlich nichts gelöscht wurde.

Wenn du in der remove-Methode den Job übergibts solltest du nicht mühselig die Liste durchiterieren sondern direkt etwas machen wie:

Java:
public void removeJob(Job job) {
    int index = jobList.indexOf(job);
    if (index >= 0) {
        jobList.remove(index);
        fireTableRowsDeleted(index, index);
    }
}

*EDIT*
Analog für
Code:
addJob()
.
 

Ollek

Bekanntes Mitglied
Kann es sein dass der Job, der gelöscht werden soll nicht gefunden wird und daher der jobIndex = -1 ist? In dem fall darfst du kein
Code:
fireTableRowsDeleted()
machen weil nämlich nichts gelöscht wurde.

Wenn du in der remove-Methode den Job übergibts solltest du nicht mühselig die Liste durchiterieren sondern direkt etwas machen wie:

Java:
public void removeJob(Job job) {
    int index = jobList.indexOf(job);
    if (index >= 0) {
        jobList.remove(index);
        fireTableRowsDeleted(index, index);
    }
}


Diese Idee habe ich zu aller erst ebenfalls ausprobiert. Leider bliebt der Job in der JTable bestehenn und löscht sich nicht raus, da indexOf ein -1 zurückliefert.
Das Problem könnte dort sein, dass er Job der gelöscht werden soll von einem Server gesendet wird und aus diesem grund nicht in der Liste gefunden werden kann? Leider habe ich es auch nciht verstanden warum der Job nicht gelöscht wurde, deswegen habe ich den Weg mit der for-Schleife gewählt um die Jobs durch die Namen zu finden.

Wenn ich die Liste nach dem job mit contains abfrage erhalte ich ebenfalls ein false, obwohl in den Jobs das identische drin steht, der Job nur vom anderen Server kommt.

Deswegen muss ich einen anderen Weg finden, wie ich den Job aus der ArrayList löschen kann.
 

Ollek

Bekanntes Mitglied
Habe nun ma noch eine andere Sache ausprobiert.
Wenn ich die Methode folgendermaßen ändere:

Java:
public void removeJob(Job job) {
//		this.jobListSeleted.clear();
		int index = -1;
		for(Job aktJob : jobList){
			if(aktJob.getName().equals(job.getName())){
				index = jobList.indexOf(aktJob);
				System.out.println("JOB gefunden: " + job.getName());
			}				
		}
//		int index = jobList.indexOf(job);
	    if (index >= 0) {
	    	System.out.println("GEFUNDEN");
	        jobList.remove(index);
	        fireTableRowsDeleted(index, index);
	    }
		
//		fireTableRowsDeleted(jobIndex, jobIndex);
	}

dann erhalte ich diese Exception...

Code:
Exception in thread "Thread-3" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
	at java.util.ArrayList.RangeCheck(Unknown Source)
	at java.util.ArrayList.get(Unknown Source)
	at de.ernsting.gui.JobTableModel.getValueAt(JobTableModel.java:115)
	at de.ernsting.gui.JobTableModel$1.tableChanged(JobTableModel.java:38)
	at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
	at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(Unknown Source)
	at de.ernsting.gui.JobTableModel.removeJob(JobTableModel.java:191)
	at de.ernsting.controller.JobController.removeJob(JobController.java:168)
	at de.ernsting.network.Client.run(Client.java:115)
	at java.lang.Thread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$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)

Der Job wird allerdings aus der JTable gelöscht.

Dort muss doch irgendwo der Fehler im Detail stecken, ich beiß mir da echt die Zähne aus... :eek:
 

KrokoDiehl

Top Contributor
Ok, bei erstem kannst du ggfs noch überleben die equals()-Methode von Job zu überschreiben. Aber wenn das manuelle Suchen funktioniert ist es ok. Mit der index >= 0 Prüfung sollte es dann auch an der Stelle hinhauen.

Zu den weiteren Ausnahmen: Prinzipiell sagt das "invalid index" das irgendwo mit einem negativen Index auf die Liste zugegriffen wird. Also irgendwo kommt noch ein -1 oder so raus.
Die obere Ausnahme ist deutlicher: Die Liste hat Größe 1 und du kommst mit Index 1, was eben nicht geht. Diese Ausnahme kommt aus deinem anonymen TableModelListener, den du an dein Modell selbst hängst. Vermutlich nach einem Deleted-Event und dann gibt es den gelöschten Index nicht mehr. Also hier noch nach den Eventtyp prüfen bevor du mit getValueAt() rangehst.

Übrigens halte ich es für seltsam bzw. unnötig kompliziert sich selbst zuzuhören ;-)
 

Ollek

Bekanntes Mitglied
Danke, werde ich gleich mal einbauen :)

Aber ich muss irgendwie herausfinden, welche Jobs nun selektiert wurden und welche nicht.
Hast du dort sonst einen anderen Vorschlag, wie ich überprüfen kann, ob der Job selektiert wurde oder nicht? :rtfm:
 

Ollek

Bekanntes Mitglied
Habs nun folgendermaßen geändert, da der -1 Wert in dem TableModelListener vorkam.
Allerdings bringt es nicht den gedachten erfolg, erhalte die Exception, die ich unten wieder angebe immer noch. Wie kann ich denn den -1 Wert abfangen, geht es überhaupt??
Java:
this.addTableModelListener(new TableModelListener() {
			
			@Override
			public void tableChanged(TableModelEvent e) {
				System.out.println("EVENT_TYPE: " +e.getType());
				if(e.getType() != -1 && e.getType() == TableModelEvent.UPDATE){
					System.out.println("UPDATE erhalten");
					int column = e.getColumn();
					int row = e.getFirstRow();
					//aktuellen Job holen
					Job job = (Job) getValueAt(row);
					if(job.isUpload()){
						jobListSeleted.add(job);
						System.out.println("JOB Seleted");
					}else{
						jobListSeleted.remove(job);
					}
				}
			}
		});

public void removeJob(Job job) {
		this.jobListSeleted.clear();
		int index = -1;
		for(Job aktJob : jobList){
			if(aktJob.getName().equals(job.getName())){
				index = jobList.indexOf(aktJob);
			}				
		}

		if (index >= 0) {
	        jobList.remove(index);
	        fireTableRowsDeleted(index, index);
	    }
	}

Wenn du natürlich jetzt noch einen Vorschlag hast, wie ich mir nicht selber zuhören muss bzw. wie ich mitbekomme das ein job selektiert oder deselektiert wird, wäre ich dir sehr dankbar :)
Eventuell wäre dann das problem mit dem -1 Wert und dem Invalid Index auch gelöst ???:L

Code:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$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)
 
Zuletzt bearbeitet:

KrokoDiehl

Top Contributor
Mal zur Klarheit: Das Tabellenmodell ist nur zur Verwaltung der Daten da, die Selektion geschieht über die Ansicht (JTable). An die Tabelle kannst du einen Listener hängen (bzw. an das SelectionModel der Tabelle...) und der bekommt die Selektionen mit. Was gerade selektiert ist, ist aber keine Sache für das Modell. Ferner werden Selektionen auch gar nicht über den TableModelListener behandelt.

Mein Vorschlag also: Das Modell soll nur deine Jobs verwalten, mit add()- und remove()-Methoden, ggfs. auch set() und jeweilige Änderungen über
Code:
fireXXXX()
propagieren. Mehr nicht.

Selektion etc. ist eher eine Sache für den Controller (im MVC). Also hier wie gesagt an die Tabelle einen SelectionListener hängen (
Code:
myTable.getSelectionModel().addListSelectionListener()
).


Bonusmaterial:
Bei Tabellen muss man auch zwische View- und Model-Koordinaten aufpassen. Wenn du z.B.
Code:
myTable.getSelectedRow()
nimmst dann liefert es dir den VIEW-Index der ersten selektierten Zeile zurück. Der muss nicht mit dem Modell-Index übereinstimmen, vor allem dann nicht, wenn du deine Tabelle sortiert hast.
Für solche Übersetzungen gibt es die Methoden
Code:
convertRowIndexToModel()
etc. an der JTable. Gleiches gibt auch für Spalten.

So bis morgen ;)
 

Ollek

Bekanntes Mitglied
Danke, werde ich mal ausprobieren.
Habs gerade auf die schnelle mal gemacht um ein bisschen rumzuspielen.

Da bin ich schon direkt aufs erste Problem gestürzt.

Java:
this.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			
			@Override
			public void valueChanged(ListSelectionEvent e) {
				int row = getSelectedRow();
		        int column = getSelectedColumn();
		       							
		        Job job = (Job) model.getValueAt(convertRowIndexToModel(row));
				if(job.isUpload()){
					selectedJobs.add(job);
					System.out.println("JOB selektiert");
				}else{
					selectedJobs.remove(job);
					System.out.println("JOB deselektiert");
				}
			}
		});

Die Prüfung tritt nur ein, wenn ich wirklich eine neue Spalte selektiere, sollte ich die ganze Zeit auf der einen Spalte bleiben und dann immer in der JCkeckbox den Upload an und abwählen, ändert sich leider nix. Da ich wirklich nur den Status von der ComboBox zurück erhalte, sobald ich eine neue Zeile ausselektiert habe. ???:L

Hoffe du verstehst mein Problem.

Hänge nochmal nen Screenshot an, damit du nochmal grafisch siehst, was ich mit der ComboBox meine.
 

Anhänge

  • UM.jpg
    UM.jpg
    68,9 KB · Aufrufe: 35

KrokoDiehl

Top Contributor
Ah ja... diese Sache. Ehrlich gesagt bin ich bei den Indizes an dem SelectionEvent auch überfragt, daher gehe ich immer über die Tabelle. Vorher auch noch das "valueAdjusting" abprüfen:

Java:
@Override
public void valueChanged(ListSelectionEvent e) {
    if (e.getValueIsAdjusting()) {
        return;
    }

    int row = myTable.getSelectedRow();
    if (row >= 0) {
        row = myTable.convertRowIndexToModel(row);
        ...
    }
}
 

Ollek

Bekanntes Mitglied
Das habe ich so auch umgesetzt gehabt, allerdings wenn ich die Zeile nicht wechsel, dann kann ich selektieren und deselektieren wie ich will, nimmt nix an.. :rtfm:

Muss doch möglich sein, so eine selektierung außerhalb des Models abzufangen...
 

Momolin

Aktives Mitglied
Hi Ollek,

ich habe dich nun so verstanden:
Du hast Dein Modell mit den Jobs und Änderungen am Modell kann entweder der User über die Tabelle machen oder Änderungen kommen von einem Server.

Wenn also eine Löschauftrag von einem Server (oder einer anderen Quelle) kommt, dann ist das ja schon völlig richtig, das Löschen (oder Ändern) am Modell zu machen.

Ich bin sicher die Exceptions kommen von dem Aufruf
Code:
fireTableRowsDeleted(jobIndex, jobIndex)
. Der Index in Deinem Modell muss nicht der Zeile in der Tabelle (= View) entsprechen, nimm lieber
Code:
fireTableDataChanged();
:
Java:
public void removeJob(Job job) {
	// das brauchst Du nicht
	// this.jobListSeleted.clear();
	int jobIndex = -1;
	for (Job aktJob : jobList) {
		if (aktJob.getName().equals(job.getName())) {
			jobIndex = jobList.indexOf(aktJob);
			System.out.println("JOB gefunden: " + job.getName());
		}
	}

	// hier würde ich auf alle Fälle die eine if-Abfrage machen
	if (jobIndex != -1) {
		jobList.remove(jobIndex);
		// du kannst dich nicht darauf verlassen, das die Zeile in der
		// Tabelle auch dem Index in deinem Modell entspricht, insbesondere
		// wenn die Tabelle umsortiert wurde
		// fireTableRowsDeleted(jobIndex, jobIndex);
		fireTableDataChanged();
	}
}

Dann musst Du wirklich keinen TableModelListener an Dein TableModel hängen. Deine Modell weiß doch immer wann es geändert wurde (Du programmierst das ja ;)).

Nun zum Abfragen der Selektion außerhalb des Modells:
Wenn Du Änderungen an der Tabellen-Selektierung mitbekommen willst, dann würde ich die Tabelle (oder besser deren Container, z.B. eine JFrame) ListSelectionListener implementieren lassen:

Java:
public class JobTable extends JFrame implements ListSelectionListener {

private JTable table;
private JobModel jobModel;

  public JobTable () {
        jobModel = new JobModel();

        // hier werden Tabelle und übrigens Modell so verbunden
        // das die Tabelle nun auf Modell-Änderungen hören (Listener) kann
       // und auch Änderungen aus der Tabelle gleich in das Modell eintragen kann, mit
       // @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex)
       table = new JTable(jobModel);
       table.getSelectionModel().addListSelectionListener(this);
  }

  @Override
   public void valueChanged(ListSelectionEvent arg0) {
	ListSelectionModel smodel;
	int changed;
	int selectedRow;

	smodel = table.getSelectionModel();
        changed = smodel.getMinSelectionIndex();
	selectedRow = table.getSelectedRow();
	// natürlich sollte man im echten Programm was besseres tun
        System.out.println("changed = " + changed + ", selectedRow =" + selectedRow);
    }
}

und wenn Du nun noch mit einem Button selektiert Jobs löschen willst, dann geht das in einer ActionPerformed-Methode:

Java:
//irgendein Lösch-Button wurde geklickt ...
public void actionPerformed(ActionEvent arg0) {
int selectedRow = table.getSelectedRow();

if (selectedRow != -1) {
// das ist wichtig, wenn der User die Tabelle umsortieren darf
	int modelRow = table.convertRowIndexToModel(selectedRow);
	
// und sollte es noch einen aktiven Editor geben,
// sollte man den Beenden um sicher alle Tabllen-Werte im Model zu haben
        if (table.getCellEditor() != null) {
		table.getCellEditor().cancelCellEditing();
	}
	tableModel.removeJob(modelRow);
}
}

dazu muss das Modell natürlich
Code:
removeJob(int selectedRow)
implementieren:
Java:
public void removeJob(int selectedRow) {
		if (selectedRow >= 0 && selectedRow < jobs.size()) {
			jobs.remove(selectedRow);
			fireTableDataChanged();
		}
	}

ich hoffe das hilft Dir weiter.

Grüße
Momolin
 

Ollek

Bekanntes Mitglied
Hallo Momolin,

der erste Part von deinem Post hat mir weiter geholfen.
Der zweite trifft leider nicht mein Problem.

Ich versuche es nochmal etwas besser zu erläutern.

Ich habe eine Tabelle mit sogenannten "Jobs". Diese Jobs können in der ersten Spalte mit einem Häckchen versehen werden, somit sind diese für den upload selektiert. (siehe Screenshot).
Die erste Spalte in der Tabelle ist auch die einzige Spalte, die bearbeitet werden darf. Die Spalte gibt einen Boolean zurück, entweder true= ausgewählt oder false= nicht ausgewählt. Und das bekomme ich leider nicht mit durch deinen Vorschlag.
Bei deinem Vorschlag erhalte ich eine Info, wenn eine neue Zeile ausgewählt wurde, aber nicht ob sich der boolean Wert in Spalte eins geändert hat.
Das habe ich bis Dato über einen TableModelListener gelöst, der sich selber zuhört, denke das ist nicht die feine Art und auch nicht die Aufgabe von model, wurde mir in diese, Post ja schon klar gemacht. :rtfm:

Ich hoffe, ihr habt mein problem jetzt verstanden und könnt mir dort helfen? ???:L

Viele Grüße

Ollek
 

Anhänge

  • UM.jpg
    UM.jpg
    77,4 KB · Aufrufe: 42

Momolin

Aktives Mitglied
Hi Ollek,

jetzt habe ich es verstanden, dann war der Rat, das TableModel keinen Listener implementieren zu lassen, kein guter Rat.

Mein Vorschlag, das TableModel added sich selber im Konstruktor als Listener, natürlich implementiert es auch das Interface:
Java:
public class JobTableModel extends AbstractTableModel implements
		TableModelListener {
	private List<Job> jobs = new ArrayList<Job>();
	// [..]
	public JobTableModel() {
		// [..]
		this.addTableModelListener(this);
	}
}
in der Methode
Code:
@Override	public void tableChanged(TableModelEvent arg0)
geht man dann die Liste der Jobs durch und sucht die neu ausgewählten:
Java:
	@Override
	public void tableChanged(TableModelEvent arg0) {
		for (Job job : jobs) {
			if (job.isUpload() && job.isEditable()) {
				job.setEditable(false);
				// und mache was mit dem Job ...
				System.out
						.println("Job " + job.getName() + " wird hochgeladen");

			}
		}
	}

Job erweitere ich um ein Attribut
Code:
editable
, so dass ich in
Code:
public boolean isCellEditable(int rowIndex, int columnIndex)
verhindern kann, dass ein schon hochgeladener Job immer wieder neu ausgewählt wird:
Java:
	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return columnIndex == 0 && jobs.get(rowIndex).isEditable();
	}

Viele Grüße
Momolin
 
Zuletzt bearbeitet:

Ollek

Bekanntes Mitglied
Hi Momolin,

Danke!
Hat mir sehr geholfen, sowas in der Art hatte ich ebenfalls schon, allerdings habe dort immer Exceptions geworfen bekommen. ;(

Aber die Erweiterung für den Job ist doch eigentlich nicht sinnvoll, wenn der Job nochmal deselektiert werden darf? Oder sehe ich das falsch?

Es soll den Usern nämlich weiterhin möglich sein, dass se den Job auch wieder deselektieren dürfen.
 

Ollek

Bekanntes Mitglied
Weiter erhalte ich beim Löschen nun immer noch folgender Exception:

Java:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.access$700(Unknown Source)
	at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$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)

Ich habe schon vieles ausprobiert, finde auch nicht heraus, wo se ausgelöst wird. ???:L
Tritt immer beim Löschen eines Jobs auf...

Überarbeiteted TableModel:
Java:
public class JobTableModel extends AbstractTableModel implements TableModelListener {
	
	//Columns Number.
    public static final int    JOB_SEL_COL = 0;                                   
    public static final int    JOB_NAME_COL = 1;
    public static final int    JOB_FOLDERS_COL = 2;
    public static final int    JOB_DATE_COL = 3;
	
    private String[] columnNames = new String[]{"", "Job Name", "Unterverzeichnisse", "Datum" };
	private ArrayList<Job> jobs;
	private ArrayList<Job> selectedJobs;
	private ArrayList<TableModelListener> tableListener = new ArrayList<TableModelListener>();
	
	public JobTableModel(){
		super(); 
		this.jobs = new ArrayList<Job>();
		this.selectedJobs = new ArrayList<Job>();
		this.addTableModelListener(this);
	}
	
	
	@Override
	public int getColumnCount() {
		return columnNames.length;
	}

	@Override
	public int getRowCount() {
		return jobs.size();
	}
	
	/**
	 * Aktualisiert die Daten im TableModel
	 * nachdem diese in der Tabelle geändert 
	 * wurden
	 */
	public void setValueAt(Object value, int row, int col){
		
		Job job = jobs.get(row);	
		
		switch(col){
		case JOB_SEL_COL: job.setUpload((Boolean)value); break;
		case JOB_NAME_COL: job.setName((String)value); break;
		case JOB_FOLDERS_COL: value.toString(); break;
		case JOB_DATE_COL: job.setDate((String)value); break;
		}
		fireTableCellUpdated(row, col);
	}

	/**
	 * Gibt den Wert, welcher sich in den 
	 * übergebenen Parametern befindet zurück
	 * 
	 */
	@Override
	public Object getValueAt(int row, int column) {
		Job job = jobs.get(row);
		
		String folders = "";
		if(job.getSourceFolders().length > 0){
			for (String folder : job.getSourceFolders()) {
				if(folders.isEmpty())
					folders += folder;
				else
					folders += "\n" + folder;
			}
		}
		
		switch(column){
		case JOB_SEL_COL: return job.isUpload();
		case JOB_NAME_COL: return job.getName();
		case JOB_FOLDERS_COL: return folders;
		case JOB_DATE_COL: return job.getDate();
		default: return new Object();
		}
	}
	
	/**
	 * Gibt das Object zurück, was sich
	 * in der übergebenen Zeile befindet
	 * zurück
	 * 
	 * @param row
	 * @return
	 */
	public Object getValueAt(int row){
		System.out.println("Zeile: " + row);
		return jobs.get(row);
	}
	
	public String getColumnName(int iColumn){
		return columnNames[iColumn];
	}
	
	// passendes Format in der Spalte wird angezeigt
	public Class getColumnClass(int columnIndex){
		switch(columnIndex){
			case 0: 	return Boolean.class;
			default: 	return String.class;
		}
	}
	
	public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        return col == 0;
    }
	
	public ArrayList<Job> getSelectedJobs() {
		return selectedJobs;
	}
	
	public ArrayList<Job> getJobs() {
		return jobs;
	}
		
	/**
	 * Fügt einen Job in die
	 * ArrayList des Models hinzu
	 * 
	 * @param job
	 */
	public void addJob(Job job){
		jobs.add(job);
		this.fireTableDataChanged();
	}

	/**
	 * Löscht einen bestehen Job aus
	 * der ArrayList des Models
	 * 
	 * @param job
	 */
	public void removeJob(Job job) {
		int index = -1;
		for(Job aktJob : jobs){
			if(aktJob.getName().equals(job.getName())){
				index = jobs.indexOf(aktJob);
			}				
		}
		
		if (index > -1) {
			jobs.remove(index);
			
	        if(jobs.size() > 0){
	        	fireTableDataChanged();
	        }
	    }
	}

	@Override
	public void tableChanged(TableModelEvent event) {
		System.out.println();
		System.out.println("VERÄNDERUNG!" + event.getType());
		if(event.getType() > TableModelEvent.DELETE){
		for(Job job : jobs){
			if(job.isUpload() && job.isEditable()){
				job.setEditable(false);
				selectedJobs.add(job);
			} else if(!job.isUpload() && !job.isEditable()) {
				job.setEditable(true);
				selectedJobs.remove(job);
			}
		}
		}
	}
	
}
 

Ollek

Bekanntes Mitglied
Ok.
Habs folgendermaßen geändert.
Java:
public void removeJob(Job job) {
	int index = -1;
	for(Job aktJob : jobs){
		if(aktJob.getName().equals(job.getName())){
			index = jobs.indexOf(aktJob);
		}				
	}
	
	if (index > -1) {
		jobs.remove(index);
		fireTableDataChanged(); //SObald ich in der Liste was lösche, wird eine Changed Methode aufgerufen!
    }
}

Allerdings erhalte ich immer noch die Exception.
 

Ollek

Bekanntes Mitglied
So haben nochmal etwas rumprobiert...
Habe aus der JTable Klasse mal den selbstgeschriebenen TableCellRenderer und den DefaultTableCellRenderer rausgenommen. Danach konnte ich Zeilen löschen, einfügen, aktualisieren ohne irgendeine Exception und so oft ich wollte...
Denke dort liegt das Problem..

Wie kann ich denn mit diesen beidenen Renderer diesen Exceptions aus dem Weg gehen, weiß dies jemand? Scheinen sich nicht zu vertragen... ;(

Hier nochmal der Code, der JTable Klasse.
Java:
public class JobTable extends JTable {
	
	private JobTableModel model;
	private Config config = Config.getInstance();
	private FileIO fileIO = new FileIO();
	private ArrayList<Job> selectedJobs;
	
	
	public JobTable(){
		selectedJobs = new ArrayList<Job>();
		init();
	}

	private void init() {
		model = new JobTableModel();		
		
		this.setModel(model);
		this.setAutoCreateRowSorter(true);
		this.setSurrendersFocusOnKeystroke(true);
		this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);	
			
		// Setzen der passenden Ausrichtung innerhalb der Zelle
		this.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
		{
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
			{
				/* Sollten die Spalten durch den User neu sortiert sein,
				 * dann haben die spalten einen neuen Index. Man benötigt den Modelindex
				 */
				final int modelColumn = table.convertColumnIndexToModel(column);
				switch (modelColumn)
				{
						/* alignment left setzen */
					default :
						setVerticalAlignment(JLabel.TOP);
				}
				return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			}
		});
		
		// Tabellen Header Einstellungen - aktuellen holen, von der JTable um damit abreiten zu können
		JTableHeader tblHeader = this.getTableHeader();
		tblHeader.setResizingAllowed(false);
		tblHeader.setReorderingAllowed(false);
				
		// Spaltenbreite setzen
		this.getColumnModel().getColumn(0).setMaxWidth(43);
		this.getColumnModel().getColumn(1).setMinWidth(120);
		this.getColumnModel().getColumn(2).setMinWidth(380);
		this.getColumnModel().getColumn(3).setMinWidth(20);
		
		TableColumn column = this.getColumnModel().getColumn(2);
		column.setCellRenderer(new TwoLinesCellRenderer());
	}
	
	public JobTableModel getModel(){
		return model;
	}
	
	/**
	 * Renderer für eine mehrzeilige Zellen.
	 * 
	 */
	private class TwoLinesCellRenderer extends JTextArea implements TableCellRenderer {

		@Override
		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			
			if (isSelected){		    	
	      		setForeground(table.getSelectionForeground());
	      		setBackground(table.getSelectionBackground());
		    }	 
	    	else{
	      		setForeground(table.getForeground());
	      		setBackground(table.getBackground());
	    	} 
			
			setFont(table.getFont());
			setText(value.toString());
			
			// Passt die Zellenhöhe nur an, wenn die aktuelle ungleich der TA ist und die Tabelle Daten hat
			if (table.getRowHeight() != (int) this.getMinimumSize().height && table.getModel().getRowCount() > 0){ 
				table.setRowHeight(row, (int) this.getMinimumSize().height);
			}
			
			return this;
		}
	}
}
 

Momolin

Aktives Mitglied
Hallo Ollek,

hm, das ist etwas rätselhaft.

Weiter erhalte ich beim Löschen nun immer noch folgender Exception:

Java:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.convertRowIndexToModel(Unknown Source)
	at javax.swing.JTable.getValueAt(Unknown Source)
	at javax.swing.JTable.prepareRenderer(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
	at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent._paintImmediately(Unknown Source)
	at javax.swing.JComponent.paintImmediately(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.access$700(Unknown Source)
	at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$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)
hier sind nur die Orte der Ausnahmen in den Paketen
Code:
java.awt
und
Code:
javax.swing
. Ist beim StackTrace noch eine Ausgabe, wo es in Deinem Code "angefangen" hat, also so was wie
Code:
at JobTable.getModel(Unknow Source)
?

Grüße
Momolin
 

bERt0r

Top Contributor
Das ist typisch wenn der JTable versucht eine Zeile zu zeichnen die das Model nicht mehr hergibt. Darum muss das Model nach jeder änderung die JTable benachrichtigen - dafür gibts verschiedene Methoden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Swing AWT-Exception bei JTable mit JComboBox beim Löschen der letzten Zeile AWT, Swing, JavaFX & SWT 3
F Swing JTable: Problem beim zeile löschen AWT, Swing, JavaFX & SWT 3
R JTable Zeile löschen AWT, Swing, JavaFX & SWT 4
A Zeile in JTable einfügen/löschen- Tutorial gesucht AWT, Swing, JavaFX & SWT 9
H jtable makierte zeile löschen AWT, Swing, JavaFX & SWT 4
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
T Swing JTable Zeile mit ausgelesenen Werten mit Hilfe von einem Button hinzufügen AWT, Swing, JavaFX & SWT 1
J Swing JTable Zeile nicht auswählbar machen AWT, Swing, JavaFX & SWT 0
J JTable Zeile anklicken und neues Frame öffnen AWT, Swing, JavaFX & SWT 4
S JTable nach aktualisierung - neue Zeile nicht "klickbar" AWT, Swing, JavaFX & SWT 0
D Swing Letzte Zeile einer JTable nicht über RowSorter sotieren AWT, Swing, JavaFX & SWT 2
B jTable ganze Zeile anhand eines Kriterium färben AWT, Swing, JavaFX & SWT 6
P Swing Alle Zeilen einer Spalte (jTable) zusammen zählen und in eine eigene Zeile das Ergebnis schreiben. AWT, Swing, JavaFX & SWT 7
S Swing Kopieren einer vollständigen Zeile einer JTable AWT, Swing, JavaFX & SWT 3
H Unterschiedliche JComboBox je JTable Zeile AWT, Swing, JavaFX & SWT 4
J Swing JTable: Komplette Zeile aber ohne Spalten markieren AWT, Swing, JavaFX & SWT 11
G Zeile in JTable durch rechte Maustaste manipulieren AWT, Swing, JavaFX & SWT 4
Meldanor Swing JTable - Eine neue Zeile vor einer bestehenden Einfügen AWT, Swing, JavaFX & SWT 2
R Zeile in JTable anhand von Wert einfärben AWT, Swing, JavaFX & SWT 2
N JTable, Zeile bleibt immer selektiert.... AWT, Swing, JavaFX & SWT 3
N Methode zum ermitteln der editierte Zeile/Zelle in jTable AWT, Swing, JavaFX & SWT 8
C Mit SelectionListener herausfinden welche zeile in Jtable angeklickt wurde AWT, Swing, JavaFX & SWT 5
E In JTable neue Zeile mit Tabulator einfügen AWT, Swing, JavaFX & SWT 5
R JTable Hintergrund der Zeile abhängig von Inhalt einer Zelle verändern AWT, Swing, JavaFX & SWT 3
C JTable mit RowSorter und Drag & Drop: Zeile verschieben AWT, Swing, JavaFX & SWT 4
P JTable zeile einfärben AWT, Swing, JavaFX & SWT 1
N Farbe einer einzelnen Zeile einer JTable ändern AWT, Swing, JavaFX & SWT 10
R JTable: Zellen einer Zeile zusammenfassen? AWT, Swing, JavaFX & SWT 3
D JTable um eine Zeile erweitern AWT, Swing, JavaFX & SWT 4
GilbertGrape JTable - immer leere Zeile AWT, Swing, JavaFX & SWT 6
A JTable zeile auswählen AWT, Swing, JavaFX & SWT 2
S in JTable eine Zeile färben AWT, Swing, JavaFX & SWT 5
T JTable ohne Titel in der ersten Zeile AWT, Swing, JavaFX & SWT 2
K leere Zeile zu JTable zufügen AWT, Swing, JavaFX & SWT 2
E JTable letzte Zeile in Fett schrift? AWT, Swing, JavaFX & SWT 3
O JTable + event wenn andere Zeile selektiert ist AWT, Swing, JavaFX & SWT 5
O JTable Zeile zuweisen und weiter mit dem Button AWT, Swing, JavaFX & SWT 2
M JTable & Problem, das nicht die komplette Zeile gefärbt AWT, Swing, JavaFX & SWT 6
G JTable erste zeile fixieren wie in excel? AWT, Swing, JavaFX & SWT 3
Z JTable automatisch zu einer Zeile scrollen AWT, Swing, JavaFX & SWT 4
G JTable Zeile zurückgeben AWT, Swing, JavaFX & SWT 4
D Herausfinden auf welche Zeile in einer JTable geklickt wurde AWT, Swing, JavaFX & SWT 2
S JTable: Zeile unter MouseCursor farblich hervorheben AWT, Swing, JavaFX & SWT 2
N Die Zeile einer JTable verändert beim klicken ihre Farbe? AWT, Swing, JavaFX & SWT 7
S Eine Zeile zu einer JTable hinzufügen wo Zelle selektiert is AWT, Swing, JavaFX & SWT 4
G JTable Zeile mit Farbe füllen AWT, Swing, JavaFX & SWT 2
G JTable komplette Zeile auf deaktiv setzen AWT, Swing, JavaFX & SWT 2
B JTable erste Zeile aktiv AWT, Swing, JavaFX & SWT 6
K JTable: letzte Zeile immer sichtbar AWT, Swing, JavaFX & SWT 2
G JTable-Zeile/Zelle markieren und mir Shortcut in Arbeitsspei AWT, Swing, JavaFX & SWT 3
A Zeile in einer JTable einfügen AWT, Swing, JavaFX & SWT 4
K JTable - ganze Zeile soll nicht markiert werden AWT, Swing, JavaFX & SWT 2
F JTable: Selektion einer kompletten Zeile AWT, Swing, JavaFX & SWT 5
G JTable selektion der Zeile bei Fokusieren mit der Maus AWT, Swing, JavaFX & SWT 5
C JTable -> Rechtsklick -> Zeile markieren AWT, Swing, JavaFX & SWT 5
N JTable Ganze Zeile markieren AWT, Swing, JavaFX & SWT 8
G Farbe einer JTable-Zeile von "Außen" ändern AWT, Swing, JavaFX & SWT 2
M JTable mit JCombobox eigene Auswahl pro Zeile ? AWT, Swing, JavaFX & SWT 3
L Falsche Zeile gelöscht nach Spalte Sortierung in JTable AWT, Swing, JavaFX & SWT 2
V Click auf JTable (Zeile) liefert den Eintrag? AWT, Swing, JavaFX & SWT 11
M Farbe der Umrandung einer ausgwählten Zeile ändern (JTable) AWT, Swing, JavaFX & SWT 3
C Aktion auführen nach Doppelklick auf Zeile in JTable AWT, Swing, JavaFX & SWT 10
S JTable + Zeile Selektieren AWT, Swing, JavaFX & SWT 5
V JTable: Bei Klick in Zelle -> Ganze Zeile markeiren AWT, Swing, JavaFX & SWT 7
R Gewählte Zeile aus JTable ausgeben lassen AWT, Swing, JavaFX & SWT 17
R JTable: nur eine Zeile auswählen AWT, Swing, JavaFX & SWT 2
J JTable Zeile mit rechtsklick AWT, Swing, JavaFX & SWT 6
T Zeile in JTable mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 8
G Zeile aus JTable in anderem JTable hinzufügen AWT, Swing, JavaFX & SWT 3
C JTable - Zeile fokussieren / selektieren AWT, Swing, JavaFX & SWT 7
J JTable: ganze Zeile selektieren AWT, Swing, JavaFX & SWT 5
S Neue Zeile in JTable adden AWT, Swing, JavaFX & SWT 3
G JTable! Beim anklicken einer Zeile soll sich Farbe ändern! AWT, Swing, JavaFX & SWT 2
I Swing JTable zeichnet kein vertical Grid AWT, Swing, JavaFX & SWT 6
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
F Swing JTable - MultiHeader inkl. Eingabemöglichkeit AWT, Swing, JavaFX & SWT 1
S JTable - Feldinhalte anzeigen AWT, Swing, JavaFX & SWT 15
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G jTable - getSelectedRow() AWT, Swing, JavaFX & SWT 3
I JTable mit einem Button zu einer Detail Seite springen AWT, Swing, JavaFX & SWT 4
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
P Checkboxes in JTable nicht editable AWT, Swing, JavaFX & SWT 9
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Kohl Jedes Objekt einer JTable um ein Zeichen verkürzen AWT, Swing, JavaFX & SWT 7
I JTable, DefaultTableModel, zwei Zahlen multiplizieren. AWT, Swing, JavaFX & SWT 26
M JTABLE / wie oft wurde gewürfelt. AWT, Swing, JavaFX & SWT 1
F JTable vergrößern AWT, Swing, JavaFX & SWT 2
H JTable: Diverse NullPointer-Exceptions zur Laufzeit AWT, Swing, JavaFX & SWT 3
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
B JTable Zellen zusammenfügen AWT, Swing, JavaFX & SWT 3
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
H JTable im JSplitPane darstellen AWT, Swing, JavaFX & SWT 2
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
D Zeilenumbruch in einer JTable AWT, Swing, JavaFX & SWT 9

Ähnliche Java Themen


Oben