Swing Spaltenbreite wird nicht gesetzt

fittich

Mitglied
Hallo,

ich hab folgendes Problem:

Ich hab eine JTable mit einem eigenen Renderer für den Header, weil ich dort vertikale Spaltenüberschriften nutze. Die Spaltenbreite meiner Tabelle berechne ich "dynamisch" (derzeit mehr oder weniger ;-)).

Java:
private void measureColumns() {
                TableColumnModel columns = table.getTableHeader().getColumnModel();
                int maxHeight = 0;
                //TODO: Dynamisch ermitteln, zurzeit Annahme, dass in jeder Zelle x steht
                String mark = "x";
                
                for(int c = 0; c < columns.getColumnCount(); ++c) {
                        TableColumn column = columns.getColumn(c);
                        
                        int modelColumn = table.convertColumnIndexToModel(c);
                        if(modelColumn < model.getColumnCount()) {
                               [...]                                
                                column.setPreferredWidth(mark.length() * 8);
                        }
                }
                table.getTableHeader().setPreferredSize(new Dimension(table.getColumnModel().getTotalColumnWidth(), maxHeight));
        }

Wenn ich das Panel mit der JTable neu aufrufe, funktioniert auch alles.
Jetzt können sich die Daten (Zeilen- und Spaltenüberschriften) der Tabelle allerdings ändern, also habe ich einen TableModelListener auf die JTable registriert und in tableChanged() wird das measureColumns() aufgerufen. Problem ist: die Spalten nehmen irgendeinen Default-Wert an und nicht den berechneten Wert aus measureColumns(). Auch wenn ich jetzt wieder zu den ursprünglichen Daten gehe, sind die Spaltenbreiten nicht mehr korrekt. Hat jemand 'ne Ahnung, was ich falsch mache?
 

André Uhres

Top Contributor
Hallo fittich,

vielleicht hilft das folgende Beispiel. Dazu musst du dir nur die angegebenen vier Klassen bei "tips4java" holen.

Gruß,
André

Java:
/**
 * TableDemo.java
 *
 * needs the following tablesupport classes:
 *
 * DefaultTableHeaderCellRenderer.java
 * VerticalTableHeaderCellRenderer.java
 * VerticalLabelUI.java
 * http://tips4java.wordpress.com/2009/02/27/default-table-header-cell-renderer/
 *
 * TableColumnAdjuster.java
 * http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/
 */
import tablesupport.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableDemo extends JFrame {

    private JTable table;
    private final TableColumnAdjuster tca;

    public TableDemo() {
        super("Table Demo");
        initComponents();
        TableCellRenderer headerRenderer = new VerticalTableHeaderCellRenderer() {

            JLabel label = new JLabel();
            Font font = label.getFont().deriveFont(Font.BOLD);

            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus, int row,
                    int column) {
                super.getTableCellRendererComponent(table, value, isSelected,
                        hasFocus, row, column);
                setFont(font);
                String str = value.toString().trim();
                if (str.contains(" ")) {
                    String val = "<html><font color=blue>"
                            + str.split(" ")[0]
                            + "<font color=green> "
                            + str.substring(str.indexOf(" ")) + "</font></html>";
                    setValue(val);
                }
                return this;
            }
        };
        Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
        while (columns.hasMoreElements()) {
            columns.nextElement().setHeaderRenderer(headerRenderer);
        }
        final JTableHeader header = table.getTableHeader();
        header.setReorderingAllowed(false);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        tca = new TableColumnAdjuster(table);
        tca.adjustColumns();
        TableModelListener tableModelListener = new TableModelListener() {

            public void tableChanged(final TableModelEvent e) {
                tca.adjustColumns();
            }
        };
        table.getModel().addTableModelListener(tableModelListener);

    }

    private void initComponents() {
        table = new JTable();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        table.setModel(new DefaultTableModel(
                new Object[][]{
                    {"aaaaaaaaaaaaaa", "bbbbbbb", "cc", "ddddddddddddddddddd"},
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null}
                },
                new String[]{
                    "Title 1", "Title 2", "Title 3", "Title 4"
                }) {

            Class[] types = new Class[]{
                String.class, String.class, String.class, String.class
            };

            @Override
            public Class getColumnClass(int columnIndex) {
                return types[columnIndex];
            }
        });
        getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
        pack();
    }

    public static void main(final String args[]) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                new TableDemo().setVisible(true);
            }
        });
    }
}
 

