Swing Gemeinsame JTable-Implementierung

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
Hallo Community,

Hintergrund dieses Threads:

Ich hab jetzt eine Idee: Ich fange das Programm neu an, from scratch, und ich würde dann immer posten, wenn ich etwas bestimmtes getan habe (natürlich nur was den Table und die Daten betrifft, nicht jeden Schmarrn!!), damit wir das gemeinsam "absegnen" können.
Würdet ihr euch da bereit erklären für?
Weil ich glaube mein Programm ist jetzt schon soviel Choas... ;( Ich möchte halt auch einfach eine tolle GUI machen, hab ne tolle Vorstellung aber das erfordert eben lauter Custom Renderers und blabla, und das hab ich wohl scheinbar nicht so drauf..

Also ich würde jetzt neu beginnen, und wenn ich zB das TableModel implementiert habe, würde ich es hier gleich posten und fragen, ob das so okay ist. Wenn ich dann zB die Sortierung implementiert habe, würd ich das auch posten, und wenn ich einen speziellen Renderer geschrieben habe, auch.

So kommt ihr halt auch mit, es ist völlig klar dass es höllisch schwer für euch ist zu helfen wenn ich schon 4000 Zeilen Code habe und überall lauter Fehler..

Ich mache dafür jetzt einen neuen Thread auf, ihr findet ihn unter "AWT, Swing & SWT" mit dem Titel "Gemeinsame JTable-Implementierung".

Hoffe das ist okay, ansonsten löschen. Aber ich glaube nur auf diese Art und Weise krieg ich etwas vernünftiges zusammen, meine Ansprüche an das Programm sprengen halt leider auch das, was es in der FAQ zum Thema Table zu lesen gibt...

Merci euch, see you im anderen Thread hoffentlich ;)

Der hier enstehende Thread kann also idealerweise am Ende als Tutorial für einen komplexen und stark customizeden JTable mit eigener Sortier- & Filterfunktion in die FAQ übernommen werden!

Also dann..ich mach mich mal an die Arbeit und ihr hört bald von mir. An dieser Stelle nochmals einen Dank an alle die mir dabei helfen :meld:
 
Zuletzt bearbeitet:

hdi

Top Contributor
Sooo, also ich hab jetzt wieder einiges gemacht, und soweit wie ich denke auch richtig.

TableModel:

Java:
public class MyTableModel extends AbstractTableModel {

	// utility constants for easier use and understanding of the column indices
	public static final int TITLE = 0;
	public static final int YEAR = 1;
	public static final int GENRE = 2;
	public static final int FORMAT = 3;
	public static final int DURATION = 4;
	public static final int FSK = 5;
	public static final int RATING = 6;

	// our raw data
	private List<Movie> movies;

	public MyTableModel() {
		// initialize data
		movies = new DBReader().readMovies();
	}

	@Override
	public int getColumnCount() {
		return 7;
	}

	@Override
	public int getRowCount() {
		return movies.size();
	}

	@Override
	public Class<?> getColumnClass(int column) {
		switch (column) {
		case TITLE:
			return String.class;
		case YEAR:
			return Integer.class;
		case GENRE:
			return String.class;
		case FORMAT:
			return String.class;
		case DURATION:
			return Integer.class;
		case FSK:
			return Integer.class;
		case RATING:
			return Double.class;
		default:
			// this should never happen
			return null;
		}
	}

	@Override
	public String getColumnName(int column) {
		switch (column) {
		case TITLE:
			return "Titel";
		case YEAR:
			return "Jahr";
		case GENRE:
			return "Genre";
		case FORMAT:
			return "Format";
		case DURATION:
			return "Dauer";
		case FSK:
			return "FSK";
		case RATING:
			return "Rating";
		default:
			// this should never happen
			return null;
		}
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Movie m = movies.get(rowIndex);
		switch (columnIndex) {
		case TITLE:
			return m.getTitleGerman();
		case YEAR:
			return m.getYear();
		case GENRE:
			return m.getGenre();
		case FORMAT:
			return m.getFormat();
		case DURATION:
			return m.getDuration();
		case FSK:
			return m.getFsk();
		case RATING:
			return m.getRating();
		default:
			// this should never happen
			return null;
		}
	}

	/**
	 * 
	 * @param listIndex
	 *            the index of the movie to delete within the data list, NOT the
	 *            selection index of the table!
	 */
	public void removeRow(int listIndex) {
		movies.remove(listIndex);
		fireTableDataChanged();
	}

	public void addMovie(Movie newMovie) {
		movies.add(newMovie);
		fireTableDataChanged();
	}

}

meine Klasse für den Renderer des Table Headers:
Java:
public class MyHeaderRenderer extends JPanel implements TableCellRenderer {

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		return this;
	}

	private JLabel label;

	public MyHeaderRenderer(String title) {
		label = new JLabel(title);
		label.setFont(new Font("Arial", Font.BOLD, 11));

		// set background color
		Color bg = new Color(210, 210, 210);
		label.setOpaque(true);
		label.setBackground(bg);
		this.setBackground(bg);

		add(label);

	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		// draw outline
		g.setColor(Color.black);
		g.drawRect(-1, -1, getWidth(), getHeight());
	}
}

auch noch ein kleiner Cell-Renderer für (fast) alle Spalten:
Java:
public class MyTextCellRenderer extends JLabel implements TableCellRenderer {

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		this.setText(value == null ? "-" : value.toString());
		this.setBackground(isSelected ? selectedClr : notSelectedClr);
		return this;
	}

	private Color selectedClr;
	private Color notSelectedClr;

	public MyTextCellRenderer(int alignment) {
		selectedClr = new Color(200, 200, 255);
		notSelectedClr = Color.WHITE;
		
		// various settings
		this.setFont(new Font("Arial",Font.BOLD,11));
		this.setOpaque(true);
		this.setHorizontalAlignment(alignment);
	}

}

