Swing JTable mit scrollbalken anhand von Spalten

BigMichi1

Neues Mitglied
Hallo,

ich versuche derzeit eine JTable zu erzeugen, mit 5 Spalten, jede Spalte hat eine minimale Breite gesetzt.
das Frame hat eine Breite von 400 am Anfang.

gewünschtes Verhalten wäre dies:
  • ist die Summe der minimalen Spaltenbreite < der Framebreite soll ein AutoResize aller Spalten durchgeführt werden ala JTable.AUTO_RESIZE_ALL_COLUMNS
  • ist die Summe der minimalen Spaltenbreite > der Framebreite soll der Scrollbalken angezeigt werden (Änderung kann entweder duch verkleinerung / vergrößerung des Frame geschehen oder durch Änderung der Splatenbreite im Header der Tabelle)
  • ist ein Scrollbalken vorhanden und wird das Frame vergrößert soll der Scrollbalken unter den obigen Bedingungen verschwinden oder angezeigt werden und beim verschwinden dann die Tabelle verbreitert werden wie bei JTable.AUTO_RESIZE_ALL_COLUMNS
  • ist kein Scrollbalken vorhanden soll auch wenn die Spalte manuell verbreitert wurde diese proportional mit geändert werden, als wenn diese Spalte eine neue minimale Breite hätte

Java:
package com.salt;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

public class Test extends JFrame {
    JTable jt = new JTable(20, 5);

    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final Container content = getContentPane();
        content.add(new JScrollPane(jt), BorderLayout.CENTER);
        jt.getTableHeader().addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(final ComponentEvent e) {
                final Container tableParent = jt.getParent();
                if (tableParent instanceof JViewport) {
                    final int oldMode = jt.getAutoResizeMode();
                    if (tableParent.getSize().getWidth() < jt.getPreferredSize().getWidth()) {
                        if (oldMode != JTable.AUTO_RESIZE_OFF) {
                            jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                        }
                    } else {
                        if (oldMode != JTable.AUTO_RESIZE_ALL_COLUMNS) {
                            jt.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
                        }
                    }
                }
            }
        });
        setSize(400, 400);
        for (int col = 0; col < jt.getModel().getColumnCount(); col++) {
            jt.getColumnModel().getColumn(col).setMinWidth(50);
        }
        setVisible(true);
    }

    public static void main(final String[] args) {
        new Test();
    }
}

soweit funktioniert auch einiges, nur hänge ich derzeit an dem Problem wenn eine Spalte im Header der Tabelle verbreitert wurde so dass ein Scrollbalken erscheint und man dann das Frame verbreitert (größer als die gesamte Breite der Tabelle), werden die Spalten nicht mehr verbreitert automatisch obwohl JTable.AUTO_RESIZE_ALL_COLUMNS gesetzt wird.

hat jemand für solch ein Problem eine Lösung parat oder weiß wo man da ansetzen kann?
 
Ich bin nicht sicher; willst Du einfach nur das da?

Java:
final JTable table = new JTable(5, 5) {

  @Override
  public boolean getScrollableTracksViewportWidth() {
    final Container p = getParent();
    if (p instanceof JViewport) {
      return (((JViewport) p).getWidth() > getPreferredSize().width);
    }

    return super.getScrollableTracksViewportWidth();
  }
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
final JScrollPane sp = new JScrollPane(table);
contentPane.add(sp);

final JFrame f = new JFrame("Test Frame: JViewportWidthTrackingTableFun");
f.setContentPane(contentPane);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
Ebenius
 
Das funktioniert zwar prinzipiell, doch hat diese Lösung den sehr unschönen Effekt das wenn die Spalten vergrößert werden per Maus ein hässliches flackern entsteht bzw. sich die Spalte erst gar nicht vergrößern lässt, da die Breite sofort auf den alten Wert zurückspringt
 
Da hast Du recht. Ist's so besser?

Java:
final JTable table = new JTable(5, 5) {

  @Override
  public void columnMarginChanged(ChangeEvent e) {
    final JTableHeader th = getTableHeader();
    TableColumn resizingCol = th == null ? null : th.getResizingColumn();
    if (resizingCol != null && autoResizeMode != AUTO_RESIZE_OFF) {
      final Dimension vpSize = getViewportSize();
      if (vpSize != null && vpSize.width <= getWidth()) {
        resizingCol.setPreferredWidth(resizingCol.getWidth());
      }
    }
    super.columnMarginChanged(e);
  }

  @Override
  public boolean getScrollableTracksViewportWidth() {
    final Dimension vpSize = getViewportSize();
    return vpSize != null
          ? vpSize.width >= getPreferredSize().width
          : super.getScrollableTracksViewportWidth();
  }

  private Dimension getViewportSize() {
    final Container p = getParent();
    return p instanceof JViewport ? p.getSize() : null;
  }
};

final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
final JScrollPane sp = new JScrollPane(table);
contentPane.add(sp);

final JFrame f = new JFrame("Test Frame: JViewportWidthTrackingTableFun");
f.setContentPane(contentPane);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
 

Zurück
Oben