fittich

Mitglied
Erstmal danke für deine Antwort.

Um jetzt nicht alle meine Klassen über den Haufen zu werfen, hab ich jetzt erstmal die Klasse "TableColumnAdjuster.java" von "tips4java" eingebunden, um mir meine Spaltenbreiten berechnen zu lassen. Ich habe den gleichen Effekt wie vorher. Beim ersten Aufruf meiner Table funktioniert alles richtig, sobald ich das Model ändere, sind die Spalten wieder zu groß. Ich poste mal meine entsprechenden Klassen.

Java:
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;

import java.awt.*;

public class Overview extends JPanel implements TableModelListener {
        
        private static final long serialVersionUID = 1L;
        private JTable table;
        private MyData data;
        private TableColumnAdjuster tca;
        
        public Overview(MyData data){
                setLayout(new BorderLayout());
                this.data = data;
                initTable();
        }
        
        private void initTable(){
                RelationshipTableModel dataModel = new RelationshipTableModel(data);
                HiddenColumnsTableModel hiddenColumnsModel = new HiddenColumnsTableModel(dataModel);
                HiddenRowsTableModel hiddenRowsModel = new HiddenRowsTableModel(hiddenColumnsModel);
               
                hiddenRowsModel.addTableModelListener(this);
                
                table = new JTable(hiddenRowsModel);
                table.setDefaultRenderer(Object.class, new MyCellRenderer());
                table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
               
                JTableHeader header = table.getTableHeader();
                header.setDefaultRenderer(new MyHeaderCellRenderer());
                
                tca = new TableColumnAdjuster(table);
                tca.adjustColumns();
                
                JScrollPane pane = new JScrollPane(table);
                pane.setRowHeader(new MyTableRowHeaderRenderer(table, pane));
                add(pane, BorderLayout.CENTER);
        }
        
        @Override
        public void tableChanged(TableModelEvent e) {
                tca.adjustColumns();
        }
        
}

Mein HeaderCellRenderer:
Java:
public class MyHeaderCellRenderer extends DefaultTableCellHeaderRenderer  {
        private static final long serialVersionUID = 1L;

        public Component getTableCellRendererComponent(JTable table, Object value, 
                boolean isSelected, boolean hasFocus, int row, int column) {
                
                createVLabel((String)value);
                setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                setOpaque(true);
                return this;
        }
        
        private void createVLabel(String caption) {
                setIcon(new VTextIcon(this, caption, VTextIcon.ROTATE_LEFT));
                setFont(getFont().deriveFont(Font.PLAIN));
                setVerticalAlignment(SwingConstants.BOTTOM);
        }
}

Mein CellRenderer:
Java:
public class MyCellRenderer extends DefaultTableCellRenderer {
        private static final long serialVersionUID = 1L;
        private static final Color defaultColor = Color.WHITE;
        private static final Color selectedColor = new Color(200, 200, 255);
        private static final Border defaultBorder = new EmptyBorder(1, 1, 1, 1);

        public Component getTableCellRendererComponent(JTable table, Object val, boolean isSelected, boolean hasFocus, int row, int column) {
                Color color = defaultColor;
                Color foregroundColor = defaultColor;
                Border border = defaultBorder;
                
                if(hasFocus || isSelected) {
                        color = selectedColor;
                }
                
                MyTableModel model = (MyTableModel)table.getModel();
                int modelCol = table.convertColumnIndexToModel(column);
                int modelRow = table.convertRowIndexToModel(row);
                RelationshipInfo relInfo = model.getRelationshipInfo(modelRow, modelCol);

                if(relInfo != null){
                        foregroundColor = relInfo.getColor();
                        setText(relInfo.toString());
                } 
                else {
                        setText(null);
                }
                
                setOpaque(true);
                setForeground(foregroundColor);
                setBackground(color);
                setBorder(border);
                setHorizontalAlignment(SwingConstants.CENTER);
                setVerticalAlignment(SwingConstants.CENTER);
                
                return this;
        }
        