als letztes ein weiterer Renderer für eine ganz spezielle Spalte:
Java:
public class RatingCellRenderer extends JPanel implements TableCellRenderer {

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		this.isSelected = isSelected;
		rating = (Integer) value;
		return this;
	}

	private Font digitFont;
	private boolean isSelected;
	private Color selectedClr;
	private Integer rating;

	public RatingCellRenderer() {
		selectedClr = new Color(200, 200, 255);
		digitFont = new Font("Arial", Font.BOLD, 11);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		// fill
		if (rating != null) {
			for (int i = 0; i <= rating; i++) {
				g.setColor(RatingColor.getColor(i));
				g.fillRect(i, 0, 1, 20);
			}
		}
		// fill empty space with cell background selection color
		if (isSelected) {
			g.setColor(selectedClr);
			int start = (rating == null ? 0 : rating + 1);
			for (int i = start; i <= 100; i++) {
				g.fillRect(i, 0, 1, 20);
			}
		}

		// if there is no rating, draw "-", otherwise draw the rating digit
		String digit = (rating == null ? "-" : rating + "");

		// draw rating string
		Point center = StringStuff.centerPoint(digit, g.getFontMetrics(),
				getWidth(), getHeight());
		g.setFont(digitFont);
		g.setColor(Color.BLACK);
		g.drawString(digit, center.x, center.y);
	}
}

... und zusammengebastelt wird das ganze nun in meinem JTable:
Java:
public class MyTable extends JTable {

	public MyTable() {
		// set model
		setModel(new MyTableModel());

		// install column header
		for (int i = 0; i < getColumnCount(); i++) {
			TableColumn col = getColumnModel().getColumn(i);
			String title;
			switch (i) {
			case MyTableModel.TITLE:
				title = "Titel";
				break;
			case MyTableModel.YEAR:
				title = "Jahr";
				break;
			case MyTableModel.GENRE:
				title = "Genre";
				break;
			case MyTableModel.FORMAT:
				title = "Format";
				break;
			case MyTableModel.DURATION:
				title = "Dauer";
				break;
			case MyTableModel.FSK:
				title = "FSK";
				break;
			case MyTableModel.RATING:
				title = "Rating";
				break;
			default:
				// this should never happen
				title = null;
			}
			col.setHeaderRenderer(new MyHeaderRenderer(title));
		}

		// our columns (except for the rating column) get a renderer where
		// null-values are shown as "-"
		for (int i = 0; i < getColumnCount(); i++) {
			TableColumn col = getColumnModel().getColumn(i);
			if (i != MyTableModel.RATING) {
				if (i == MyTableModel.TITLE) {
					col.setCellRenderer(new MyTextCellRenderer(
							SwingConstants.LEFT));
				} else {
					col.setCellRenderer(new MyTextCellRenderer(
							SwingConstants.CENTER));
				}
			}
		}

		// the rating column retrieves yet another special renderer
		TableColumn ratingCol = getColumnModel().getColumn(MyTableModel.RATING);
		ratingCol.setCellRenderer(new RatingCellRenderer());

		// out columns may not be resized (makes drawing the rating bar nearly
		// impossible), so we assign fix values
		this.setAutoResizeMode(AUTO_RESIZE_OFF);
		for (int i = 0; i < getColumnCount(); i++) {
			TableColumn col = getColumnModel().getColumn(i);
			int width;
			switch (i) {
			case MyTableModel.TITLE:
				width = 300;
				break;
			case MyTableModel.YEAR:
				width = 70;
				break;
			case MyTableModel.GENRE:
				width = 100;
				break;
			case MyTableModel.FORMAT:
				width = 80;
				break;
			case MyTableModel.DURATION:
				width = 70;
				break;
			case MyTableModel.FSK:
				width = 70;
				break;
			case MyTableModel.RATING:
				width = 100;
				break;
			default:
				// this should never happen
				width = 0;
			}
			col.setResizable(false);
			col.setPreferredWidth(width);
		}

		// set sorter
		setAutoCreateRowSorter(true);

		// various settings
		setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		setFillsViewportHeight(true);
	}
}

Soweit passt sich im Moment auch alles. Ich habe nen Delete Button und einen, der einen neuen Film hinzufügt, und der Table updatet sich immer schön brav, keine Exceptions. Ich denke mal das is richtig:

Action des Delete-Buttons:
Java:
	@Override
	public void actionPerformed(ActionEvent e) {
		// get selected row in table
		int rowIndex = table.getSelectedRow();
		if (rowIndex == -1) {
			return;
		}

		// map to data list index
		int realIndex = table.convertRowIndexToModel(rowIndex);
		// fire deletion request
		MyTableModel model = (MyTableModel) table.getModel();
		model.removeRow(realIndex);
	}

Action des Hinzufügen-Buttons:
Java:
	@Override
		public void actionPerformed(ActionEvent e) {
			// add movie
			MyTableModel model = (MyTableModel) table.getModel();
			Movie m = RandomMovie.getRandom(); // zu Testzwecken erstmal 
			model.addMovie(m);
			
			// TODO select it
			// TODO snap scrollbar so that it is visible
		}

Jetzt fang ich aber mit meinen weiteren Vorstellungen an etwas zu schwanken, darum gehen wir das jetzt bitte gemeinsam an.

1) Wie man in der Action des Hinzufüge-Buttons sieht, möchte ich gerne den neuen Eintrag selektieren, und dann die ScrollBar anpassen, so dass er auf jeden Fall angezeigt wird. Letzteres wurde schon in einem anderen Thread gepostet, aber ich weiss nicht so recht wie ich programmatisch (und KORREKT!) eine Zeile markieren kann? Ich weiss noch nicht mal, wie ich herausfinde in welcher Zeile jetzt das neue Objekt steht.

2) In meinem Programm wird es ein Panel geben, dass erweiterte Infos über einen selektierten Film anzeigt. Ich frage mich wie ich am besten beim Table lauschen kann? ListSelectionListener ändert seinen Wert ja glaube ich echt nur, wenn man selber auf eine Zeile klickt. Also ich suche einen Listener, wie ich darüber vom Table automatisch informiert werde, wenn sich die Selektion geändert hat, und zwar egal ob durch Klick oder durch ein anderes internes Table-Event.

...das reicht erstmal, sonst wird's wieder zu viel Chaos!

