2012-07-10 103 views
3

我正在处理具有适合内容的行的表格。我将TableModelListener安装到表模型,以便无论何时添加新行,新添加的行的高度都会自动更改。这里是我的测试代码:使用JTable.setRowHeight不能正常工作更改行高度

final DefaultTableModel model = new DefaultTableModel(0, 1); 
final JTable table = new JTable(model); 
model.addTableModelListener(new TableModelListener() { 
    @Override 
    public void tableChanged(TableModelEvent e) { 
     // TO DO: replace 100 with the actual preferred height. 
     table.setRowHeight(e.getFirstRow(), 100); 
    } 
}); 

JButton button = new JButton("Add Row"); 
button.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     model.addRow(new String[] {"abc"}); 
    } 
}); 

我想到的是,当“添加行”按钮后,一个新行添加到表并具有100个像素的高度,但它不工作 - 行高度从不改变。一个离奇的事情是,JTable.setRowHeight方法可以正常工作,如果我移动呼叫按钮的动作侦听器,像这样:

button.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     model.addRow(new String[] {"abc"}); 
     talbe.setRowHeight(table.getRowCount() - 1, 100); 
    } 
}); 

当然我不能依靠这种“解决方案”,因为表的模型可以被改变其他地方。我是否正确使用TableModelListener或者这是一个错误?

+0

没有错误 - 只要记住,该表是听它的模型以及并相应地更新自己。该内部更新必须在客户端代码执行之前完成(这就是invokeLater的用途) – kleopatra 2012-07-10 09:09:21

回答

4

如何使用EventQueue.invokeLater(...)

model.addTableModelListener(new TableModelListener() { 
    @Override public void tableChanged(final TableModelEvent e) { 
    // TO DO: replace 100 with the actual preferred height. 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     table.setRowHeight(e.getFirstRow(), 100); 
     } 
    }); 
    } 
}); 
+0

可能是工作,很好的接球+1 – mKorbel 2012-07-10 06:42:10

+0

是的,它的工作原理!我仍然没有在这里使用'EventQueue.invokeLater',因为'tableChanged'方法已经在EDT上运行了。无论如何,非常感谢! – 2012-07-10 06:48:58

+0

我想你会发现将事件监听器外部的调用(通过稍后调用)会导致重绘管理器更新组件 - 因此建议尝试使用invalidate;但你有一个工作的解决方案 – MadProgrammer 2012-07-10 09:01:53

0

您是否在设置行高值后尝试使表格无效/重新绘制?

+0

JTable.setRowHeight方法将调用revalidate和repaint,所以这不应该是问题。 – 2012-07-10 06:17:59