Swing setPreferredWidth für JTable funktioniert nur beim ersten Aufruf!?

kleine247

Mitglied
Hallo,

ich entschuldige mich im Voraus, wenn die Antwort auf meine Frage hier irgendwo im Forum zu finden ist und ich sie nicht gefunden/verstanden habe. Ich habe sehr wohl gesehen, dass hier viele ähnliche Beiträge sind, aber irgendwie hat mich noch nichts weitergebracht.

Ich versuche gerade eine schöne Oberfläche auf die Reihe zu kriegen, wobei ich mehrere verschachtelte Panels habe. In einem JScrollPane habe ich ein JTable und habe es jetzt endlich geschafft, dass die Spaltenbreiten so gesetzt werden wie ich will (es wird erst jede Spalte so breit gemacht wie minimal notwendig um allen Text zu sehen und wenn das Panel dann noch Platz hat, werden die Breiten gleichmäßig erhöht). Die Methode, die das macht, wird direkt am Anfang aufgerufen und das klappt auch. Damit die Spaltenbreite auch wieder angepasst wird, wenn der Benutzer die Größe des Gesamtfensters ändert, habe ich einen HierarchyBoundsListener() hinzugefügt, der das ganze dann nochmal aufruft (und das tut er auch)... nur leider ändert sich dadurch an den Spaltenbreiten dann absolut gar nichts >.< Mein col.setPreferredWidth wird aber mit neuen Zahlen aufgerufen. Mit col.setMinWidth und col.setMaxWidth ändert sich leider auch nichts. Außerdem habe ich hintendran noch ein validate auf das JSplitPane gemacht, in dem mein JScrollPane mit der JTable ist. Jetzt fällt mir aber langsam nichts mehr ein. Fehlt da noch irgendwas ganz Offensichtliches?

Wenn das so nicht nachvollziehbar ist, kann ich gerne auch Code posten.
 
Zuletzt bearbeitet von einem Moderator:

Airborne

Mitglied
Warum setzt du die Spaltenbreite nicht in Abhängigkeit von der darüber liegenden Panel-Breite? einfacher isses allemal also sich "ranzutasten".

An sich sollte die Tabelle mit der GUI rendern - wenn sie denn relativ bemessen ist und kein minWidth()/ setmaxWidth() gesetzt ist.
 

kleine247

Mitglied
genau das versuche ich ja. mein setPreferredSize soll jedes Mal, wenn die Gesamtgröße geändert wird, in Abhängigkeit vom Panel gesetzt werden
 

kleine247

Mitglied
Hallo,

leider besteht mein Problem immer noch. Nur ist mir klar geworden, dass das Problem nicht nur im graphischen Bereich liegt. Ich schaffe es einfach nicht, dass meine Tabelle irgendwie aktualisiert wird.

Mit der Methode 'showResult' erzeuge ich eine neue Tabelle und mache die ganzen Berechnungen für die richtige Breite der Spalten. Die Methode wird direkt im Konstruktor aufgerufen und beim ersten Anzeigen sind auch alle Spaltenbreiten so wie sie sein sollen. Wenn sich jetzt die Daten in der zugrundeliegenden MySQL Datenbank ändern, soll das natürlich sichtbar werden. Über einen aktualisieren-Button rufe ich deswegen 'redrawTable' auf, was wiederrum nichts anderes macht, als wieder 'showResult' aufzurufen. Die Daten sollen also komplett neu gelesen werden und die Tabelle neu aufgebaut. Ich mache im Prinzip nichts anderes, wie beim ersten Mal auch. Deswegen komme ich auch einfach nicht dahinter, warum sich danach in meiner Tabelle rein gar nichts ändert (nachdem ich in der DB Daten hinzugefügt habe).
Ich muss irgendwo einen offensichtlichen Denkfehler oder eine totale Wissenslücke haben, von der ich noch nichts weiß o_O

