java – JScrollpane中的JTable调整显示组件的高度
作者:互联网
我在jscrollpane中有一个jtable.我使用jgoodies表单布局并将滚动窗格放在一行设置为“pref”.这就是表格现在的样子:
我顺便使用swingx JXTable并将visibleRowCount设置为2.但是只显示了半行.
在制作SSCCE时,我意识到它无法正常工作,因为我有一个自定义的TextAreaRenderer.我认为由于这个渲染器,行高度没有正确计算.我想弄清楚为什么,与此同时,如果你们能发现它会很棒……
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);
}
}
这是渲染器:
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;
}
}
当我使用TextAreaRenderer时,setVisibleRowHeight()无法正确使用.我认为这与在渲染器中未正确设置行高度有关.
解决方法:
使用JXTable,您可以配置最初显示的行数(或列数):
table.setVisibleRowCount(2)
这是一个快速片段,展示了如何根据行设置初始大小并动态更新TableModelListener中的pref高度
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);
标签:java,swing,swingx,jgoodies 来源: https://codeday.me/bug/20190613/1235465.html