Also ich würd mich freuen über Antworten auf meine Fragen, und bitte kuckt euch den Code mal komplett durch, ich will nicht wieder "auf Sand bauen". Wenn da was nicht passt, bitte melden!
 

hdi

Top Contributor
Danke, habe den Header jetzt richtig gemach soweit ich denke:

Java:
public class MyHeaderRenderer extends JPanel implements TableCellRenderer {

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {

		label.setText(value.toString());
		return this;
	}

	private JLabel label;

	public MyHeaderRenderer() {
		label = new JLabel();
		label.setFont(new Font("Arial", Font.BOLD, 11));

		// set background color
		Color bg = new Color(210, 210, 210);
		label.setOpaque(true);
		label.setBackground(bg);
		this.setBackground(bg);

		add(label);

		// set default table header border
		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
	}
}

und in meiner JTable-Klasse jetzt nur noch:
Java:
getTableHeader().setDefaultRenderer(new MyHeaderRenderer());

zu 2): Komisch ich dachte ich hatte das mal versucht und er hat da nicht immer ein Event gefeuert. Vllt war da was anderes falsch, aber du hast recht der ListSelectionListener merkt das.

... zu 1): Aber ich weiss noch immer nicht, wie ich
a) herausfinde in welcher Zeile im Table jetzt mein neues Objekt ist. Es ist ja nicht zwingend die letzte Zeile, denn wenn sortiert ist wird das neue Element automatisch richtig einsortiert
b) wie ich dann tatsächlich diese Zeile markiere.

...zumindest wie ich das sehe, hast du "nur" gepostet, wie ich die ScrollPane dann dazu bringe, dorthin zu springen.
 

ModellbahnerTT

Bekanntes Mitglied
... zu 1): Aber ich weiss noch immer nicht, wie ich
a) herausfinde in welcher Zeile im Table jetzt mein neues Objekt ist. Es ist ja nicht zwingend die letzte Zeile, denn wenn sortiert ist wird das neue Element automatisch richtig einsortiert
b) wie ich dann tatsächlich diese Zeile markiere.

...zumindest wie ich das sehe, hast du "nur" gepostet, wie ich die ScrollPane dann dazu bringe, dorthin zu springen.
Stimmt, ich bin allerdings auch davon ausgagangen, dass wenn du die convertRowIndexToModel-Methode aus deinem andern thread kennst du auch die entsprechende Umkehrfunktion convertRowIndexToView kennst
Und wenn du auch schon den ListSelectionListener kennst, kennst du sicher auch das ListSelectionModel in dem du die selection änderst.

PS: das Panel im Renderer kannst du dir schenken, aber ist auch eigentlich egal
 

hdi

Top Contributor
Naja wie man sieht gibt es hier leider nicht nur die richtige Art es zu machen, deshalb frage ich lieber. Ich hab's jetzt versucht, aber ich verstehe wohl noch etwas falsch:

Java:
// add movie
		Movie newMovie = new Movie();
		newMovie.setTitleGerman(movieTitle.getText());
		MyTableModel model = (MyTableModel) MyTable.getInstance().getModel();
		model.addMovie(newMovie);

		// select it
		int modelIndex = model.getMovies().indexOf(newMovie);
		int viewIndex = MyTable.getInstance().convertRowIndexToView(modelIndex);
		MyTable.getInstance().getSelectionModel().setLeadSelectionIndex(viewIndex);
		
		//  snap scroll bar so that it is visible
		Rectangle cellRect = MyTable.getInstance().getCellRect(viewIndex, 0, false);
		MyTable.getInstance().scrollRectToVisible(cellRect);

Die Indices stimmen schon, aber es wird nix markiert, der ListSelectionListener wird auch nicht aufgerufen. Ich schätze es liegt an der setLeadSeletionIndex() Methode?! Ist das die falsche?

PS: Es tut mir leid ich hab daraus wieder ein Singleton mit öffentlichem Getter gemacht weil ich sonst in tausend Klassen meine JTable durchreichen müsste, das wird ja fast überall benötigt... Also vllt ist das kein gutes Design aber ich weiss nicht wie ich es sonst schön machen soll ohne dass am Ende jede meiner Klassen eine JTable im Konstruktor haben will....
 

hdi

Top Contributor
Habe es nun hinbekommen:

Java:
	int modelIndex = model.getMovies().indexOf(newMovie);
		int viewIndex = MyTable.getInstance().convertRowIndexToView(modelIndex);
		MyTable.getInstance().getSelectionModel().setSelectionInterval(viewIndex, viewIndex);
 

hdi

Top Contributor
Ich stehe jetzt wieder vor einem Problem: Ich habe ja meinen TableHeader installiert (siehe einige Posts weiter oben). Das ist ja eine Klasse:
Java:
extends JPanel implements TableCellRenderer

...daher kann ich auch einen MouseListener adden. Leider wird der aber irgendwie nie benachrichtigt, wenn ich auf den Header klicke zB. Das Problem ist wohl, dass da automatisch ein MouseListener installiert ist, und meiner sozusagen überschrieben wird oder nicht zum Zug kommt :bahnhof:
Also dass ein MouseListener dran ist, muss ja eigentlich so sein weil wenn ich auf dem Header rumklicke wird ja mein Table sortiert.

Ich möchte halt gerne ein kleines Icon in den Header-Spalten jeweils einblenden lassen wenn man drüber geht mit der Maus. Wie kann ich das jetzt machen?

und ich habe noch eine weitere Frage: Man kann ja per default die Spalten vertauschen wenn man sie im Header rumzieht. Wenn man das getan hat, möchte ich gerne ein Event feuern (der Table soll sich neu sortieren, denn später will ich noch eine multiple Sortierung einbauen, wobei die Prioritäten sich daraus ermitteln, in welcher Reihenfolge die Spalten im Moment im Table angebracht sind).

Würd mich über Hilfe freuen, hab jetzt schon einiges probiert aber bislang erfolglos.
Danke!
 

hdi

Top Contributor
Hallo,
ich melde mich wieder weil noch keiner etwas dazu gesagt hat.

