2013-04-30 156 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