Hier jetzt mal mein Code, wobei ich denke, dass ihr euch nicht die Mühe machen müsst, meinen ganzen Berechnungskram 100% nachzuvollziehen, da dieser laut meinen Probeausgaben funktioniert. Es wird nur einfach nicht angezeigt =(
Java:
public class CentreView extends JSplitPane {

    JPanel panelFunctions;
    JScrollPane paneResults;	
    JTable table=null;
    ...

    //Konstruktor
    public CentreView (MainView mainView){	
        ...
        showResult (activeAccount.getResult(), activeAccount.getAttribute());
        ...
        setTopComponent(panelFunctions=new JPanel());
        setBottomComponent(paneResults);
    }

    //wird aufgerufen bei resize oder bei Klick auf aktualisieren (Tabelle komplett neu erzeugen)
    public void redrawTable (){		
        this.table=null;
        showResult (activeAccount.getResult(), activeAccount.getAttribute());		
    }

    //Result-Tabelle mit Daten aus MySQL DB erstellen und in Panel anzeigen
    public void showResult(ResultSet result, Vector<String> attributes){ 
        Vector<Vector<Object>> tableRows= new Vector<Vector<Object>>(); 	
        //Datenstruktur aufbauen, die von JTable Konstruktor akzeptiert wird    
        try {
            while (result.next()) {			//jede Zeile				
                Vector<Object> row = new Vector<Object>();
                for (String s: attributes){	//jedes Attribut
                    row.add(result.getObject(s));	        		
                }
                tableRows.add(row);
            }
        }catch (Exception e){
            System.out.println("Fehler bei Tabellenbefüllung "+e);
        }
        //JTable erzeugen
        table = new JTable(tableRows, attributes);		
        //Spalten nicht mehr gleichmäßig über die verfügbare Fläche verteilen, damit eigene Berechnungen gelten
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
				
        DefaultTableColumnModel colModel = (DefaultTableColumnModel)table.getColumnModel();
				
        //eigene Methode aufrufen, um für jede Spalte der Tabelle, die minimal benötigte Spaltenbreite zu ermitteln
        List<Integer> necessaryWidths = getNecessaryWidth(table, colModel);
        //insgesamt benötigte Breite für Tabelle erreichnen
        int necessaryWidthSum=0;
        for (Integer i: necessaryWidths){
            necessaryWidthSum+=i;
        } 
				
        //Tabelle dem JScrollPane hinzufügen
        paneResults= new JScrollPane(table);
		
        //verfügbare Breite für Tabelle ermitteln
        int availableWidth=0;
        //Höhe zur Verfügung kleiner als Höhe benötigt	
        if (paneResults.getPreferredSize().height<table.getPreferredSize().getHeight()) {	
            //Gesamtframebreite - Menübreite - Puffer, damit kein Scrollen - Platz für Scrollbar
            availableWidth=(int)mainView.getSize().getWidth()-(int)mainView.getPanelMenue().getPreferredSize().getWidth()-20-15;
        }else {
            //Gesamtframebreite - Menübreite - Puffer, damit kein Scrollen 
            availableWidth=(int)mainView.getSize().getWidth()-(int)mainView.getPanelMenue().getPreferredSize().getWidth()-20;
        }
		
        //ermitteln, um wieviel die Tabellenspalten ggf noch erhöht werden können und Spaltenbreiten setzen
        int add =0;
        int remainder=0;
        if (availableWidth>necessaryWidthSum){			
            add = (int) ((availableWidth-necessaryWidthSum) / table.getColumnCount());
            remainder = (int) (availableWidth - necessaryWidthSum - (add*table.getColumnCount()));
						
            for (int i = 0; i<table.getColumnCount(); i++){
                TableColumn col = colModel.getColumn(i);
                if (i==table.getColumnCount()-1){	//letzte Spalte kriegt den Rest
                    col.setPreferredWidth(necessaryWidths.get(i)+add+remainder);
                }
                else{
                    col.setPreferredWidth(necessaryWidths.get(i)+add);	
                }
            }	
        }		
        this.validate();	
		
        paneResults.setVisible(true);	
        table.setVisible(true);	
    }
}
 

bERt0r

Top Contributor
Deine Berechnungen haben mit deinem Problem überhauptnichts zu tun. Den wichtigen Code hast du nämlich rausgelöscht.
"Mit der Methode 'showResult' erzeuge ich eine neue Tabelle" da liegt dein Problem. Du erzeugst nicht eine neue Tabelle, du zeigst neue Werte an. Die Tabelle kann die gleiche bleiben. Wenn du eine Variable JTable table hast und diese null setzt, wird dein hat das keinerlei auswirkungen auf die GUI. Eine Objektvariable ist eine Referenz. Löscht du die Referenz, ist das Objekt immer noch da.

Wenn du einen JTable verändern willst, gib ihm mit setModel ein neues TableModel.
 

kleine247

Mitglied
Danke für deine Antwort. Damit hab ichs schonmal versucht und aufgegeben. Nachdem ich jetzt von dir weiß, dass das der richtige Ansatz war, hab ichs nochmal probiert. Aber ich hab schon wieder tausende Varianten erfolglos ausprobiert. Ich weiß nich genau, ob ich richtig dahintersteige. Also ich hab jetzt folgendermaßen ein TableModel hinzugefügt:

Java:
table.setModel(		
		new AbstractTableModel() {
			private static final long serialVersionUID = 1L;
			public String getColumnName(int col) {
		        return attributes.get(col).toString();
		}
		public int getRowCount() { 
		    	return tableRows.size(); 
		}
		public int getColumnCount(){ 
		    	return attributes.size(); 
		}
		public Object getValueAt(int row, int col) {
		        return tableRows.get(row).get(col);
		}
		public boolean isCellEditable(int row, int col) { 	
		    	return true; 
		}
		public void setValueAt(Object value, int row, int col) {
		    	tableRows.get(row).set(col, value);
		        fireTableCellUpdated(row, col);
		}
});

Soo.. dann denk ich mir theoretisch, dass es sogar schon reichen müsste, zum Aktualisieren nur meinen verschachtelten Vector tableRows anzupassen. Okay, so einfach ist es aber anscheinend nicht.
Soweit ich gelesen habe, soll man also das TableModel anpassen, indem man die alten Zeilen entfernt und die neuen einfügt. Okay.. Aber das würde doch heißen, dass ich die Methode setValueAt(..) von meinem TableModel aufrufe und da wieder die Werte von tableRows reinschreibe, womit ich im Grunde doch gar nichts mache, weil ich Werte aus tableRows in tableRows schreibe. Das wäre nich so, wenn keine Referenz auf tableRows gespeichert ist. Okay, dann müsste mans wirklich anpassen - könnt ich noch irgendwie so nachvollziehen. Aber das krieg ich auch irgendwie nicht hin. Ich dachte mir, ich füg meinem TableModel noch eine Methode clear() hinzu, um erstmal die alten Zeilen zu löschen.

Java:
public void clear (){
	tableRows.clear();
}

Wenn ich dann aber table.getModel().clear(); aufrufen will, kennt er das clear nicht, weil ein normales TableModel das wohl nicht hat. Was macht man da? Oder andere Frage: Bewege ich mich annährend in die richtige Richtung, oder ist das alles Schrott, was ich mir hier überlege?
 

kleine247

Mitglied
Hab das mit dem TableModel wahrscheinlich zu kompliziert gemacht. Ich dachte, so würde es jetzt ganz gut aussehen:

Java:
//tableRows und attributes mit aktuellen Daten befüllen
...

if (first){   //beim ersten Mal JTable und TableModel neu erstellen
	first=false;
	table = new JTable();	
	tabMod = new DefaultTableModel (tableRows, attributes);
	table.setModel (tabMod);
}	
else {	      //bei weiteren Durchgängen JTable und TableModel nur noch bearbeiten
	for (int i = 0; i<tabMod.getRowCount(); i++){   //Zeilen aus TableModel entfernen
		((DefaultTableModel) table.getModel()).removeRow(i);
	}
	for (int i = 0; i<tableRows.size(); i++){    //aktuelle Zeilen in TableModel einfügen
		((DefaultTableModel) table.getModel()).addRow(tableRows.get(i));
	}				
}

Leider lädt er dann so lange, bis es zu einem java heap space error kommt. Warum passiert das? Ich hab durch Probeausgaben herausgefunden, dass meine tableRows erstmal 17 Zeilen hat (stimmt mit der DB überein). Nachdem aber die erste for-Schleife im else Zweig durchgelaufen ist, in der ich die Zeilen aus dem TabelModel entferne, sind in tableRows nur noch 8 Zeilen!? Wie kommt denn sowas zustande - ich hätte gedacht das TableModel beeinflusst meine Daten entweder ganz oder gar nicht. Unabhängig davon, verstehe ich trotzdem nicht, warum er dann überfordert ist, weil er muss damit ja sozusagen weniger Zeilen durchgehen als geplant. Zur Info: Bei jedem Start wird noch ca. 5 Mal resize aufgerufen, was wahrscheinlich durch die ganzen verschachtelten Panels oder so passiert. Dadurch wird das ganze dann halt nicht nur einmal gerechnet - aber eine Erklärung ist das nicht..
 

bERt0r

Top Contributor
Erstell einfach ein neues DefaultTableModel mit den Daten die du erhältst und weise dieses deiner JTable mit setModel zu.
 

kleine247

Mitglied
Jaaa, jetzt hab ichs! Vielen Dank =)

