JTable 不断调用自定义单元格渲染器方法... [英] JTable Calls Custom Cell Renderer Method... Continuously
问题描述
可在以下位置找到可编译源:http://www.splashcd.com/jtable.tar一个>
Compilable source can be found at: http://www.splashcd.com/jtable.tar
我是该语言的新手,所以我不确定这是否可以接受.
I'm new to the language, so I'm not sure if this is acceptable behavior or not.
我创建了一个 JTable 来为收到的每条消息显示一行(它收到大约每 20 秒一次).表列之一可以包含大量文本,所以我创建了一个自定义单元格渲染器,它会自动换行并设置行相应的高度.
I created a JTable to display a row for each message received (it receives about one every 20 seconds). One of the table columns can contain a large amount of text, so I created a custom cell renderer which word wraps and sets the row height accordingly.
所有一切都按预期工作,除了一旦表格显示其第一行,它每秒调用单元格渲染器大约十次......直到用户关闭表.
All that works as expected, except that once the table displays its first row, it calls the cell renderer about ten times a second... until the user closes the table.
一旦我在那里得到大约 20 行,桌子就会变得相当缓慢,需要 2-8调整列大小、向上或向下滚动或使用选择的背景颜色.
Once I get approx 20 rows in there, the table gets fairly sluggish, taking 2-8 seconds to resize a column, scoll up or down, or render a selected row with the selected background color.
我在渲染器中插入了一个打印语句,所以我可以看到多少次正在调用 getTableCellRendererComponent 方法.
I inserted a print statement inside the renderer, so I can see how many times the getTableCellRendererComponent method is being called.
我禁用了工具提示,并禁用了所有单元格编辑.我确实有一个听众添加新行或表格时,将视图滚动到最后一行调整大小.
I disabled tool tips, and disabled all cell editing. I do have a listener that scrolls the view to the last row when either a new row is added or the table is resized.
getTableCellRendererComponent 方法是否应该每秒调用几次当我只是在查看屏幕(不触摸鼠标或键盘)时?
Should the getTableCellRendererComponent method be called several times a second when I'm just viewing the screen (not touching mouse or keyboard)?
TIA
推荐答案
aaaaach
aaaaach
你需要
doLayout()
,下一级:-),然后您也可以轻松地为
JTextComponents
设置最大可见行
snext level :-), then there you can to set
Maximum visible row
s forJTextComponents
too, with little effortdoLayout()
import java.awt.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.text.*; //http://tips4java.wordpress.com/2008/10/26/text-utilities/ public class AutoWrapTest { public JComponent makeUI() { String[] columnNames = {" Text Area Cell Renderer "}; Object[][] data = { {"123456789012345678901234567890"}, {"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"}, {"----------------------------------------------0"}, {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd" + "dddddddxdddddddddddddddddddddddddddddddddddddddddddddd" + "dddddddddddx>>>>>>>>>>>>>>>>>>>>>>>>>|"}, {">>>>>>>>>>>>ddddddddddddddddddddddddddddddddddddddddddddddddddd" + "ddddddx>>>>>>>>>>>>>>>>>>>>>>>>>>|"}, {"a|"}, {">>>>>>>>bbbb>>>>>>>>>>>>>>>>>>>|"}, {">>>>>>>>>>>>>>>>>>|"}, {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd" + "dddddddxdddddddddddddd123456789012345678901234567890dddddd" + "dddddddddddddddddddddddddddddddddddddx>>>>>>>>>>>>>>>>>>>>" + ">>>>>|"}, {">>>>>>>>>>>>>dddddddddddddd123456789012345678901234567890dddddd" + "dddddddddddddddddddddddddddddddddddddxdddddddddddddd123456" + "789012345678901234567890dddddddddddddddddddddddddddddddddd" + "ddddd123456789012345678901234567890ddddx>>>>>>>>>>>>>>>>>>" + ">>>>>>>|"},}; TableModel model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; @Override public boolean isCellEditable(int row, int column) { return false; } }; JTable table = new JTable(model) { private static final long serialVersionUID = 1L; @Override public void doLayout() { TableColumn col = getColumnModel().getColumn(0); for (int row = 0; row < getRowCount(); row++) { Component c = prepareRenderer(col.getCellRenderer(), row, 0); if (c instanceof JTextArea) { JTextArea a = (JTextArea) c; int h = getPreferredHeight(a) + getIntercellSpacing().height; if (getRowHeight(row) != h) { setRowHeight(row, h); } } } super.doLayout(); } private int getPreferredHeight(JTextComponent c) { Insets insets = c.getInsets(); View view = c.getUI().getRootView(c).getView(0); int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS); return preferredHeight + insets.top + insets.bottom; } }; table.setEnabled(false); table.setShowGrid(false); table.setTableHeader(null); table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer()); //table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane sp = new JScrollPane(table); sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); sp.setPreferredSize(new Dimension(250, 533)); JPanel p = new JPanel(new BorderLayout()); p.add(sp); return p; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new AutoWrapTest().makeUI()); f.setLocation(100, 100); f.pack(); f.setVisible(true); } } class TextAreaCellRenderer extends JTextArea implements TableCellRenderer { private static final long serialVersionUID = 1L; private final Color evenColor = new Color(230, 240, 255); public TextAreaCellRenderer() { super(); setLineWrap(true); setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); setBackground((row % 2 == 0) ? evenColor : getBackground()); } setFont(table.getFont()); setText((value == null) ? "" : value.toString()); return this; } }
这篇关于JTable 不断调用自定义单元格渲染器方法...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!