2013-04-30 118 views
2

有很多时间,我试图在由Shanon Hickey,Romain Guy和Chris Campbell编写的JavaOne 2007的演讲中,在第38和39页(您可以在这里找到:http://docs.huihoo.com/javaone/2007/desktop/TS-3548.pdf)。我问过罗曼盖伊和克里斯坎贝尔,但没有成功,他们说他们不能榨取源代码。JTable:复杂单元格渲染器

那么,任何人都可以给出一个想法,甚至是如何使这个复杂的单元格渲染器的源代码? 我学到了很多次这样的幻灯片,他们说:

1)单元格渲染:跨列 视窗剪辑列内容 和 2)视口移至 露出右边的文本 为每列

我不明白,请你能给出更深入的解释吗?

干杯

+0

我觉得很多在幻灯片中的UI元素中可以找到这本书肮脏富有的客户。最后他们也提到它。绝对让它看起来。 – pek 2013-04-30 20:00:39

+0

我在2007年购买了这本书,我读过它,并且我可以说我已经记住了,本书只是解释了如何通过添加一些静态/动态效果,动画等来美化GUI,但它没有谈谈JTable或CellRenderer! – arafat877 2013-05-01 00:11:00

回答

2
  • Windows 7的
  • JDK 1.7.0_21

enter image description here

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class ComplexCellRendererTest { 
    private static boolean DEBUG = true; 
    private JRadioButton r1 = new JRadioButton("scrollRectToVisible"); 
    private JRadioButton r2 = new JRadioButton("setViewPosition"); 

    public JComponent makeUI() { 
    String[] columnNames = {"AAA", "BBB"}; 
    Object[][] data = { 
     {new Test("1", "aaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), "4"}, 
     {new Test("2", "1234567890\nabcdefghijklmdopqrstuvwxyz"), "5"}, 
     {new Test("3", "ccccccccccccccccccccccccccccccccccc\ndddddddddddd"), "6"}, 
    }; 
    DefaultTableModel model = new DefaultTableModel(data, columnNames) { 
     @Override public boolean isCellEditable(int row, int column) { 
     return false; 
     } 
    }; 
    final JTable table = new JTable(model); 
    table.getTableHeader().setReorderingAllowed(false); 
    table.setRowSelectionAllowed(true); 
    table.setFillsViewportHeight(true); 
    table.setShowVerticalLines(false); 
    table.setIntercellSpacing(new Dimension(0,1)); 
    table.setRowHeight(56); 
    for(int i=0; i<table.getColumnModel().getColumnCount(); i++) { 
     TableColumn c = table.getColumnModel().getColumn(i); 
     c.setCellRenderer(new ComplexCellRenderer()); 
     c.setMinWidth(50); 
    } 

    ActionListener al = new ActionListener() { 
     @Override public void actionPerformed(ActionEvent e) { 
     DEBUG = (e.getSource()==r1); 
     table.repaint(); 
     } 
    }; 
    Box box = Box.createHorizontalBox(); 
    ButtonGroup bg = new ButtonGroup(); 
    box.add(r1); bg.add(r1); r1.addActionListener(al); 
    box.add(r2); bg.add(r2); r2.addActionListener(al); 
    r1.setSelected(true); 

    JPanel p = new JPanel(new BorderLayout()); 
    p.add(box, BorderLayout.NORTH); 
    p.add(new JScrollPane(table)); 
    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 ComplexCellRendererTest().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 

    static class ComplexCellRenderer extends JPanel implements TableCellRenderer { 
    private final JTextArea textArea = new JTextArea(2, 999999); 
    private final JLabel label = new JLabel(); 
    private final JScrollPane scroll = new JScrollPane(); 
    public ComplexCellRenderer() { 
     super(new BorderLayout(0,0)); 

     scroll.setViewportView(textArea); 
     scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); 
     scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     scroll.setBorder(BorderFactory.createEmptyBorder()); 
     scroll.setViewportBorder(BorderFactory.createEmptyBorder()); 
     scroll.setOpaque(false); 
     scroll.getViewport().setOpaque(false); 
     textArea.setBorder(BorderFactory.createEmptyBorder()); 
     //textArea.setMargin(new Insets(0,0,0,0)); 
     textArea.setForeground(Color.RED); 
     textArea.setOpaque(false); 
     label.setBorder(BorderFactory.createMatteBorder(0,0,1,1,Color.GRAY)); 
     setBackground(Color.WHITE); 
     setOpaque(true); 
     add(label, BorderLayout.NORTH); 
     add(scroll); 
    } 
    @Override public Component getTableCellRendererComponent(
     JTable table, Object value, boolean isSelected, 
     boolean hasFocus, int row, int column) { 
     Test test; 
     if(value instanceof Test) { 
     test = (Test)value; 
     } else { 
     String title = value.toString(); 
     Test t = (Test)table.getModel().getValueAt(row, 0); 
     test = new Test(title, t.text); 
     } 
     label.setText(test.title); 
     textArea.setText(test.text); 
     Rectangle cr = table.getCellRect(row, column, false); 
     if(DEBUG) { 
     //Unexplained flickering on first row? 
     textArea.scrollRectToVisible(cr); 
     } else { 
     //Work fine for me (JDK 1.7.0_21, Windows 7 64bit): 
     scroll.getViewport().setViewPosition(cr.getLocation()); 
     } 
     if(isSelected) { 
     setBackground(Color.ORANGE); 
     } else { 
     setBackground(Color.WHITE); 
     } 
     return this; 
    } 
    } 


} 
class Test { 
    public final String title; 
    public final String text; 
    //public final Icon icon; 
    public Test(String title, String text) { 
    this.title = title; 
    this.text = text; 
    } 
} 
+1

'//textArea.scrollRectToVisible(cr); // JViewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);',或者有两种不同的模式 – mKorbel 2013-06-04 10:00:49

+1

@mKorbel感谢您的报告(对不起,没有足够的解释) 。使用'textArea.scrollRectToVisible(cr);':当我更改标题列的宽度时,第一行表格单元格中的文本会稍微移动一点。 'JViewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);'在我的环境中保持不变。 – aterai 2013-06-04 11:02:22

+1

不错的CellRenderer和...没有闪烁在这里:_MacOS 10.7.5与Java 1.7.0_21-B12和Windows 7与Java 1.7.0_21-b11_ – bobndrew 2013-06-12 09:05:25