我有一个从hibernate填充的Jtable。虽然表在jscrollpane中,但所有字段都填充得很好。我像这样设置表的dbData.setPreferredScrollableViewportSize:
dbData.setPreferredScrollableViewportSize(dbData.getPreferredSize());
dbScrollPane = new JScrollPane(null, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
dbScrollPane.getViewport().add(dbData);
Universalvars.setUpdatePane(dbScrollPane);
dbScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
dbScrollPane.setSize(750, 725);
dbScrollPane.setLocation(25, 0);
this.add(dbScrollPane);
现在用hibernate和mysql中的数据填充表后,我调整了每个列的宽度,这反过来又使得text中的textAreas变得更长,因为文本的高度需要更少的空间。执行此操作后,行不会调整大小。
现在有问题的表有15列。只有前7个在视口中可见,并且是1个衬里文本块。当我在Jscrollpane中滚动以查看较大的文本块单元格时,表格自动生成单元格的高度,尽管它仍然留下空白空白区域。
我希望这有意义,因为发布所有项目代码可能会非常过分。无论如何,有没有办法得到它,以便我可以将单元格设置在一定的宽度和行高度,以匹配他们应该保持正确数量的文本?就好像所有列在行中都有一行文本我不需要它高200 px,但如果有一行有一列有500个字符的文本和单元格,那就相同是300 px宽,然后整行需要更高。虽然它不需要具有容纳所述文本所需的空间量的两倍或三倍。
有什么想法吗?提前致谢。
答案 0 :(得分:1)
请勿使用getViewport().add(...)
,请使用getViewport().setView(...)
这是因为视口在概念上控制单个视图,并以特殊方式完成。
不要使用setSize
或setLocation
,这建议使用null
布局,这会导致在不同系统上运行时遇到问题,使用不同的字体和渲染管道。坚持使用布局管理API,它会让生活更简单
<强>更新强>
首先,不要在单元格渲染器中修改表格或模型的状态,这将设置一个严重的永无止境的更新。
其次,使用TableModelListener监视表状态的更改,使用TableColumnModelListener监视列模型的更改
当您检测到其中任何一个的更改时,您需要探测适当的单元格渲染器以确定其首选大小并相应地调整列/行大小。
请确保,由于您的调整引发的事件,您不会进行调整;)
更新了示例
这是一个非常基本的例子,可以尝试大致了解如何实现这一目标......
import java.awt.Color;
import java.awt.Component;
import static java.awt.Component.TOP_ALIGNMENT;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
public class VariableTable {
public static void main(String[] args) {
new VariableTable();
}
private JTable table;
private boolean ignoreUpdates;
public VariableTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
table = new JTable(loadTableModel());
table.getColumnModel().getColumn(2).setCellRenderer(new TextAreaRenderer());
table.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
updateTableProperties();
}
});
table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
@Override
public void columnAdded(TableColumnModelEvent e) {
updateTableProperties();
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
updateTableProperties();
}
@Override
public void columnMoved(TableColumnModelEvent e) {
updateTableProperties();
}
@Override
public void columnMarginChanged(ChangeEvent e) {
updateTableProperties();
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
});
updateTableProperties();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected void updateTableProperties() {
if (!ignoreUpdates) {
ignoreUpdates = true;
try {
for (int i = 0; i < table.getColumnCount() - 1; i++) {
adjustColumnSizes(i, 2);
}
adjustJTableRowSizes(2);
} finally {
ignoreUpdates = false;
}
}
}
private void adjustJTableRowSizes(int column) {
for (int row = 0; row < table.getRowCount(); row++) {
int maxHeight = 0;
TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
Object valueAt = table.getValueAt(row, column);
Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(table, valueAt, false, false, row, column);
DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
TableColumn tc = colModel.getColumn(column);
int heightPreferable = tableCellRendererComponent.getPreferredSize().height;
tableCellRendererComponent.setSize(tc.getWidth(), heightPreferable);
heightPreferable = tableCellRendererComponent.getPreferredSize().height;
maxHeight = Math.max(heightPreferable, maxHeight);
table.setRowHeight(row, maxHeight);
}
}
public void adjustColumnSizes(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);
// col.setMinWidth(width);
col.setMaxWidth(width);
}
public TableModel loadTableModel() {
DefaultTableModel model = new DefaultTableModel(
new String[]{"Chapter", "Paragraph", "Text"}, 0);
int chapter = 0;
int paragraph = 0;
try (BufferedReader br = new BufferedReader(new FileReader(new File("Book.txt")))) {
String text = null;
while ((text = br.readLine()) != null) {
if (text.startsWith("Chapter:")) {
chapter++;
paragraph = 0;
} else if (text.trim().length() > 0) {
paragraph++;
model.addRow(new Object[]{
chapter,
paragraph,
text
});
}
}
} catch (IOException exp) {
exp.printStackTrace();;
}
return model;
}
public static class TextAreaRenderer extends JTextArea implements TableCellRenderer {
protected static Border NOT_SELECTED_BORDER = new EmptyBorder(1, 1, 1, 1);
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
this.setAlignmentY(TOP_ALIGNMENT);
setBorder(NOT_SELECTED_BORDER);
setColumns(20);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
setText(value.toString());
if (table == null) {
return this;
}
Color fg = null;
Color bg = null;
JTable.DropLocation dropLocation = table.getDropLocation();
if (dropLocation != null
&& !dropLocation.isInsertRow()
&& !dropLocation.isInsertColumn()
&& dropLocation.getRow() == row
&& dropLocation.getColumn() == column) {
fg = UIManager.getColor("Table.dropCellForeground");
bg = UIManager.getColor("Table.dropCellBackground");
isSelected = true;
}
if (isSelected) {
setForeground(fg == null ? table.getSelectionForeground()
: fg);
setBackground(bg == null ? table.getSelectionBackground()
: bg);
} else {
Color background = table.getBackground();
if (background == null || background instanceof javax.swing.plaf.UIResource) {
Color alternateColor = UIManager.getColor("Table.alternateRowColor");
if (alternateColor != null && row % 2 != 0) {
background = alternateColor;
}
}
setForeground(table.getForeground());
setBackground(background);
}
setFont(table.getFont());
if (hasFocus) {
Border border = null;
if (isSelected) {
border = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
}
if (border == null) {
border = UIManager.getBorder("Table.focusCellHighlightBorder");
}
setBorder(border);
if (!isSelected && table.isCellEditable(row, column)) {
Color col;
col = UIManager.getColor("Table.focusCellForeground");
if (col != null) {
super.setForeground(col);
}
col = UIManager.getColor("Table.focusCellBackground");
if (col != null) {
super.setBackground(col);
}
}
} else {
setBorder(NOT_SELECTED_BORDER);
}
return this;
}
}
}