Also nochmal kurz, ich würde gerne folgendes realisieren:
1) Einen funktionierenden MouseListener auf meinem TableHeader installieren bzw. den default-Listener irgendwie herholen und modifizieren

2) (...und ich denke dafür ist 1) eine Voraussetzung) möchte ich darauf reagieren wenn man eine Spalte verschoben hat, um

3) dann eine eigene Sortierung vorzunehmen: Dabei soll immer nach allen Spalten sortiert werden, wobei die linkeste Spalte höchste Priorität hat, die rechteste niedrigste.

Also ich hab jetzt schon viel rumversucht und gegooglet, aber mein Problem ist gerade dass ich halt irgendwie den MouseListener brauch, der standardmässig für diese Dinge wie Sortierung bei Klick oder Verschieben von Spalten zuständig ist.

Kann mir da keiner helfen :bahnhof:

Hier nochmal der Code meines TableHeaders, der per

Java:
table.	getTableHeader().setDefaultRenderer(new MyHeaderRenderer());

auf meinem Table installiert wird:

Java:
public class MyHeaderRenderer extends JPanel implements TableCellRenderer{

	@Override
	public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {
		// set column label
		label.setText(value.toString());
		
		return this;
	}

	private JLabel label;

	public MyHeaderRenderer() {
		label = new JLabel();
		label.setFont(new Font("Arial", Font.BOLD, 11));

		// set background color
		Color bg = new Color(210, 210, 210);
		label.setOpaque(true);
		label.setBackground(bg);
		this.setBackground(bg);

		add(label);

		// set default table header border
		setBorder(UIManager.getBorder("TableHeader.cellBorder"));

	}
}
 

DStrohma

Bekanntes Mitglied
ihr scheint euch ja mit JTable gut auszukennen...
seit doch bitte so nett und seht euch mal diesen thread an: Link (auch hier im forum)

ich komm da nicht weiter und hab die befürchtung dass sich keiner dafür interessiert :(
 

hdi

Top Contributor
So, ich hab jetzt zumindest etwas zum laufen gebracht, zweifel aber irgendwie stark daran dass das so besondern gut gelöst ist. Wär nett wenn ihr mir einfach sagt was ihr davon haltet, oder ob es anders (besser) geht.

Und zwar adde ich einen MouseListener zu meinem TableHeader. (table.getDefaultHeader()).

Und wenn ich jetzt mit der Maus was am Header mache, bekommt der auch was mit.
Jetzt möchte ich ja zwei Dinge haben

1) Icons in den Spalten-Header anzeigen beim mouseOver
2) Nach dem Verschieben von Spalten neu sortieren

Hier mal mein Ansatz:

Java:
	@Override
	public void mouseEntered(MouseEvent e) {
		JTableHeader header = MyTable.getInstance().getTableHeader();
		TableCellRenderer renderer = header.getDefaultRenderer();
		Component c = renderer.getTableCellRendererComponent(MyTable.getInstance(), "", false, true, 0, 1);
		c.setBackground(Color.red);
		header.repaint();
	}

Also es tut sich was, aber der Grund warum ich denke das ist eher nich so bombastisch gelöst: Ich frag mich jetzt schon wie ich hier im MouseListener ermitteln soll, über welche Spalte man gerade mit der Maus gegangen ist.
Also dieser Listener ist halt total abgekoppelt von allen internen JTable-Dingen.

Deshalb denke ich komme ich da nicht so weit.

Mensch.. Weiss den wirklich keiner wie ich sowas machen kann? :(
 

Marco13

Top Contributor
Eigentlich klingt das mit der automatischen Spaltenweisen Sortierung ja ganz interessant ... da müßte man sich mal ein KSKB basteln. Ich schreib' mir mal einen Merkzettel, dass ich mir das (wenn ich dazu komme) im Lauf der Woche nochmal ansehe....
 

DStrohma

Bekanntes Mitglied
Ich frag mich jetzt schon wie ich hier im MouseListener ermitteln soll, über welche Spalte man gerade mit der Maus gegangen ist.
Also dieser Listener ist halt total abgekoppelt von allen internen JTable-Dingen.

vielleicht so in der art:

Java:
				// get the coordinates of the mouse click
				Point p = e.getPoint();
				// get the row index that contains that coordinate
				int rowNumber = table.rowAtPoint(p);
				// Get the ListSelectionModel of the JTable
				ListSelectionModel model = table.getSelectionModel();
				// set the selected interval of rows. Using the "rowNumber"
				// variable for the beginning and end selects only that one row.
				model.setSelectionInterval(rowNumber, rowNumber);

sollte wenn du es änderst auch für den header gehen
 
Zuletzt bearbeitet:

hdi

Top Contributor
@dstrohma: werd's mal anschauen, aber ich kuck noch weiter ob es dafür vllt noch einen richtigeren Ansatz gibt.

@Marco: Das wär echt super ;)
 

Marco13

Top Contributor
Also das mit dem automatischen sortieren mit absteigender Priorität von links nach rechts ist gar nicht so aufwändig ... ist zwar nur schnell hingeschrieben, aber vom Prinzip her tut's da wohl schon sowas
Code:
        final MyTableModel model = new MyTableModel();
        final JTable table = new JTable(model);

        table.getColumnModel().addColumnModelListener(new TableColumnModelListener()
        {
            public void columnMoved(TableColumnModelEvent e)
            {
                //System.out.println("columnMoved event "+e);
                //System.out.println("From "+e.getFromIndex());
                //System.out.println("to   "+e.getToIndex());

                int from = e.getFromIndex();
                int to = e.getToIndex();
                if (from != to)
                {
                    System.out.println("Adjusting sorter");
                    TableRowSorter<MyTableModel> sorter = new TableRowSorter<MyTableModel>(model);
                    List <RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
                    for (int i=0; i<table.getColumnCount(); i++)
                    {
                        int modelColumnIndex = table.convertColumnIndexToModel(i);
                        sortKeys.add(new RowSorter.SortKey(modelColumnIndex, SortOrder.ASCENDING));
                    }
                    sorter.setSortKeys(sortKeys); 
                    table.setRowSorter(sorter);
                }
            }
            
            public void columnAdded(TableColumnModelEvent e)
            {
            }
            public void columnMarginChanged(ChangeEvent e)
            {
            }
            public void columnRemoved(TableColumnModelEvent e)
            {
            }
            public void columnSelectionChanged(ListSelectionEvent e)
            {
            }
        });