        /** Override to increase performance */
        public void validate() {} 
        public void revalidate() {} 
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {} 
        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {} 
}
 

fittich

Mitglied
So, das Problem hat sich geklärt. Ich hab meinen ursprünglichen Code genommen und einfach das tableChanged so angepasst:

Java:
public void tableChanged(TableModelEvent e) {
        SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                        measureColumns();                                
                }
        });
}

Durch das invokeLater läuft jetzt alles richtig :)
 

André Uhres

Top Contributor
Hallo fittich,

ich wollte gerade sagen, dass die Zusammenhänge in deinen Klassen
reichlich kompliziert und schwer nachvollziehbar sind und wollte deshalb vorschlagen,
dass du versuchst ein kurzes, selbständiges und kompilierbares Beispiel zu machen.
Aber das hat sich ja nun erledigt.
Aufgrund deines jetzigen Codes nehme ich an, dass "tableChanged" nicht immer
auf dem EventDispatchThread läuft. Das kannst du so feststellen:
Java:
        boolean eventDispatchThread = SwingUtilities.isEventDispatchThread();
        System.out.println("eventDispatchThread = " + eventDispatchThread);

Gruß,
André
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
richis-fragen Spaltenbreite bei drag nicht änderbar AWT, Swing, JavaFX & SWT 4
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
M Gridbaglayout Spaltenbreite AWT, Swing, JavaFX & SWT 3
S Jtable dynamische Spaltenbreite AWT, Swing, JavaFX & SWT 5
0 JTable Spaltenbreite automatisch an Inhalt anpassne geht nicht AWT, Swing, JavaFX & SWT 3
T jTable Spaltenbreite lässt sich nicht ändern AWT, Swing, JavaFX & SWT 8
A Swing Anpassen der Spaltenbreite durch die länge eines Strings AWT, Swing, JavaFX & SWT 3
1 Swing Spaltenbreite and CellEditor- Komponente anpassen AWT, Swing, JavaFX & SWT 4
R JTable: Spaltenbreite automatisch anpassen AWT, Swing, JavaFX & SWT 3
jueki Event bei Änderung der Spaltenbreite in einem JTable AWT, Swing, JavaFX & SWT 15
TiME-SPLiNTER Swing JTable Spaltenbreite beibehalten AWT, Swing, JavaFX & SWT 13
T JTable erst nach Änderung der Spaltenbreite neu zeichnen AWT, Swing, JavaFX & SWT 10
KrokoDiehl Swing Optimale Spaltenbreite auf Doppelklick (JTable) AWT, Swing, JavaFX & SWT 2
B Swing minimale Spaltenbreite für JTable AWT, Swing, JavaFX & SWT 2
T Spaltenbreite bei jTabel in Kombination mit Srollbalken AWT, Swing, JavaFX & SWT 2
L JTable automatische Spaltenbreite AWT, Swing, JavaFX & SWT 2
J JTable Spaltenbreite AWT, Swing, JavaFX & SWT 8
T JTable SpaltenBreite will einfach nich klappen AWT, Swing, JavaFX & SWT 4
M Spaltenbreite mit Sortierung AWT, Swing, JavaFX & SWT 3
J jTable, welcher listener für Änderung der Spaltenbreite AWT, Swing, JavaFX & SWT 2
D wiedermal JTable und die Spaltenbreite. AWT, Swing, JavaFX & SWT 8
S JTable Spaltenbreite AWT, Swing, JavaFX & SWT 2
T jTable / Spaltenbreite und Position AWT, Swing, JavaFX & SWT 2
K Spaltenbreite von mehreren Tabellen gleichzeitig verändern AWT, Swing, JavaFX & SWT 3
A JTable - Aktualisierung und Spaltenbreite AWT, Swing, JavaFX & SWT 5
J Probleme mit Spaltenbreite bei GridBagLayout AWT, Swing, JavaFX & SWT 19
S JTable und spaltenbreite AWT, Swing, JavaFX & SWT 2
G JTable: Spaltenbreite automatisch setzen AWT, Swing, JavaFX & SWT 4
L JTable -> Spaltenbreite ändern! AWT, Swing, JavaFX & SWT 3
J Spaltenbreite JTable AWT, Swing, JavaFX & SWT 7
P Methode wird nicht überprüft AWT, Swing, JavaFX & SWT 4
P paintComponent-Methode wird dauernd neu aufgerufen AWT, Swing, JavaFX & SWT 2
G JavaFX LineChart Datenpunkte Markierung wird abgeschnitten AWT, Swing, JavaFX & SWT 1
P JTextField wird nur sehr klein angezeigt und verändert die Größe nicht AWT, Swing, JavaFX & SWT 3
Telisti Javafx Image wird nicht richtig integiert AWT, Swing, JavaFX & SWT 8
J Netbeans die JavaFX-Anwendung wird nicht ausgeführt AWT, Swing, JavaFX & SWT 16
N €-Zeichen wird nicht akzeptiert AWT, Swing, JavaFX & SWT 4
G Problem mit der Anzeige von jLabel. Unlesbar wenn der Text geändert wird. AWT, Swing, JavaFX & SWT 28
berserkerdq2 Wie füge ich ein Bild in javafx mit dem Scenebuilder ein, das automatisch mitgezogen wird, wenn das Fenster vergrößert wird oder Vollbildmodus AWT, Swing, JavaFX & SWT 6
L jComboBox Actionlistener wird beim erstmaligen Befüllen getriggert AWT, Swing, JavaFX & SWT 7
_user_q Objekt.setSelected(false), wenn es nicht mehr fokussiert wird AWT, Swing, JavaFX & SWT 2
S Javafx getResource-Pfad wird nicht erkannt AWT, Swing, JavaFX & SWT 7
U Warum wird zweimal die Affinetransformation estellt (2Dgraphics, Java)? AWT, Swing, JavaFX & SWT 31
DonBronson Gezeichnetes Objekt verschwindet nachdem erneut gezeichnet wird AWT, Swing, JavaFX & SWT 8
ProggersWorld JavaFX TextArea BackgroundImage wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
M Bild wird nicht geladen obwohl sie gefunden wird AWT, Swing, JavaFX & SWT 0
M Nach Export als Runnable Jar wird css nicht merh gefunden AWT, Swing, JavaFX & SWT 22
izoards Outlook Mail erstellen - Signatur wird nicht angezeigt. AWT, Swing, JavaFX & SWT 3
J actionperformed wird nicht aufgerufen/ repaint() AWT, Swing, JavaFX & SWT 6
J Swing Komponente wird unpassend angepasst in der Größe AWT, Swing, JavaFX & SWT 35
J Java FX NullPointerException, ObservableList wird in View nicht angezeigt.. AWT, Swing, JavaFX & SWT 34
S Next_Button wird nicht ausgeführt. AWT, Swing, JavaFX & SWT 6
FrittenFritze Ein Problem mit der CSSBox, die Größe wird nicht angepasst AWT, Swing, JavaFX & SWT 5
CptK windowClosed() nur aufrufen, wenn Fenster nicht über Button geschlossen wird AWT, Swing, JavaFX & SWT 1
J Komponente wird manchmal falsch gezeichnet AWT, Swing, JavaFX & SWT 0
J Swing JList wird nicht angezeigt AWT, Swing, JavaFX & SWT 6
JMölleri Swing Image wird unscharf dargestellt AWT, Swing, JavaFX & SWT 2
JojoSand Java Programm wird nicht gestartet - keinen Fehlerhinweis AWT, Swing, JavaFX & SWT 9
R Text vom Jlabel wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
D JavaFX Bearbeitetes Bild wird nicht gespeichert AWT, Swing, JavaFX & SWT 9
J setOnCloseRequest wird nicht ausgelöst AWT, Swing, JavaFX & SWT 3
P JavaFX Fenster wird nicht angezeigt (Mac) AWT, Swing, JavaFX & SWT 13
B JavaFX Bei Scenen-Wechsel im primaryStage wird aktuelle Fenstergröße nicht mit übernommen AWT, Swing, JavaFX & SWT 16
B JavaFX Warum wird hier eine NullPointer-Exception geworfen? AWT, Swing, JavaFX & SWT 7
M JavaFX javaFX Label-Text wird nicht gesetzt AWT, Swing, JavaFX & SWT 3
O Swing "Eigenes" JPanel wird dem JScrollPane nicht hinzugefügt AWT, Swing, JavaFX & SWT 5
L Swing JLabel wird beim ändern der Schriftart immer neu gezeichnet. AWT, Swing, JavaFX & SWT 2
R Layout Manager null und Component wird nicht hinzugefügt AWT, Swing, JavaFX & SWT 3
Zrebna JavaFX-Projekt mit Bildern funktioniert nicht - um Hilfe wird gebeten AWT, Swing, JavaFX & SWT 14
kodela BufferStrategy wird nicht gefunden AWT, Swing, JavaFX & SWT 5
J JPanel wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
S ImageView wird dem Gridpane nicht zugefügt AWT, Swing, JavaFX & SWT 1
G Repaint wird nicht durchgeführt AWT, Swing, JavaFX & SWT 8
E Warum wird Text im JTextArea erst am Programmende angezeigt ? AWT, Swing, JavaFX & SWT 1
S Swing Panel wird nicht neu gezeichnet AWT, Swing, JavaFX & SWT 3
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
Bluedaishi TableView mit Combox wert wird nicht in die TableView gesetzt AWT, Swing, JavaFX & SWT 38
L JFrame wird zu klein erstellt AWT, Swing, JavaFX & SWT 7
T JavaFX Nach Zoomen wird an falscher Stelle gezeichnet AWT, Swing, JavaFX & SWT 0
kodela Swing Letzte Änderung in der Tabelle wird nicht gespeichert AWT, Swing, JavaFX & SWT 5
cool_brivk24 AWT BufferedImage wird nicht geladen AWT, Swing, JavaFX & SWT 17
S JavaFX Wird es überhaupt genutzt? AWT, Swing, JavaFX & SWT 3
FRI3ND GUI wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
J Canvas wird nicht angezeigt AWT, Swing, JavaFX & SWT 10
K Swing JScrollPane wird nicht angezeigt wenn man Components darstellt. AWT, Swing, JavaFX & SWT 2
ralfb1105 Swing Wert in JTextField wird falsch ausgegeben AWT, Swing, JavaFX & SWT 2
B JavaFX Text wird nicht angezeigt, kein Fehler AWT, Swing, JavaFX & SWT 2
J Aus welchen Grund wird der Button nicht angezeigt im GridPane? AWT, Swing, JavaFX & SWT 1
J MouseListener wird nicht ausgeführt. AWT, Swing, JavaFX & SWT 4
E Swing Liste in Scrollpane wird nicht angezeigt AWT, Swing, JavaFX & SWT 2
J Controller wird zu groß, was tun ? AWT, Swing, JavaFX & SWT 5
CptK Wieso wird nur ein Teil meiner Buttons angezeigt? AWT, Swing, JavaFX & SWT 1
T Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
M Aktion ausführen wenn ein JRadiobutton deselektiert wird. AWT, Swing, JavaFX & SWT 3
DaCrazyJavaExpert Swing JPanel "ContentPane" wird nicht gesetzt/angezeigt AWT, Swing, JavaFX & SWT 16
I JavaFX Fenster wird auf einem anderen Rechner anders dargestellt AWT, Swing, JavaFX & SWT 5
zhermann FX Label text wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 12
zhermann TableView wird nicht gefüllt AWT, Swing, JavaFX & SWT 14
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben