Swing JTable: SortKeys und Header Column Width

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
edit:
sry ich muss das erstmal genauer einschränken, ich kann das gar nicht richtig erklären...
 
Zuletzt bearbeitet:

hdi

Top Contributor
So also, ich frag jetzt einfach mal ins Blaue hinein, weil ich weiß echt nicht was ich euch an Code zeigen sollte. Mein Problem: Wenn beim Klick auf den Table-Header (auf eine Spalte) die SortKeys geändert werden, passiert es manchmal dass eine Spalte 1px breiter oder schmäler wird..

Das beobachte ich bisher nur, wenn man den Columns eine preferredSize vergeben hat (die nicht bei allen gleich ist). Also hier ne Demo von dem Verhalten:

Java:
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;

public class JTableColumnResizeOnClick extends JFrame {
	public static void main(String[] args) {
		new JTableColumnResizeOnClick().setVisible(true);
	}

	public JTableColumnResizeOnClick() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		MyModel model = new MyModel();
		JTable table = new JTable(model);
		
		/* set table column widths */
		for (int i = 0; i < table.getColumnCount(); i++) {
			TableColumn col = table.getColumnModel().getColumn(i);
			int width = 26 + (int)(Math.random()*50);
			int min = 25;
			col.setPreferredWidth(width);
			col.setMinWidth(min);
		}
		
		table.setRowSorter(new TableRowSorter<MyModel>(model));
		add(new JScrollPane(table));
		pack();
	}

	class MyModel extends AbstractTableModel {

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

		@Override
		public int getRowCount() {
			return 10;
		}
		
		@Override
		public Class<?> getColumnClass(int arg0) {
			return String.class;
		}
		
		@Override
		public String getColumnName(int column) {
			return "col";
		}

		@Override
		public Object getValueAt(int arg0, int arg1) {
			return "Cell";
		}

	}
}

Klickt mal in den Spalten-Headern rum, vertauscht Spalten usw. Es sollte irgendwann auffallen, dass eben manchmal eine Spalte ihre größe leicht ändert. Ich denke es ist echt nur 1px.

Also mein wirkliches Problem ist folgendes: Ich hab ne App mit nem Table, bei dem so ziemlich alles "custom" ist. D.h. eigener Header-Renderer, Header-Listener usw. Auch dort setz ich wie im Code oben die Sizes für meine Spalten. Aber dort passiert es mir nicht, dass sie ihre Größe verändern.

Ich hab eig. schon alles so nachgebaut gehabt wie in der anderen App, und trotzdem hab ich bei meiner neuen App noch immer dieses Problem. Also irgendwas übersehe ich.

Jetzt also einfach mal ne Frage, ob einer von euch weiß woran das liegt, also wer oder was ist zuständig für diese Veränderung der Größe beim Ändern der SortKeys?

Danke ;)
 

André Uhres

Top Contributor
Ich sehe das Phänomen :bae:. Es scheint von den relativen Spaltenbreiten abzuhängen. Dein Testprogramm legt die Spaltenbreiten ja zufällig fest und so kam es bei mir zu einem Fall, wo ich das Programm startete ohne dass danach der Fehler auch nur ein einziges mal auftrat. Darum halte ich das Ganze für einen Rundungsfehler im Autoresize.
 

hdi

Top Contributor
Also ich konnte das Problem jetzt beheben, und zwar hat das was mit der ScrollPane zu tun. (@André: Aber wohl auch was mit den Sizes der Spalten) Ich berechne die Größe der ScrollPane indem ich die preferredSizes der Columns zusammenrechne, und dann auch noch die Breite der ScrollBar (die ich immer anzeige) hinzuaddiere. Hier meine Klasse:

Java:
public class TableScrollPane extends JScrollPane {

	public TableScrollPane(MyTable table) {
		super(table);
		setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		// calculate width from table column widths & width of scroll bar
		int width = 0;
		for (int i = 0; i < table.getColumnCount(); i++) {
			TableColumn col = table.getColumnModel().getColumn(i);
			width += col.getPreferredWidth();
		}
		width += getVerticalScrollBar().getPreferredSize().width;
		width -= 1; // ????????????
		
		// set a height where cells are fully visible, and not cut off
		int cellsToDisplay = 20;
		int headerHeight = table.getTableHeader().getPreferredSize().height;
		int height = headerHeight + (cellsToDisplay * table.getRowHeight());

		// set size
		setPreferredSize(new Dimension(width, height));
	}
}

Der Schlüssel war die Zeile
Java:
width -= 1; // ????????????
. Wenn ich das tue tritt der Fehler nicht auf. Aber zwei Dinge verstehe ich nicht
1) WARUM? Hab ich hier nen Logik-Fehler? Die SP ist doch so breit wie alle Spalten und die ScrollBar oder?
2) Bei zwei Spalten liest er mir übrigens oben in der Schleife nicht die Werte aus, die ich vorher im Table gesetzt habe. Aus 75/bzw 70 hat er 80 gemacht. Die anderen stimmen...
 

hdi