Zusätzlich hatte ich noch den Fehler drin, dass

Java:
paneResults= new JScrollPane(table);

jedes Mal gemacht wurde. Darf natürlich nur beim ersten Mal sein.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Gibt es soetwas wie setPreferredWidth() für JTextPane? AWT, Swing, JavaFX & SWT 3
Juelin setzen background color für selected Row im Tableview AWT, Swing, JavaFX & SWT 21
Juelin Für Java-Spezialisten AWT, Swing, JavaFX & SWT 4
H JTabel - RowFilter Daten für Berechnung filtern AWT, Swing, JavaFX & SWT 6
I JavaFX JavaFx-Anwendung für die Erstellung einer Windows-Anwendung? AWT, Swing, JavaFX & SWT 6
M Eigene Java Klasse für allgemeine Grafikelemente AWT, Swing, JavaFX & SWT 8
M Vokabelprogram - Schleife für Liste soll schrittweise durchlaufen werden AWT, Swing, JavaFX & SWT 3
tommybalbor JavaFx Anwendung klappt nicht für macOs Nutzern, wenn ich zwei dependecies bei maven hinzufüge AWT, Swing, JavaFX & SWT 6
I Libraries für AWT für andere Grafik-Frameworks tauglich machen AWT, Swing, JavaFX & SWT 6
R auto. Importanweisungen für javafx funktioniert in Eclipse nicht mehr AWT, Swing, JavaFX & SWT 4
komplettlost Vollbildmodus für MacOs Nutzer geht nicht AWT, Swing, JavaFX & SWT 13
D JavaFX Schadensberechnung für Kartenspiel AWT, Swing, JavaFX & SWT 1
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
Jose05 JavaFX: eigene FXML-Datei für einen Button AWT, Swing, JavaFX & SWT 3
L actionListener für Button AWT, Swing, JavaFX & SWT 97
izoards Textfeld für Zeit AWT, Swing, JavaFX & SWT 4
CptK Wie funktioniert contains() für Path2D.Double AWT, Swing, JavaFX & SWT 10
T Getter und Setter für eine Stage AWT, Swing, JavaFX & SWT 6
P Swing Programm hängt sich bei Buttondruck auf? (GUI für "Chatbot" erstellen) AWT, Swing, JavaFX & SWT 15
T Button für GUI programmieren AWT, Swing, JavaFX & SWT 1
Z Switch Case für Buttons AWT, Swing, JavaFX & SWT 8
M Hough-Transformation für Kreise und andere Formen AWT, Swing, JavaFX & SWT 3
kodela HTML-tags für JLabel AWT, Swing, JavaFX & SWT 9
E Keystroke für Ausschneiden läßt sich nicht ändern AWT, Swing, JavaFX & SWT 2
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
MiMa Package Struktur für GUI Programmierung AWT, Swing, JavaFX & SWT 26
N JavaFX 1 Listener für mehrere ChoiceBoxen AWT, Swing, JavaFX & SWT 3
B eclipse für JavaFx setuppen AWT, Swing, JavaFX & SWT 4
K Swing Struktur für TreeTable rekursiv aufbauen AWT, Swing, JavaFX & SWT 17
A Swing JTextField an Button übergeben für Popup-Fenster funktioniert nicht AWT, Swing, JavaFX & SWT 3
H Ein Patten für das Gluon Mobile Framework AWT, Swing, JavaFX & SWT 7
J Gibt es einen Grund für 16x16 anstatt z.B. 15x15 Tiles ? AWT, Swing, JavaFX & SWT 10
F JFormattedTextField für kg und Währung AWT, Swing, JavaFX & SWT 6
V Swing für jedes Kästchen eine eigene Farbe AWT, Swing, JavaFX & SWT 2
F Wie bekomme ich den Wert der ComboBox in eine Variable gespeichert welche ich für meinen ActionListener nutzen kann? AWT, Swing, JavaFX & SWT 3
Soloeco JavaFX Dreifachklick für MenuButton erforderlich AWT, Swing, JavaFX & SWT 2
L JavaFX Lösungsvorschläge für dieses coole Control AWT, Swing, JavaFX & SWT 8
looparda Suche Lib für Visualisierung von Graphen AWT, Swing, JavaFX & SWT 12
G LayoutManager Beliebige Anzahl von Panels für LayoutManager AWT, Swing, JavaFX & SWT 3
L Ein Actionlistener für ein Textfeld, anstatt viele Actionlistener für ein Textfeld AWT, Swing, JavaFX & SWT 7
S Swing Finde Grund für NullPointerExeption nicht. AWT, Swing, JavaFX & SWT 2
W JavaFX (j)Unittests für GUI AWT, Swing, JavaFX & SWT 0
B JavaFX JavaFX TableView PropertyValueFactory für Werte aus HashMap AWT, Swing, JavaFX & SWT 2
SchmidiMC Swing Vorschläge für ein Design AWT, Swing, JavaFX & SWT 5
Z JavaFX Pane für wechselnde Sub-Panes mit Auto-Resize AWT, Swing, JavaFX & SWT 2
S 2D-Grafik affine Transformation für Text-Shape AWT, Swing, JavaFX & SWT 0
G Swing Variable Elemente für GroupLayout AWT, Swing, JavaFX & SWT 18
kodela Accalerator für einige Menüoptionen funktioniert nicht mehr AWT, Swing, JavaFX & SWT 3
P Swing Empfehlungen für einfaches Computerspiel AWT, Swing, JavaFX & SWT 4
L DragDropped für jede Node AWT, Swing, JavaFX & SWT 0
temi JavaFX Lösungsansatz für Umsetzung gesucht AWT, Swing, JavaFX & SWT 4
J Swing JavaProgramm für Verschlüssen für eine Datei AWT, Swing, JavaFX & SWT 19
D DatePicker für Java Swing AWT, Swing, JavaFX & SWT 2
MiMa Programmeinstellungen für Anwendung?? AWT, Swing, JavaFX & SWT 54
heinz ketchup While-Schleife in einem Service für GUI AWT, Swing, JavaFX & SWT 22
L JavaFX Renderer für JavaFX AWT, Swing, JavaFX & SWT 2
MiMa GUI Controller für Border Pane als MVC Modell AWT, Swing, JavaFX & SWT 1
L Font für Dashboard AWT, Swing, JavaFX & SWT 3
F Swing JColorChooser für die JToggleButtons AWT, Swing, JavaFX & SWT 5
S JavaFX Optimierung für verschiedene Auflösungen AWT, Swing, JavaFX & SWT 12
L JavaFX Animation für Panel wechsel AWT, Swing, JavaFX & SWT 3
T Swing Drag and Drop für JComponents AWT, Swing, JavaFX & SWT 1
Kloso Swing Pseudocode für Strafurzeichnung AWT, Swing, JavaFX & SWT 4
F Konstruktor für "Vier Gewinnt" AWT, Swing, JavaFX & SWT 10
L JavaFX PdfViewer für JavaFX Anwendung AWT, Swing, JavaFX & SWT 6
R Swing Welche LayoutManager sind die richtigen für mich? AWT, Swing, JavaFX & SWT 11
L Event Handling Gui für Taschenrechner AWT, Swing, JavaFX & SWT 27
C Slider für Zeitauswahl AWT, Swing, JavaFX & SWT 3
M Limit für JFrame-Vergrößerung AWT, Swing, JavaFX & SWT 8
GreenTeaYT Button funktioniert nicht für Ein-und Auszahlungen? AWT, Swing, JavaFX & SWT 8
K Liniendicke für Line Chart dynamisch ändern AWT, Swing, JavaFX & SWT 0
K JButton nicht sichtbar machen für User 2 AWT, Swing, JavaFX & SWT 4
OnDemand Gui Themes für FX AWT, Swing, JavaFX & SWT 4
G DefaultListModel für JList AWT, Swing, JavaFX & SWT 2
P JavaFX Kalender mit Kacheln für Ereignisse AWT, Swing, JavaFX & SWT 4
S ActionListener für alle Buttons AWT, Swing, JavaFX & SWT 26
J Swing Neuen Command für "show"? AWT, Swing, JavaFX & SWT 2
sandaime Swing Thread für CMD auslesen AWT, Swing, JavaFX & SWT 16
H Swing JFileChooser für nicht existierendes Unterverzeichnis AWT, Swing, JavaFX & SWT 3
R Java FX - Fxml - relative Größenangaben für Breite und Höhe einer TextArea AWT, Swing, JavaFX & SWT 8
D GUI-Bau für ein Auswertungs-Tool AWT, Swing, JavaFX & SWT 11
L Swing CellRenderer für einzelne Zellen? AWT, Swing, JavaFX & SWT 5
RalleYTN Swing Menü für Texteditor (Rechtsklick) AWT, Swing, JavaFX & SWT 4
H Applet Flappy Bird für Noobs AWT, Swing, JavaFX & SWT 4
X JavaFX Tooltips für XYChart-Knoten werden nicht angezeigt! AWT, Swing, JavaFX & SWT 3
Thallius Swing Aufgabe für einen der gerne Tüftelt. AWT, Swing, JavaFX & SWT 4
A hilfe für flowlayout AWT, Swing, JavaFX & SWT 6
B EventHandler für durch Tastenkombination erzeugte Zeichen AWT, Swing, JavaFX & SWT 3
T Hintergrund für GUI AWT, Swing, JavaFX & SWT 1
L JavaFX TableView mit Attributs der Modellreferenzerierung für die Spalte AWT, Swing, JavaFX & SWT 3
C JavaFX Character Comparator für TableColumn AWT, Swing, JavaFX & SWT 0
KrokoDiehl JavaFX Gleiche Controller-Instanz für inludiertes FXML AWT, Swing, JavaFX & SWT 1
V Tastatur KeyListener für mehrere Buttons AWT, Swing, JavaFX & SWT 1
S Pfad für Speichervorgang auswählen AWT, Swing, JavaFX & SWT 11
M If für viele TextFields AWT, Swing, JavaFX & SWT 7
stylegangsta Eigene Klasse für JButton aus dem JFrame abrufen AWT, Swing, JavaFX & SWT 29
R JMenuItems für Touchscreen auseinanderziehen AWT, Swing, JavaFX & SWT 3
L LookAndFeel Eigenes Design für die Applikation AWT, Swing, JavaFX & SWT 4
G Grafikformat für AWT-Applet? AWT, Swing, JavaFX & SWT 0
J Java -8 Action Listener für mehrere Buttons AWT, Swing, JavaFX & SWT 9

Ähnliche Java Themen

Neue Themen


Oben