如何调整JTable列以适应列单元格中最长的内容

我正在使用答案https://stackoverflow.com/a/5820366和http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/它可以工作,但是列的大小通常也是如此宽或太窄。

无论用HTML还是文本填充我的表格。

使用oracle文档中的标准TableModel

调整模式= JTable.AUTO_RESIZE_OFF

我的容器是jGoodies:

 FormLayout currentEventLayout = new FormLayout( "fill:p", "pref, pref"); PanelBuilder currentEventBuilder = new PanelBuilder(currentEventLayout); currentEventBuilder.add(mainQuotesTable.getTableHeader(), constraints.xy(1, 1)); currentEventBuilder.add(mainQuotesTable, constraints.xy(1, 2)); 

HTML示例:

 "
" + firstValue + "\n" + secondValue + "

"

简单的行:

 firstValue + " - " + secondValue 

这是一个例子:

 public class TableAdjustExample { private static JTable mainTable; private static Random random = new Random(); private static List data; private static class Data { String name; String surname; private Data(String name, String surname) { this.name = name; this.surname = surname; } } public static void main(String[] args) { data = stubProvider(); final JFrame frame = new JFrame("table adjust example"); frame.add(createUI()); frame.pack(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setSize(350, 400); frame.setVisible(true); update(); java.util.Timer timer = new java.util.Timer(); timer.schedule(new TimerTask() { @Override public void run() { update(); } }, 3000, 3000); } private static JPanel createUI() { JPanel jPanel = new JPanel(); mainTable = new JTable(2, 3); mainTable.setModel(new AbstractTableModel() { @Override public int getRowCount() { return data.size(); } @Override public int getColumnCount() { return 2; } @Override public Object getValueAt(int rowIndex, int columnIndex) { Data dataItem = data.get(rowIndex); if (columnIndex == 0) { return dataItem.name; } if (columnIndex == 1) { return dataItem.surname; } throw new IllegalStateException(); } }); mainTable.setGridColor(Color.black); mainTable.setShowHorizontalLines(false); mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer(); mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) { JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column); if (column == 0) { parent.setText("name"); } else { parent.setText("surname"); } return parent; } }); jPanel.add(mainTable.getTableHeader()); jPanel.add(mainTable); return jPanel; } private static void update() { System.out.println("updating"); data = stubProvider(); adjustJTableRowSizes(mainTable); for (int i = 0; i < mainTable.getColumnCount(); i++) { adjustColumnSizes(mainTable, i, 2); } } private static void adjustJTableRowSizes(JTable jTable) { for (int row = 0; row < jTable.getRowCount(); row++) { int maxHeight = 0; for (int column = 0; column < jTable.getColumnCount(); column++) { TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); Object valueAt = jTable.getValueAt(row, column); Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); int heightPreferable = tableCellRendererComponent.getPreferredSize().height; maxHeight = Math.max(heightPreferable, maxHeight); } jTable.setRowHeight(row, maxHeight); } } public static void adjustColumnSizes(JTable table, int column, int margin) { DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); TableColumn col = colModel.getColumn(column); int width; TableCellRenderer renderer = col.getHeaderRenderer(); if (renderer == null) { renderer = table.getTableHeader().getDefaultRenderer(); } JLabel comp = (JLabel) renderer.getTableCellRendererComponent( table, col.getHeaderValue(), false, false, 0, 0); width = comp.getPreferredSize().width; for (int r = 0; r < table.getRowCount(); r++) { renderer = table.getCellRenderer(r, column); comp = (JLabel) renderer.getTableCellRendererComponent( table, table.getValueAt(r, column), false, false, r, column); int currentWidth = comp.getPreferredSize().width; width = Math.max(width, currentWidth); } width += 2 * margin; col.setPreferredWidth(width); } private static List stubProvider() { List data = new ArrayList(); for (int i = 0; i < 4; i++) { data.add(new Data( "" + "
Jason
" + "
" + random.nextInt() + "
" + "", "Statham " + random.nextInt())); } return data; } }

行高调整我有这个问题。 使用

\n

代替
固定行调整。

似乎对我有用……

在此处输入图像描述

 public class TestTable01 extends JPanel { private JTable mainTable; public TestTable01() { super(new GridLayout(1, 0)); String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"}; Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)}, {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)}, {"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)}, {"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)}, {"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)} }; mainTable = new JTable(data, columnNames); mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); mainTable.setPreferredScrollableViewportSize(new Dimension(500, 70)); mainTable.setFillsViewportHeight(true); update(); //Create the scroll pane and add the table to it. JScrollPane scrollPane = new JScrollPane(mainTable); //Add the scroll pane to this panel. add(scrollPane); } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("SimpleTableDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. TestTable01 newContentPane = new TestTable01(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } private void update() { System.out.println("updating"); adjustJTableRowSizes(mainTable); for (int i = 0; i < mainTable.getColumnCount(); i++) { adjustColumnSizes(mainTable, i, 2); } } private void adjustJTableRowSizes(JTable jTable) { for (int row = 0; row < jTable.getRowCount(); row++) { int maxHeight = 0; for (int column = 0; column < jTable.getColumnCount(); column++) { TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); Object valueAt = jTable.getValueAt(row, column); Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); int heightPreferable = tableCellRendererComponent.getPreferredSize().height; maxHeight = Math.max(heightPreferable, maxHeight); } jTable.setRowHeight(row, maxHeight); } } public void adjustColumnSizes(JTable table, int column, int margin) { DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); TableColumn col = colModel.getColumn(column); int width; TableCellRenderer renderer = col.getHeaderRenderer(); if (renderer == null) { renderer = table.getTableHeader().getDefaultRenderer(); } Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0); width = comp.getPreferredSize().width; for (int r = 0; r < table.getRowCount(); r++) { renderer = table.getCellRenderer(r, column); comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, column), false, false, r, column); int currentWidth = comp.getPreferredSize().width; width = Math.max(width, currentWidth); } width += 2 * margin; col.setPreferredWidth(width); col.setWidth(width); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } } 

更新

您的示例存在许多问题。

  • 表真的应该添加到JScrollPane ,这将负责添加标题...
  • JPanel的默认布局管理器是FlowLayout ,在这种情况下,它可能不是你想要的,你可能想要使用BorderLayout
  • Swing不是线程安全的。 java.util.Timer的用户将违反此策略,这可能导致模型和视图失去同步。 请改用javax.swing.Timer
  • 在每个旁边渲染两个

    将导致html布局引擎在元素之间放置一个弱中断。 也就是说,如果引擎决定没有足够的可用空间将两个元素一起渲染,它将分割它们。 最好使用带有两个标签的单个

    代替......

我会读一读

  • Swing中的并发性
  • 如何使用表格

在此处输入图像描述

 public class TestColumnWidths { private static JTable mainTable; private static Random random = new Random(); private static List data; private static class Data { String name; String surname; private Data(String name, String surname) { this.name = name; this.surname = surname; } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { data = stubProvider(); final JFrame frame = new JFrame("table adjust example"); frame.add(createUI()); frame.pack(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); update(); // java.util.Timer timer = new java.util.Timer(); // timer.schedule(new TimerTask() { // @Override // public void run() { // update(); // } // }, 3000, 3000); javax.swing.Timer timer = new javax.swing.Timer(3000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { update(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); } }); } private static JPanel createUI() { JPanel jPanel = new JPanel(); mainTable = new JTable(2, 3); mainTable.setModel(new AbstractTableModel() { @Override public int getRowCount() { return data.size(); } @Override public int getColumnCount() { return 2; } @Override public Object getValueAt(int rowIndex, int columnIndex) { Data dataItem = data.get(rowIndex); if (columnIndex == 0) { return dataItem.name; } if (columnIndex == 1) { return dataItem.surname; } throw new IllegalStateException(); } }); mainTable.setGridColor(Color.black); mainTable.setShowHorizontalLines(false); mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer(); mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) { JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column); if (column == 0) { parent.setText("name"); } else { parent.setText("surname"); } return parent; } }); // jPanel.add(mainTable.getTableHeader()); // jPanel.add(mainTable); jPanel.setLayout(new BorderLayout()); jPanel.add(new JScrollPane(mainTable)); return jPanel; } private static void update() { System.out.println("updating"); data = stubProvider(); adjustJTableRowSizes(mainTable); for (int i = 0; i < mainTable.getColumnCount(); i++) { adjustColumnSizes(mainTable, i, 2); } } private static void adjustJTableRowSizes(JTable jTable) { for (int row = 0; row < jTable.getRowCount(); row++) { int maxHeight = 0; for (int column = 0; column < jTable.getColumnCount(); column++) { TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column); Object valueAt = jTable.getValueAt(row, column); Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column); int heightPreferable = tableCellRendererComponent.getPreferredSize().height; maxHeight = Math.max(heightPreferable, maxHeight); } jTable.setRowHeight(row, maxHeight); } } public static void adjustColumnSizes(JTable table, int column, int margin) { DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); TableColumn col = colModel.getColumn(column); int width; TableCellRenderer renderer = col.getHeaderRenderer(); if (renderer == null) { renderer = table.getTableHeader().getDefaultRenderer(); } Component comp = renderer.getTableCellRendererComponent( table, col.getHeaderValue(), false, false, 0, 0); width = comp.getPreferredSize().width; for (int r = 0; r < table.getRowCount(); r++) { renderer = table.getCellRenderer(r, column); comp = renderer.getTableCellRendererComponent( table, table.getValueAt(r, column), false, false, r, column); int currentWidth = comp.getPreferredSize().width; width = Math.max(width, currentWidth); } width += 2 * margin; col.setPreferredWidth(width); } private static List stubProvider() { List data = new ArrayList(); for (int i = 0; i < 4; i++) { data.add(new Data( "" + "
" + "Jason" + "" + random.nextInt() + "" + "
" + "", "Statham " + random.nextInt())); } return data; } }

为太窄的列设置合理的MinimumWidth。 然后根据列的内容计算宽度并设置它们。