Top Contributor
Ich melde mich nochmal. Inzwischen hat sich auch mein TableHeader wieder verändert, und nun stimmt auch nicht mal mehr die Höhe vom ScrollPane :( Ich weiss einfach nicht, was ich hier noch vergesse...

Also nochmal meine JScrollPane-Klasse:

Java:
public TableScrollPane(MyTable table) {
		super(table);
		setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		// install table settings button
		TableSettings settings = new TableSettings(table);
		setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, settings);

		// calculate width from table column widths & width of scroll bar
		int width = 0;
		for (int i = 0; i < table.getColumnCount(); i++) {
			TableColumn col = table.getColumnModel().getColumn(i);
			width += col.getPreferredWidth();
		}
		width += getVerticalScrollBar().getPreferredSize().width;
		width -= 1; // ????????????

		// set a height where all cells are fully visible
		int cellsToDisplay = 20;
		int headerHeight = table.getTableHeader().getPreferredSize().height;
		int cornerHeight = getCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER)
				.getPreferredSize().height;
		int maxHeight = Math.max(headerHeight, cornerHeight);
		int height = maxHeight + (cellsToDisplay * table.getRowHeight());
		height += 2; // ????????????

		// set size
		setPreferredSize(new Dimension(width, height));
	}

Die mit ??????? markierten Zeilen lösen das Problem, aber ich weiss nicht wieso:
zum width-1: Optisch sieht man da gar keinen Unterschied, weil ich ja nicht mit dem bloßen Auge sagen kann ob die Pane nun 1px weniger breit ist oder nicht.
Aber das löst das weiter oben genannte Problem mit diesem Column-Resize, also soweit nix "neues" ;)

zum height+2: Das ist neu, und das musste ich einbauen nachdem ich meinen TableHeaderRenderer verändert hab. Auf Grund neuer Komponenten ist er nun höher geworden (Es ist ein JPanel mit BorderLayout). Die Berechnung sollte meines Wissens nach in einer Höhe resultieren, wo das ScrollPane den Header anzeigt sowie 20 Zeilen, und zwar exakt. D.h. keine abgeschnittenen Zeilen, sondern so dass es genau aufgeht.
Zu dem Corner: Ich hab da nen Button drin, und entweder der Button richtet sich nach der Höhe des Headers aus oder andersrum, je nachdem was höher ist. Deshalb also diese Prüfung. (Der Header ist übrigens in diesem Fall grösser).

Nun also.. ich verstehe einfach nicht wieso das nicht alles schön aufgeht. Ich hab auch nach Insets gesucht usw, aber alles was ich mir da ausgegeben hab war eh 0.

Ich würd mich echt sehr freuen wenn mich da mal jmd aufklärt :toll:

PS: eigentlich, so zumindest finde ich es logisch, hätte ich bei der Berechnung der width auch - ähnlich wie bei der height - erstmal prüfen müssen ob die vertikale ScrollBar breiter ist oder die Corner, und das Maximum nehmen. Aber irgendwie bekomme ich bei der preferredWidth der corner einen Wert von "46", obwohl das Ding in der Anzeige nur so breit ist wie die ScrollBar. (Und das sind nur 15 oder 20)
 
Zuletzt bearbeitet:

hdi

Top Contributor
Da keiner antwortet versuch ich's nochmal mit einer Demo. Einfach starten und über folgendes nachdenken:

1) Wieso wird die unterste sichtbare Zelle des Tables nicht voll angezeigt (siehe height-Berechnung des ScrollPanes)?

2) Wieso ändern manchmal Columns ihre Breite (1px) wenn man sie rumschiebt und drauf rumklickt? Und wieso wird dieses Problem behoben, wenn man an der width-Berechnung des ScrollPanes ein wenig rumspielt, zB am Ende 2px abziehen oder ähnliche Magic-Numbers.

Danke euch, das Problem will ich echt gelöst bekommen weil es nervt mich dass ich scheinbar nicht verstehe wie der LayoutManager die Größen berechnet!

KSKB:
Java:
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;

public class ScrollPaneTest extends JFrame {

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

	public ScrollPaneTest() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		// add a scroll pane with a table
		add(createScrollPane(createTable()));
		pack();
		setLocationRelativeTo(null);
	}

	private JTable createTable() {
		JTable table = new JTable(50, 5);
		table.setAutoCreateRowSorter(true);
		/* set column widths */
		for (int i = 0; i < table.getColumnCount(); i++) {
			TableColumn col = table.getColumnModel().getColumn(i);
			int pref = 0;
			switch (i) {
			case 0:
				pref = 400;
				break;
			case 1:
				pref = 75;
				break;
			case 2:
				pref = 150;
				break;
			case 3:
				pref = 100;
				break;
			case 4:
				pref = 70;
				break;
			case 5:
				pref = 100;
				break;
			}
			col.setPreferredWidth(pref);
		}
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		return table;
	}

	private JScrollPane createScrollPane(JTable table) {
		JScrollPane sp = new JScrollPane(table);
		sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		/*
		 * calculate proper width & height. If we skip this, and let the scroll
		 * pane pack itself automatically, the scroll pane packs the table
		 * smaller than it should be according to the set column widths..
		 * (Because we did not set AUTO_RESIZE_OFF, and don't want that!) So we
		 * calculate it manually:
		 */
		int width = 0;
		for (int i = 0; i < table.getColumnCount(); i++) {
			TableColumn col = table.getColumnModel().getColumn(i);
			width += col.getPreferredWidth();
		}
		width += sp.getVerticalScrollBar().getPreferredSize().width;

		// set a height where no cell is cut off.
		int cellsToDisplay = 20;
		int headerHeight = table.getTableHeader().getPreferredSize().height;
		int height = headerHeight + (cellsToDisplay * table.getRowHeight());

		sp.setPreferredSize(new Dimension(width, height));
		return sp;
	}
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
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
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