2013-03-05 6 views
13

Ich muss eine JTable innerhalb von JScrollPane mit skalierbaren Spalten erstellen (wenn der Benutzer die Spaltenbreite erhöht - die horizontale Bildlaufleiste erscheint). Dazu verwende ich table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);. Wenn das Ansichtsfenster groß genug ist, um die gesamte Tabelle zu enthalten, sollten die Spalten gestreckt werden, um die Breite des Darstellungsbereichs zu füllen. Um dies zu erreichen I getScrollableTracksViewportWidth() Methode der Klasse JTable wie folgt außer Kraft setzen haben:Aktivieren der automatischen Größenanpassung von JTable nur, wenn es in das Ansichtsfenster passt

@Override 
public boolean getScrollableTracksViewportWidth() { 
    return getPreferredSize().width < getParent().getWidth(); 
} 

Dieser Ansatz funktioniert gut, bis auf eine Sache: wenn ich zum ersten Mal versuchen, Spalte, um die Größe eine eigene Breite zurückzukehren Position zu starten. Wenn ich die Größe der Spalte schnell verändere und die Maustaste loslasse, arbeite ich gut weiter. Also, was ist der Grund für ein solches Verhalten? Warum versucht die Tabelle zu skalieren, selbst wenn getScrollableTracksViewportWidth() false zurückgibt? Oder vielleicht können Sie eine bessere Lösung für die Implementierung eines solchen Größenänderungsmodus vorschlagen?

Bellow ist ein einfaches Ausführungsbeispiel von oben beschriebenen Problem:

import javax.swing.*; 

public class TestTable { 
    private static Object[][] data = new Object[][] { 
      { "a", "b", "c" }, 
      { "d", "e", "f" } 
    }; 
    private static Object[] colNames = new Object[] { "1", "2", "3" }; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JTable table = new JTable(data, colNames) { 
        @Override 
        public boolean getScrollableTracksViewportWidth() { 
         return getPreferredSize().width < getParent().getWidth(); 
        } 
       }; 
       table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

Antwort

17

Es schien wie die Standard-doLayout() Logik war nicht funktioniert, wenn Sie die Größe einer Spalte zu erhöhen versucht, wenn die horizontale Scrollbar nicht sichtbar war Also habe ich die Standardlogik losgeworden und einfach die Breite der Spalte akzeptiert, ohne sie anzupassen.

import javax.swing.*; 
import javax.swing.table.*; 

public class TestTable { 
    private static Object[][] data = new Object[][] { 
      { "a", "b", "c" }, 
      { "d", "e", "f" } 
    }; 
    private static Object[] colNames = new Object[] { "1", "2", "3" }; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JTable table = new JTable(data, colNames) 
       { 
        @Override 
        public boolean getScrollableTracksViewportWidth() 
        { 
         return getPreferredSize().width < getParent().getWidth(); 
        } 

        @Override 
        public void doLayout() 
        { 
         TableColumn resizingColumn = null; 

         if (tableHeader != null) 
          resizingColumn = tableHeader.getResizingColumn(); 

         // Viewport size changed. May need to increase columns widths 

         if (resizingColumn == null) 
         { 
          setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 
          super.doLayout(); 
         } 

         // Specific column resized. Reset preferred widths 

         else 
         { 
          TableColumnModel tcm = getColumnModel(); 

          for (int i = 0; i < tcm.getColumnCount(); i++) 
          { 
           TableColumn tc = tcm.getColumn(i); 
           tc.setPreferredWidth(tc.getWidth()); 
          } 

          // Columns don't fill the viewport, invoke default layout 

          if (tcm.getTotalColumnWidth() < getParent().getWidth()) 
           setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 
           super.doLayout(); 
         } 

         setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
        } 

       }; 
       table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

Bearbeitet, um AUTO_RESIZE_ALL_COLUMNS zu verwenden.

+0

Ausgezeichnet, funktioniert gut. – user2137020

+1

Siehe auch: http://stackoverflow.com/questions/15499255/jtable-with-autoresize-horizontal-crolling-and-shrinkable-first-column für eine andere Implementierung. – camickr

+0

Funktioniert wie ein Charme! Die einzige Lösung, die ich gefunden habe, um perfekt zu funktionieren. –

Verwandte Themen