我正在项目中使用JTable。 我希望表将所有列自动调整为相同的大小,同时填充包含JScrollPane的宽度。
我不能只将首选宽度设置为固定值,因为当用户调整帧大小时,我希望所有列的大小调整为相同的大小,但是约束必须仍然填充100% JScrollPane。
例如,如果JScrollPane的宽度为1000,并且我有10列,我希望每个列的大小都为100。 如果JScrollPane然后缩小到500,我希望列的大小调整为50。
现在,我只设置JTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)
,结果如下:
我怎样才能做到这一点?
感谢。
答案 0 :(得分:3)
当表格改变大小时,您需要一些方法来更新列模型。
此基本示例使用invaldiate
方法更新其列模型。它还将列设置为“不可调整大小”。
这也会覆盖表getScrollableTracksViewportWidth
方法,以确保表自动填充水平空间。这意味着它永远不会显示水平滚动条。
public class SpringTable extends JTable {
public SpringTable(TableModel dm) {
super(dm);
setAutoResizeMode(AUTO_RESIZE_OFF);
}
public SpringTable() {
setAutoResizeMode(AUTO_RESIZE_OFF);
}
@Override
public void doLayout() {
int width = getWidth();
int columnCount = getColumnCount();
int columnSize = width / columnCount;
for (int index = 0; index < columnCount; index++) {
TableColumn column = getColumnModel().getColumn(index);
column.setResizable(false);
column.setPreferredWidth(width);
}
super.doLayout();
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
}
最好在doLayout
上使用invalidate
,但是你应该玩,看看有什么符合你的需求
运行示例
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
public class TestJTable {
public static void main(String[] args) {
new TestJTable();
}
public TestJTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
List<Pet> pets = new ArrayList<>(25);
pets.add(new Pet("Tyrannosauridae", "TYRANNOSAURUS", 20, 35));
pets.add(new Pet("Dromaeosauridae", "VELOCIRAPTOR", 45, 90));
pets.add(new Pet("Ceratopsidae", "TRICERATOPS", 15, 30));
pets.add(new Pet("Stegosauridae", "STEGOSAURUS", 22, 25));
pets.add(new Pet("Titanosauridae", "MALAWISAURUS", 22, 25));
pets.add(new Pet("Compsognathidae", "COMPSOGNATHUS", 8, 25));
pets.add(new Pet("Brachiosauridae", "BRACHIOSAURUS", 8, 25));
pets.add(new Pet("Diplodocidae", "DIPLODOCUS", 8, 25));
final PetTableModel model = new PetTableModel(pets);
final JTable table = new SpringTable(model);
InputMap im = table.getInputMap(JTable.WHEN_FOCUSED);
ActionMap am = table.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete");
am.put("delete", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
int[] indicies = table.getSelectedRows();
int[] mapped = new int[indicies.length];
for (int index = 0; index < indicies.length; index++) {
mapped[index] = table.convertRowIndexToModel(indicies[index]);
}
model.removePets(mapped);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SpringTable extends JTable {
public SpringTable(TableModel dm) {
super(dm);
setAutoResizeMode(AUTO_RESIZE_OFF);
}
public SpringTable() {
setAutoResizeMode(AUTO_RESIZE_OFF);
}
@Override
public void doLayout() {
int width = getWidth();
int columnCount = getColumnCount();
int columnSize = width / columnCount;
for (int index = 0; index < columnCount; index++) {
TableColumn column = getColumnModel().getColumn(index);
column.setResizable(false);
column.setPreferredWidth(width);
}
super.doLayout();
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
}
public class PetTableModel extends AbstractTableModel {
private List<Pet> pets;
public PetTableModel() {
pets = new ArrayList<>(25);
}
public PetTableModel(List<Pet> pets) {
this.pets = pets;
}
@Override
public int getRowCount() {
return pets.size();
}
public void removePets(int... indicies) {
List<Pet> old = new ArrayList<>(indicies.length);
for (int index : indicies) {
old.add(pets.get(index));
}
for (Pet pet : old) {
int index = pets.indexOf(pet);
pets.remove(pet);
fireTableRowsDeleted(index, index);
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
Class clazz = String.class;
switch (columnIndex) {
case 2:
case 3:
clazz = Float.class;
}
return clazz;
}
@Override
public String getColumnName(int column) {
String name = "??";
switch (column) {
case 0:
name = "Breed";
break;
case 1:
name = "Category";
break;
case 2:
name = "Buy Price";
break;
case 3:
name = "Sell Price";
break;
}
return name;
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Pet pet = pets.get(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = pet.getBreed();
break;
case 1:
value = pet.getCategory();
break;
case 2:
value = pet.getBuyPrice();
break;
case 3:
value = pet.getSellPrice();
break;
}
return value;
}
public void add(Pet pet) {
pets.add(pet);
fireTableRowsInserted(getRowCount() - 1, getRowCount() - 1);
}
}
public class Pet {
private String breed;
private String category;
private float buyPrice;
private float sellPrice;
public Pet(String breed, String category, float buyPrice, float sellPrice) {
this.breed = breed;
this.category = category;
this.buyPrice = buyPrice;
this.sellPrice = sellPrice;
}
public String getBreed() {
return breed;
}
public float getBuyPrice() {
return buyPrice;
}
public String getCategory() {
return category;
}
public float getSellPrice() {
return sellPrice;
}
}
}
答案 1 :(得分:1)
尽管我可以告诉JTable的默认行为(在Windows 7上使用JDK7),但是在更改表大小时,每个列的大小相同。只要您没有在表列上设置首选宽度,这似乎就可以工作。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class TestJTable {
public static void main(String[] args) {
new TestJTable();
}
public TestJTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
String[] columnNames = {"Column1", "a", "a long long column name", "column4"};
DefaultTableModel model = new DefaultTableModel(columnNames, 5);
final JTable table = new JTable(model);
JButton button = new JButton("Display Column Widths");
button.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int columnCount = table.getColumnCount();
for (int index = 0; index < columnCount; index++)
{
TableColumn column = table.getColumnModel().getColumn(index);
System.out.print(column.getWidth() + ", ");
}
System.out.println();
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
答案 2 :(得分:0)
调整JTable的大小后,您可以获得新的宽度(JTable.getWidth()),除以10(进行必要的调整以获得整数结果),然后手动设置每列的宽度(请参阅{{ 3}}帮助)。
答案 3 :(得分:0)
我在上一个项目中使用了这个!
addComponentListener(new ComponentListener() {
@Override public void componentShown(ComponentEvent e) {}
@Override public void componentMoved(ComponentEvent e) {}
@Override public void componentHidden(ComponentEvent e) {}
@Override
public void componentResized(ComponentEvent e) {
int w = table.getWidth() / table.getColumnCount();
for(int i = 0; i < table.getColumnCount(); i++) {
table.getColumn(i).setPreferredWidth(w);
}
}
});