Ответ 1
Кажется, все будет хорошо для меня...
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 GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
ОБНОВЛЕНО
В вашем примере имеется ряд проблем.
- Таблицы действительно должны быть добавлены к
JScrollPane
, это позаботится о добавлении заголовка... - Диспетчер компоновки по умолчанию для
JPanel
-FlowLayout
, в этом случае он, вероятно, не тот, который вы хотите, вы, вероятно, захотите использоватьBorderLayout
- Swing не является потокобезопасным. Пользователь
java.util.Timer
нарушит эту политику, это может привести к сбою синхронизации модели и представления. Вместо этого используйтеjavax.swing.Timer
. - Рендеринг двух
<div>
рядом с каждым из них заставит механизм компоновки html помещать слабые разрывы между элементами. То есть, если двигатель решит, что недостаточно свободного места для визуализации двух элементов вместе, он будет разделять их. Лучше использовать один<div>
с двумя тегами<span>
...
Я бы прочитал
public class TestColumnWidths {
private static JTable mainTable;
private static Random random = new Random();
private static List<Data> 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<Data> stubProvider() {
List<Data> data = new ArrayList<Data>();
for (int i = 0; i < 4; i++) {
data.add(new Data(
"<html>"
+ "<div>"
+ "<span style='font-size: 15px'>Jason</span>"
+ "<span style='font-size: 15px'>" + random.nextInt() + "</span>"
+ "</div>"
+ "</html>",
"Statham " + random.nextInt()));
}
return data;
}
}