Dynamically change the cell height in JTable with a GridBagLayout
I run into a problem where I have a JTable laid out using GridBagLayout manager and the number of rows in the table is not fixed. I intend to fill the space assigned to the table with all its cells, however there is a big blank (and white) space between the last row of the table and the next component in the container.
As a potential solution, I wonder if I can adjust the height of the cells to fill the space assigned to the table. So for example, if there are three rows, then the height of the space should be equally divided into three rows. If there is only one row, then this row should take up the whole space available.
Any suggestion are welcome, and if there is a better way to achieve the desired effect, please enlighten me. Thanks.
P.S. I am using JTable within a JPanel instead of a JScrollPane, if that makes any difference.
Edit: So I've tried the following code, which certainly adjusts height of the rows dep开发者_高级运维ending on the number of the rows present, but it still leaves a blank white space after the last row and before the next component. Wondering why?
// re-size the header and row height to fill the whole tPanel
int panelHeight = tPanel.getHeight();
int desiredRowHeight = panelHeight / (numOfRows + 1);
friendsInfo.getTableHeader().setPreferredSize(new Dimension(table.getColumnModel().getTotalColumnWidth(), desiredRowHeight));
table.setRowHeight(desiredRowHeight);
Yes you can. Just set the row heights. You would have to use something like here. Obviously I assume here that your panel has a 'constant' size. Otherwise the layout will make sure to resize it to appropriate size, i.e. table size.
If yes, then you can use the panel height for your calculations of the height each row should take.
EDIT1: Below is an example showing how it might be used to do so using GridBagLayout. I did all to make it look as best as possible though still it has a strange behaviour (for a short time it gets minimal size) when you making the frame smaller. But then again it might be default behaviour for the layout which I am not aware of.
NOTE: I am not an expert in using this layout manager (personally I hate it). Thus if there are some parameters which should/shouldn't be set please do let me know (and feel free to edit the answer).
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.JTableHeader;
public class TableRowResizeTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
final JTable table = new JTable(3,3);
final JTableHeader tHeader = table.getTableHeader();
final JPanel tPanel = new JPanel(new GridBagLayout());
tPanel.setBackground(Color.CYAN);
ComponentListener cL = new ComponentAdapter()
{
@Override
public void componentResized(ComponentEvent e)
{
super.componentResized(e);
// re-size the header and row height to fill the whole tPanel
int panelHeight = tPanel.getHeight();
int numOfRows = table.getRowCount();
int desiredRowHeight = panelHeight / (numOfRows + 1);
int gap = panelHeight - desiredRowHeight * (numOfRows + 1);
tHeader.setPreferredSize(new Dimension(tHeader.getPreferredSize().width,
desiredRowHeight+gap));
tHeader.revalidate();
tHeader.repaint();
if(desiredRowHeight <1)
desiredRowHeight = 1;
table.setRowHeight(desiredRowHeight);
table.revalidate();
table.repaint();
System.out.println("tPanel componentResized p.h="+tPanel.getHeight()
+"; desiredRowHeight="+desiredRowHeight+"; gap="+gap);
}
};
tPanel.addComponentListener(cL);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.VERTICAL;
c.gridx = 0;
c.gridy = 0;
c.weighty = 1.0;
tPanel.add(tHeader, c);
c.gridy = 1;
c.weighty = 0.0;
tPanel.add(table,c);
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBackground(Color.RED);
contentPane.add(tPanel);
JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println("before f.setVisible p.h="+tPanel.getHeight());
f.setVisible(true);
System.out.println("after f.setVisible p.h="+tPanel.getHeight());
}
});
}
}
精彩评论