JTable in JScrollpane adjusts the height of the displayed component

I have a jtable inside jscrollpane. I use the jgoodies form form and put scrollpane on a line that is set to "pref". Here's what the table looks like right now:

enter image description here

I use swingx JXTable and set visibleRowCount to 2. But only half of the line is displayed.

When creating SSCCE, I realized that it does not work properly, because I have a custom TextAreaRenderer. I think that because of this renderer, the line height is not calculated properly. I am trying to understand why, at the same time, if you guys can notice that it will be great ...

public static void main(String[] args) { JFrame frame=new JFrame(); JPanel panel=new FormDebugPanel(); frame.setContentPane(panel); FormLayout layout=new FormLayout("1dlu:grow,200dlu:grow,1dlu:grow", "10dlu,pref,5dlu,pref,10dlu"); panel.setLayout(layout); String[] columns= {"1st Column","2nd Column","3rd Column"}; String[][] data= { {"Sethu","Data","Something\nis\nhere"}, {"Sethu","Data","Something\nis\nhere"}, }; JXTable table=new JXTable(data,columns); table.setVisibleRowCount(2); TableColumnModel columnModel=table.getColumnModel(); columnModel.getColumn(2).setCellRenderer(new TextAreaRenderer()); JScrollPane scrlPan=new JScrollPane(table); CellConstraints cc=new CellConstraints(); panel.add(scrlPan, cc.xy(2, 2)); panel.add(new JLabel("Label After Table"),cc.xy(2,4)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } } 

And here is the visualization tool:

 class TextAreaRenderer extends JTextArea implements TableCellRenderer { private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer(); /** map from table to map of rows to map of column heights */ private final Map<JTable,Map<Integer,Map<Integer,Integer>>> cellSizes = new HashMap<JTable,Map<Integer,Map<Integer,Integer>>>(); public TextAreaRenderer() { setLineWrap(true); setWrapStyleWord(true); } public Component getTableCellRendererComponent(// JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) { // set the colours, etc. using the standard for that platform adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column); setForeground(adaptee.getForeground()); setBackground(adaptee.getBackground()); setBorder(adaptee.getBorder()); setFont(adaptee.getFont()); setText(adaptee.getText()); // This line was very important to get it working with JDK1.4 TableColumnModel columnModel = table.getColumnModel(); setSize(columnModel.getColumn(column).getWidth(), 100000); int height_wanted = (int) getPreferredSize().getHeight(); addSize(table, row, column, height_wanted); height_wanted = findTotalMaximumRowSize(table, row); if (height_wanted != table.getRowHeight(row)) { table.setRowHeight(row, height_wanted); } return this; } private void addSize(JTable table, int row, int column, int height) { Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table); if (rows == null) { cellSizes.put(table, rows = new HashMap<Integer,Map<Integer,Integer>>()); } Map<Integer,Integer> rowheights = rows.get(new Integer(row)); if (rowheights == null) { rows.put(new Integer(row), rowheights = new HashMap<Integer,Integer>()); } rowheights.put(new Integer(column), new Integer(height)); } /** * Look through all columns and get the renderer. If it is also a * TextAreaRenderer, we look at the maximum height in its hash table for * this row. */ private int findTotalMaximumRowSize(JTable table, int row) { int maximum_height = 0; Enumeration<TableColumn> columns = table.getColumnModel().getColumns(); while (columns.hasMoreElements()) { TableColumn tc = (TableColumn) columns.nextElement(); TableCellRenderer cellRenderer = tc.getCellRenderer(); if (cellRenderer instanceof TextAreaRenderer) { TextAreaRenderer tar = (TextAreaRenderer) cellRenderer; maximum_height = Math.max(maximum_height, tar.findMaximumRowSize(table, row)); } } return maximum_height; } private int findMaximumRowSize(JTable table, int row) { Map<Integer,Map<Integer,Integer>> rows = cellSizes.get(table); if (rows == null) return 0; Map<Integer,Integer> rowheights = rows.get(new Integer(row)); if (rowheights == null) return 0; int maximum_height = 0; for (Iterator<Map.Entry<Integer, Integer>> it = rowheights.entrySet().iterator(); it.hasNext();) { Map.Entry<Integer,Integer> entry = it.next(); int cellHeight = ((Integer) entry.getValue()).intValue(); maximum_height = Math.max(maximum_height, cellHeight); } return maximum_height; } } 

When I use TextAreaRenderer, then setVisibleRowHeight () is not executed properly. I think this is because you are not setting the line height in the renderer.

+4
source share
3 answers

With JXTable, you can configure how many rows (or columns) should be displayed initially:

  table.setVisibleRowCount(2) 

Here's a quick snippet showing how to set the initial size in terms of rows and dynamically update the pref height in TableModelListener

  final JXTable table = new JXTable(3, 5); table.setVisibleRowCount(table.getRowCount()); TableModelListener l = new TableModelListener() { @Override public void tableChanged(TableModelEvent e) { if (!(e.getType() == TableModelEvent.INSERT)) return; table.setVisibleRowCount(((TableModel) e.getSource()).getRowCount()); RootPaneContainer frame = (RootPaneContainer) SwingUtilities.windowForComponent(table); ((JComponent) frame.getContentPane()).revalidate(); } }; table.getModel().addTableModelListener(l); Action insert = new AbstractAction("add row") { @Override public void actionPerformed(ActionEvent e) { ((DefaultTableModel) table.getModel()).addRow(new Object[] {}); } }; new Timer(500, insert).start(); JComponent comp = new JPanel(new MigLayout()); comp.add(new JScrollPane(table)); JXFrame frame = wrapInFrame(comp, "visibleRowCount"); show(frame, frame.getPreferredSize().width, frame.getPreferredSize().height * 4); 
+4
source
 setPreferredScrollableViewportSize(Dimension) 

- this is what you should learn. and here is a good tutorial: How to use scrollbars

+2
source

I believe that to achieve this, you can use the preferredSize, minSize, and maxSize properties for JSCrollPane. If you choose preferredSize with the minimum size and maximum size you need, it should work.

+1
source

All Articles