(hatte das jetzt mangels KSKB in die http://java.sun.com/docs/books/tuto...DemoProject/src/components/TableSortDemo.java eingefügt)
 

hdi

Top Contributor
Ah schau dieses Interface ist mir noch gar nicht so richtig aufgefallen xD
Vielen Dank!

Aber wie kann ich herausfinden, wie der Table im Moment sortiert ist?
Sprich dein Bsp sortiert ja einfach immer alle absteigend, aber die momentan gesetzte Sortierung möchte ich schon beibehalten, nur die Priorität soll sich ändern.

Wenn ich mir mit dem Getter den RowSorter hole, dann hat der gar keine SortKeys drinnen Oo. Wo ist das denn gespeichert, diese Info?

.. die bräuchte ich nämlich auch noch für meinen Column-Renderer, weil der zeigt im Moment noch nicht diese Pfeile der Sortier-Richtung an. Um die selbst einzuzeichnen muss ich ja auch wissen wie die Spalte gerade sortiert ist.

Merci beaucoup :)

edit Moment erstmal Rückzug, ich sehe grad er zeigt mir doch nen SortKey an, aber nur wenn ich eben vorher diese Spalte angeklickt hab um sie zu sortieren. D.h. ich müsste das erstmal per Hand am anfangen initialisieren, mal sehen ich versuch erstmal weiter ;)
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Ja, er sortiert erst nach der ersten Verschiebung, das würde man in der "echten" Anwendung ggf. anders machen - am günstigsten wohl, indem man den Teil in der "if (from != to)" abfrage in eine private Methode "updateSorting()" oder so packt, und die dann entsprechend an dieser Stelle UND einmal ganz am Anfang aufruft.
 

hdi

Top Contributor
So, also das mit der Sortierung funktioniert leider noch nicht so ganz.
Jetzt mal komplett abgesehen von der Sortierung beim Verschieben, sondern ich rede hier einfach nur von der Sortierung durch Klick auf die Spalte, wenn setAutoCreateRowsorter(true) gesetzt wurde:

Das verändert nämlich die SortKeys auf eine Art und Weise die ich nicht nachvollziehen kann.
Ich habe nun beim Initialisieren meines JTables erstmal eine absteigende Sortierung für alle Spalten eingestellt:

Java:
	// install sorter & initialize default sort orders
		setAutoCreateRowSorter(true);
		List<SortKey> sortKeys = new ArrayList<SortKey>();
		for (int i = 0; i < getColumnCount(); i++) {
			sortKeys.add(new SortKey(i, SortOrder.ASCENDING));
		}
		getRowSorter().setSortKeys(sortKeys);

In meinem column header habe ich ein sysout drinnen, das mir immer alle SortKeys ausspuckt. Anfangs sieht man, dass das also auch wirklich so eingestellt ist, alle absteigend.
Wenn ich jetzt aber auf eine Spalte klicke, dann schmeisst er mir einige SortKeys einfach raus.

Anfangs:
0:ASCENDING
1:ASCENDING
2:ASCENDING
3:ASCENDING
4:ASCENDING
5:ASCENDING

Beim Klick auf die erste Spalte, also die mit Index = 0:
0:DESCENDING
1:ASCENDING
2:ASCENDING

Er hat also die SordOrder der ersten Spalte geändert, das ist gut. Und von Spalte 2 und 3 hat er die alten beibehalten. Aber nanu, wo sind die anderen Spalten hin??
..dadurch bekomme ich sehr schnell IndexOutOfBounds Exceptions, wenn ich im HeaderRenderer den SortKey für eine Spalte abfrage. Ganz einfach, weil es keinen gibt!
Wieso haut er die mir raus??
 

hdi

Top Contributor
So, also ich bin wieder ein Stückchen weiter.
Ich hab jetzt des Geistesblitz erhalten, wie ich den ursprünglichen Listener auf dem Header anpassen kann: Einfach einen eigenen Listener, den Default-Listener mitgeben, danach vom Table löschen! Und mein eigener ruft nur ein paar Methoden des alten auf, zB das die Funktionalität zum Verschieben noch geht.
Aber zB das Sortieren beim Klick ist nun abgeschaltet,darum kümmere ichmich komplett selber.

Allerdings gibt es hier jetzt ein Problem, ich krieg Exceptions beim wenn ich die SortKeys ändern will. Sogar, wenn ich sie nicht ändere. WAs ich meine:


Java:
		List<SortKey> oldKeys = (List<SortKey>) MyTable.getInstance()
				.getRowSorter().getSortKeys();
		
		RowSorter<MyTableModel> newSorter = new TableRowSorter<MyTableModel>();
		newSorter.setSortKeys(oldKeys);
		MyTable.getInstance().setRowSorter(newSorter);

Ich mache hier also rein logisch nichts. Ich nehm den alten Sorter per Getter, und setze ihn gleich wieder per Setter. Die Einträge sind ok, d.h. wenn ich mir alle Elemente von "oldKeys" ausgeben lasse, ist das für jede Spalte ein Key, so wie ich das auch erwarte.

Aber beim Aufruf des Setters bekomme ich plötzlich die Exception:

Java:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Invalid SortKey
	at javax.swing.DefaultRowSorter.setSortKeys(Unknown Source)

Wie kann der invalid sein? Ist doch ein gültiger SortKey... Also irgendwas versteh ich wohl falsch.

...bitte helft mir nochmal, ich bin jetzt so kurz davor dieses Sortierungs-Zeugs fertig zu haben.. Thx
 

hdi

