Hallo zusammen,
Mir vergeht langsam die Lust: ich versuche in einem GridBaglayout unter eine JTable eine Zeile mit einer Checkbox und 4 Textboxen nebeneinander zu setzen. Allerdings hat jede Textbox eine unterschiedliche Größe, was optisch einfach furchtbar aussieht. Ich versuche, jeder der 5 Komponenten die gleiche Größe zuzuweisen, (Tabellenbreite - Offset) / 5, aber alles spinnt nur rum.
Zuerst habe ich sie direkt in das GridbagLayout gesetzt. Als das nicht funktionierte dachte ich “Hey du bist schlau, setze sie in eine Box, die wird das richten!”. Aber auch hier Fehlanzeige:
Hat jemand eine Idee, wie ich den Textfelder OHNE IHNEN EINE BESTIMMTE PIXELZAHL ZUZUWEISEN auf die gleiche Breite bringe? Das mit der Pixelzahl ist mir wichtig, da ich evtl. noch mit die Gesamtbreite ändern muss und ich nicht jede Komponente einzeln wieder verändern möchte.
Wäre super wenn ihr was wisst, ich habe es langsam echt satt…
ich habe das mal etwas überarbeitet, so dass es als Komponente nutzbar ist:[SPOILER]```public class TableFooterTest extends JPanel {
private static final long serialVersionUID = 1L;
private JPanel filterRow;
private JTable table;
public TableFooterTest(TableModel tableModel) {
super(new BorderLayout());
table = new JTable(tableModel);
add(new JScrollPane(table));
// Panel for text fields
filterRow = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
for (int i = 0; i < tableModel.getColumnCount(); i++) {
filterRow.add(Boolean.class.equals(tableModel.getColumnClass(i))//
? createCheckBox()
: new JTextField(" Sum at - " + i));
}
add(new JScrollPane(filterRow), BorderLayout.SOUTH);
ColumnWithdSynchonizer columnWithdSynchonizer = new ColumnWithdSynchonizer();
table.getColumnModel().addColumnModelListener(columnWithdSynchonizer);
columnWithdSynchonizer.columnMarginChanged(new ChangeEvent(table
.getColumnModel()));
setBorder(BorderFactory.createLineBorder(Color.BLUE, 10));
}
private JCheckBox createCheckBox() {
JCheckBox checkBox = new JCheckBox();
checkBox.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
checkBox.setHorizontalAlignment(SwingConstants.CENTER);
return checkBox;
}
class ColumnWithdSynchonizer implements TableColumnModelListener {
// Implement TableColumnModelListener methods
// (Note: instead of implementing a listener you should be able to
// override the columnMarginChanged and columMoved methods of JTable)
@Override
public void columnMarginChanged(ChangeEvent e) {
TableColumnModel tcm = table.getColumnModel();
int columns = tcm.getColumnCount();
for (int i = 0; i < columns; i++) {
Component textField = filterRow.getComponent(i);
Dimension d = textField.getPreferredSize();
d.width = tcm.getColumn(i).getWidth();
textField.setPreferredSize(d);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
filterRow.revalidate();
}
});
}
@Override
public void columnMoved(TableColumnModelEvent e) {
Component moved = filterRow.getComponent(e.getFromIndex());
filterRow.remove(e.getFromIndex());
filterRow.add(moved, e.getToIndex());
filterRow.validate();
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new GridLayout(0, 1));
TableModel tableModel = new DefaultTableModel(9, 15) {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int columnIndex) {
return 0 == columnIndex ? Boolean.class : String.class;
}
};
frame.getContentPane().add(new TableFooterTest(tableModel));
tableModel = new DefaultTableModel(11, 11) {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int columnIndex) {
return getColumnCount() - 1 == columnIndex ? Boolean.class
: String.class;
}
};
frame.getContentPane().add(new TableFooterTest(tableModel));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(800, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}```[/SPOILER]Verbesserungspotenzial gibt’s noch bei der Auswahl der Footerkomponente, da muss zum einen noch Funktionalität angebunden und zum anderen andere Datentypen unterstützt werden.
Für die Überarbeitung danke ich dir. Wenn ich es recht sehe muss ich nur noch meine gewünschten Funktionen in die FooterKomponenten einbauen, stimmts?
Aber da bin ich ja mit ActionCommands und eigenen Listenern schnell durch. Ich probiere das alles mal aus
Also das ganze sieht jetzt super aus, ungefähr so:
Das einzige was ein wenig stört ist der Rand nach unten.
Außerdem funktioniert es nicht, wenn ich eigene von JTextField abgeleitete Klassen verwende. Da muss ich evtl noch ein wenig rumschauen, aber fürs erste ist das schonmal mehr als genug
@L-ectron-X : Unbedingt neue Glaskugel besorgen, dann muss niemand mehr stundenlang das Internet durchforsten um dann doch was anderes zu machen
Ich musste neulich die Größe des Panels verändern. Damit ist die Tabelle jetzt breiter geworden, aber das Alignment mit den Textfeldern stimmt nicht mehr :(. Die Checkbox unter der ersten Spalte passt, aber die Suchfelder sind kleiner als die Spaltenbreite.
Das verstehe ich aber nicht, da doch bei dem Quellcode die Spaltenbreite aus der Table ausgelesen wird und auf die Textfelder übertragen wird. Wisst ihr was da schief läuft (oder wahrscheinlicher wo mein Denkfehler ist) ?
Danke für den Tipp :). Ich habe dann herausgefunden, dass das benutzte FlowLayout kein PreferredSize beachtet. Nach dem Umsteigen auf ein BoxLayout funktioniert es nun (Leider auch nur mit Strut für den Scrollbalken.
Die Höhe der Suchleiste kann ich leider weder mit Flow noch mit BoxLayout verändern :(. Vielleicht muss ich dann noch auf ein GridBagLayout umsteigen, aber wegen 2 Komponenten ist mir das fast du doof