Top Contributor
So Leute, auch wenn ich das Gefühl hab ich führ hier einen Monolog (man kann's ja nicht verübeln :oops:), will ich mal die Interessierten up to date halten:

Ich bin nun etwas weiter, stehe aber seit ca. 6 Stunden vor einem Problem, das ich bisher mit Debugging und API lesen nicht lösen konnte.

Ich hab euch ein KSKB gebaut, bitte in der IDE ausführen weil die Sysouts interessant sind. Ich bitte euch da mal rumzuspielen, es stimmt etwas beim Verschieben der Spalten noch nicht.

Für die die nicht wissen worum's geht: Der Table in dem KSKB sollte immer eine Sortierung haben, bei der ALLE Spalten berücksichtigt werden. Dabei ist die Priorität gegeben durch die Reihenfolge der Spalten, wie man sie im Table sieht (von links = höchste nach rechts = niedrigste Prioität).

Wie gesagt... nach ein wenig rumverschieben passt irgendwie nix mehr. zB nach 1x eine Spalte um eins Verschieben und dann auf die Spalte klicken -> seht euch mal das Sysout an, da ist was doppelt und eine Spalte verschwindet usw.

...ich kann dazu jetzt nicht mehr sagen, mein Hirn hat nen riesigen Knoten.. ich versteh nix mehr. Hoffe auf eure klaren Köpfe :toll:

Java:
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.ToolTipManager;
import javax.swing.RowSorter.SortKey;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;

public class SortProblem extends JFrame {

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				new SortProblem().setVisible(true);
			}
		});
	}

	private JTable table;

	public SortProblem() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		table = new JTable(getRowData(), getColumnNames());
		table.setAutoCreateRowSorter(true);

		/*
		 * Alle Spalten werden bei der Sortierung berücksichtigt, anfangs ist
		 * die Priorität von links nach rechts, entsprechend der Anordnung der
		 * Spalten in der Tabelle am Anfang.
		 */
		List<SortKey> sortKeys = new ArrayList<SortKey>();
		for (int i = 0; i < table.getColumnCount(); i++) {
			sortKeys.add(new SortKey(i, SortOrder.ASCENDING));
		}
		table.getRowSorter().setSortKeys(sortKeys);
		// Test:
		printSortKeys();

		/* Wir entfernen erstmal den Tool Tip Listener vom Header: */
		ToolTipManager.sharedInstance().unregisterComponent(
				table.getTableHeader());

		/*
		 * Damit bleibt nur noch der default-mässige MouseListener bzw
		 * MouseMotionListener übrig. Den entfernen wir auch, speichern ihn uns
		 * aber weil wir ihn noch benutzen in unserem eigenen Listener, den wir
		 * dann als neuen Listener zum Header adden:
		 */
		MouseListener original = table.getTableHeader().getMouseListeners()[0];
		table.getTableHeader().removeMouseListener(original);
		MyHeaderListener headerListener = new MyHeaderListener(original);
		table.getTableHeader().addMouseListener(headerListener);
		table.getTableHeader().addMouseMotionListener(headerListener);

		/*
		 * Weil beim Verschieben der Spalten die Sortierung angepasst werden
		 * soll, adden wir einen ColumnModelListener, um darauf zu reagieren:
		 */
		table.getColumnModel().addColumnModelListener(
				new MyColumnModelListener());

		add(new JScrollPane(table));
		pack();
	}

	private static Object[] getColumnNames() {
		return new Object[] { "Name", "Alter", "Punkte" };
	}

	private static Object[][] getRowData() {
		Object[] row1 = new Object[] { "Arnold", 20, 82 };
		Object[] row2 = new Object[] { "Bernd", 20, 70 };
		Object[] row3 = new Object[] { "Chris", 15, 47 };
		Object[] row4 = new Object[] { "Doris", 16, 47 };
		Object[] row5 = new Object[] { "Xandir", 40, 70 };
		return new Object[][] { row1, row2, row3, row4, row5 };
	}

	/**
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * 
	 * Unser MouseListener auf dem Table Header.
	 * 
	 */
	public class MyHeaderListener extends MouseAdapter implements
			MouseMotionListener {

		private MouseListener original;
		private MouseMotionListener originalMotion;

		public MyHeaderListener(MouseListener m) {
			original = m;
			originalMotion = (MouseMotionListener) m;
		}

		@Override
		public void mouseMoved(MouseEvent e) {
			originalMotion.mouseMoved(e);
		}

		@Override
		public void mouseDragged(MouseEvent e) {
			originalMotion.mouseDragged(e);
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			original.mouseEntered(e);
		}

		@Override
		public void mouseExited(MouseEvent e) {
			original.mouseExited(e);
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			original.mouseReleased(e);
		}

		@Override
		public void mousePressed(MouseEvent e) {
			original.mousePressed(e);
		}

		@Override
		public void mouseClicked(MouseEvent e) {
			// retrieve clicked column.
			int col = table.columnAtPoint(e.getPoint());

			// build new SortKey list
			RowSorter<?> sorter = table.getRowSorter();
			List<? extends SortKey> oldKeys = sorter.getSortKeys();
			List<SortKey> newKeys = new ArrayList<SortKey>();
			for (int c = 0; c < oldKeys.size(); c++) {
				if (c == col) {
					// flip sort order
					SortOrder oldOrder = oldKeys.get(c).getSortOrder();
					SortOrder newOrder = (oldOrder == SortOrder.ASCENDING ? SortOrder.DESCENDING
							: SortOrder.ASCENDING);
					newKeys.add(new SortKey(c, newOrder));
				} else {
					// just copy
					newKeys.add(oldKeys.get(c));
				}
			}

			// set updated SortKey list
			sorter.setSortKeys(newKeys);
			// Debug
			printSortKeys();
		}
	}

	/**
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * ----------------------------------------------------------------
	 * 
	 * der Listener des Column-Models.
	 * 
	 */
	class MyColumnModelListener implements TableColumnModelListener {

		@Override
		public void columnMoved(TableColumnModelEvent e) {

			int from = e.getFromIndex();
			int to = e.getToIndex();
			if (from != to) {

				// from und to sind die VIEW-Indices!
				// Allerdings stimmen die ja von Anfang an überein mit unseren
				// Einträgen in der SortKey-Liste. D.h. wenn diese Funktion das
				// erste mal aufgerufen wird, ist zB die 3.Spalte im User
				// Interface auf repräsentiert durch den 3.Eintrag in unserer
				// SortKey-Liste.
				// Von daher muss man hier ja eig. nix converten?!

				// .. wir vertauschen einfach die Einträge der Spalten in der
				// SortKey-Liste.
				RowSorter<?> sorter = table.getRowSorter();
				List<? extends SortKey> oldKeys = sorter.getSortKeys();
				List<SortKey> newKeys = new ArrayList<SortKey>();
				for (int c = 0; c < oldKeys.size(); c++) {
					if (c == from) {
						newKeys.add(oldKeys.get(to));
					} else if (c == to) {
						newKeys.add(oldKeys.get(from));
					} else {
						// just copy
						newKeys.add(oldKeys.get(c));
					}
				}
				sorter.setSortKeys(newKeys);

				// Debug
				printSortKeys();
			}
		}

		@Override
		public void columnRemoved(TableColumnModelEvent e) {
		}

		@Override
		public void columnSelectionChanged(ListSelectionEvent e) {
		}

		@Override
		public void columnAdded(TableColumnModelEvent e) {

		}

		@Override
		public void columnMarginChanged(ChangeEvent e) {
		}

	}

	/**
	 * DEBUG-FUNKTION, druckt die Liste aller beim Aufruf gesetzer SortKeys aus.
	 */

	public void printSortKeys() {
		System.out.println("-------- Sort-Keys: --------");
		for (int i = 0; i < table.getRowSorter().getSortKeys().size(); i++) {
			SortKey k = table.getRowSorter().getSortKeys().get(i);
			int modelCol = k.getColumn(); // Laut API der Model-Index
			int viewCol = table.convertColumnIndexToView(modelCol);
			String name = table.getColumnName(viewCol); // will laut API den
			// View-Index

			System.out.println(name + "\t" + k.getSortOrder());
		}
	}
}
 

Ariol

Top Contributor
Wie gesagt... nach ein wenig rumverschieben passt irgendwie nix mehr. zB nach 1x eine Spalte um eins Verschieben und dann auf die Spalte klicken -> seht euch mal das Sysout an, da ist was doppelt und eine Spalte verschwindet usw.

Das Problem hab ich nicht, allerdings wird bei mir auch IMMER nach Name sortiert, egal in welcher Reihenfolge die Spalten sind
 

hdi

Top Contributor
Start mal, und klick 1x auf die Punkte-Spalte. Soweit wird dann die Ausgabe noch stimmen. Jetzt zieh die Punkte-spalte ganz nach links. Dann ist es nicht nach Name sondern tatsächlich nach Punkten absteigend sortiert, die Ausgabe ist auch korrekt.

Aber dann klick nochmal auf die Punkte-Spalte. Und dann schau dir die Ausgabe an..da kommt 1 Spalte doppelt vor und eine andere ist weg, zumindest vom Namen her. Das ist einer der Fehler...
 

Ariol

Top Contributor
Hab's versucht, aber bei mir kommt beim besten Willen nichts doppelt...
Nur beim 2. Klick wird wieder nach Namen sortiert...

Sortieren klappt nur mit:
1. Spalte nach der sortiert werden soll anklicken
2. Spalte nach vorne ziehen...
 

hdi

Top Contributor
Hah, ich hab's geschafft :hihi:

Wen es interessiert, hier also eine Sorterung nach allen Spalten, mit Prioirisierung links nach rechts (absteigend):

Listener auf dem ColumnModel des Tables:

Java:
public class MyColumnModelListener implements TableColumnModelListener {

	@Override
	public void columnMoved(TableColumnModelEvent e) {

		int from = e.getFromIndex();
		int to = e.getToIndex();
		if (from != to) {

			// convert
			int fromModel = MyTable.getInstance().convertColumnIndexToModel(
					from);
			int toModel = MyTable.getInstance().convertColumnIndexToModel(to);

			// copy old SortKey list, but switch "from" and "to".
			RowSorter<?> sorter = MyTable.getInstance().getRowSorter();
			List<? extends SortKey> oldKeys = sorter.getSortKeys();
			List<SortKey> newKeys = new ArrayList<SortKey>();
			for (int i = 0; i < oldKeys.size(); i++) {
				SortKey k = oldKeys.get(i);
				if (fromModel == k.getColumn()) {
					newKeys.add(getSortKeyWithColumn(toModel));
				} else if (toModel == k.getColumn()) {
					newKeys.add(getSortKeyWithColumn(fromModel));
				} else {
					// just copy
					newKeys.add(oldKeys.get(i));
				}
			}
			sorter.setSortKeys(newKeys);

			// update header renderer
			JTableHeader h = MyTable.getInstance().getTableHeader();
			MyHeaderRenderer.colToPaint = to;
			h.repaint();
		}
	}

	private SortKey getSortKeyWithColumn(int col) {
		for (SortKey k : MyTable.getInstance().getRowSorter().getSortKeys()) {
			if (k.getColumn() == col) {
				return k;
			}
		}
		return null;
	}

	@Override
	public void columnRemoved(TableColumnModelEvent e) {
	}

	@Override
	public void columnSelectionChanged(ListSelectionEvent e) {
	}

	@Override
	public void columnAdded(TableColumnModelEvent e) {

	}

	@Override
	public void columnMarginChanged(ChangeEvent e) {
	}

}

Der MouseListener, durch den der default-mässigen Listener ("original") auf dem TableHeader des JTable ersetzt werden muss (D.h. original löschen und diesen adden):

Java:
public class MyHeaderListener extends MouseAdapter implements
		MouseMotionListener {

	private MouseListener original;
	private MouseMotionListener originalMotion;

	public MyHeaderListener(MouseListener m) {
		original = m;
		originalMotion = (MouseMotionListener) m;
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		originalMotion.mouseMoved(e);
		updateAppearance(e.getPoint());
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		originalMotion.mouseDragged(e);
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		original.mouseEntered(e);
		updateAppearance(e.getPoint());
	}

	@Override
	public void mouseExited(MouseEvent e) {
		original.mouseExited(e);
		// no column should match the x coordinate
		updateAppearance(new Point(-1000, 0));
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		original.mouseReleased(e);
	}

	@Override
	public void mousePressed(MouseEvent e) {
		original.mousePressed(e);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// retrieve clicked column (as model index)
		int col = MyTable.getInstance().convertColumnIndexToModel(
				getColumnByPoint(e.getPoint()));

		// build new SortKey list
		RowSorter<?> sorter = MyTable.getInstance().getRowSorter();
		List<? extends SortKey> oldKeys = sorter.getSortKeys();
		List<SortKey> newKeys = new ArrayList<SortKey>();
		for (int i = 0; i < oldKeys.size(); i++) {
			SortKey k = oldKeys.get(i);
			if (k.getColumn() == col) {
				// flip sort order
				SortOrder oldOrder = k.getSortOrder();
				SortOrder newOrder = (oldOrder == SortOrder.ASCENDING ? SortOrder.DESCENDING
						: SortOrder.ASCENDING);
				newKeys.add(new SortKey(col, newOrder));
			} else {
				// just copy
				newKeys.add(k);
			}
		}

		// set updated SortKey list
		sorter.setSortKeys(newKeys);
	}

	/**
	 * 
	 * @param p
	 * @return the view index!
	 */
	private int getColumnByPoint(Point p) {
		return MyTable.getInstance().columnAtPoint(p);
	}

	private void updateAppearance(Point p) {
		int col = getColumnByPoint(p);
		JTableHeader h = MyTable.getInstance().getTableHeader();
		MyHeaderRenderer.colToPaint = col;
		h.repaint();
	}

}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
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
R Swing JTable und Spaltenausrichtung AWT, Swing, JavaFX & SWT 8
G JTable füllen AWT, Swing, JavaFX & SWT 1
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J Datensatz in jTable ausgeben AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JTable aktualisieren AWT, Swing, JavaFX & SWT 5
adiko01 JTable: Nur markierte Zeilen aus der Tabelle in CSV exportiern AWT, Swing, JavaFX & SWT 9
M JTable.setDefaultRenderer(...) greift nicht AWT, Swing, JavaFX & SWT 0
J JTable: Eingabe in Tabellenzelle korrigieren AWT, Swing, JavaFX & SWT 4
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
D MySQL Daten in JTable anzeigen AWT, Swing, JavaFX & SWT 2
H Swing Jtable extra spalte AWT, Swing, JavaFX & SWT 6
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
S Swing Mal wieder JTable Ansicht aktualisieren AWT, Swing, JavaFX & SWT 10
A JTable mit Daten füllen AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
N AWT jTable CellRenderer AWT, Swing, JavaFX & SWT 6
T Swing JTable valueChanged datensatz löschen AWT, Swing, JavaFX & SWT 1
0 Swing JTable aus anderer Klasse updaten AWT, Swing, JavaFX & SWT 5
S Jtable defaultRenderer wohin damit ? AWT, Swing, JavaFX & SWT 23
T Swing JTable / FocusListener AWT, Swing, JavaFX & SWT 0
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
T Swing Double Click bei Buttons in JTable AWT, Swing, JavaFX & SWT 9
J addRow bei JTable AWT, Swing, JavaFX & SWT 6
M Jtable gibt -1 wert bei selectedRow und Column AWT, Swing, JavaFX & SWT 3
Meeresgott Swing JTable AWT, Swing, JavaFX & SWT 4
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
B Swing JTable sortieren AWT, Swing, JavaFX & SWT 2
T Swing JTable auslesen und befüllen AWT, Swing, JavaFX & SWT 8
B JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
J JTable und Suchlogik AWT, Swing, JavaFX & SWT 4
Viktim Swing JTable mit Tab verlassen AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
Viktim Swing JTable Mit Tab druch Zeilen Wechseln AWT, Swing, JavaFX & SWT 5
Thallius Warum refrehsed mein JTable nicht? AWT, Swing, JavaFX & SWT 5
Ghostman1711 Hinzufügen ausgewählter Dateinen des Filechoosers zu einem JTable AWT, Swing, JavaFX & SWT 9
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
K JTable getValueAt() klappt nicht immer AWT, Swing, JavaFX & SWT 1
K JTable in extra Klasse, Zugriff in einer anderen klasse nicht möglich AWT, Swing, JavaFX & SWT 26
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
P JTable - bei Eingabe Selektion AWT, Swing, JavaFX & SWT 0
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
S Swing Deselektion in JTable verhindern AWT, Swing, JavaFX & SWT 0
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
N Swing Print JTable mit AbstractTableModel AWT, Swing, JavaFX & SWT 1
Ananaskirsche Swing jTable Reihen zuviel eingefügt AWT, Swing, JavaFX & SWT 12
P im JTable die Schriftfarbe ändern AWT, Swing, JavaFX & SWT 19
T Swing JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Dreiecke in bestimmte Zellen einer JTable AWT, Swing, JavaFX & SWT 9
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
D Swing JTable Renderer Grafikfehler AWT, Swing, JavaFX & SWT 0
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1
M Swing JTable GroupableHeader Background Color AWT, Swing, JavaFX & SWT 4
K Swing JTable updaten AWT, Swing, JavaFX & SWT 9
thet1983 Swing MySQL >> JTable AWT, Swing, JavaFX & SWT 5
J JTable bounds ändern durch resizing des Fensters AWT, Swing, JavaFX & SWT 9
F JTable Zellen-Hintergrund ändern AWT, Swing, JavaFX & SWT 7
O JTable linksbündig drucken (nicht der Zelleninhalt) AWT, Swing, JavaFX & SWT 2
Crazynet xls Datei in JTable AWT, Swing, JavaFX & SWT 3
O JTable ohne Rahmen printen AWT, Swing, JavaFX & SWT 3
L Swing JTable refresht die Column Namen nicht AWT, Swing, JavaFX & SWT 0
K JTable komplett durch andere ersetzen AWT, Swing, JavaFX & SWT 4
S JTable übernimmt Änderungen nicht AWT, Swing, JavaFX & SWT 2
Y JTable AWT, Swing, JavaFX & SWT 6
D Swing JCombobox in einem JTable vorbelegen AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben