如何使用Renderer for TableHeader [英] How to use Renderer for TableHeader

查看:65
本文介绍了如何使用Renderer for TableHeader的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使我通过@kleopatra阅读和测试答案




  • 的$ b

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

    公共类SelectedTableHeader {

    private JFrame frame = new JFrame(Table Demo);
    私有JTableHeader头;
    private Object selectedColumn = null;
    private String [] columnNames = {String,I​​nteger,Float,Double,Locale& Double,Boolean};
    private Object [] [] data = {
    {aaa,new Integer(12),new Float(12.15),new Double(100.05),new Double(12.05),true},
    {bbb,new Integer(5),new Float(7.154),new Double(6.1555),new Double(417.55),false},
    {CCC,new Integer(92), new Float(0.1135),new Double(3.1455),new Double(11.05),true},
    {ddd,new Integer(12),new Float(31.15),new Double(10.05),new Double (23.05),true},
    {eee,new Integer(5),new Float(5.154),new Double(16.1555),new Double(17.55),false},
    {fff ,new Integer(92),new Float(4.1135),new Double(31.1455),new Double(3.05),true}};
    private TableModel model = new DefaultTableModel(data,columnNames){

    private static final long serialVersionUID = 1L;

    @Override
    public Class<?> getColumnClass(int column){
    return getValueAt(0,column).getClass();
    }
    };
    private JTable table = new JTable(model);

    public SelectedTableHeader(){
    header = table.getTableHeader();
    header.addMouseListener(new MouseAdapter(){

    @Override
    public void mouseClicked(MouseEvent e){
    JTableHeader h =(JTableHeader)e.getSource() ;
    int i = h.columnAtPoint(e.getPoint());
    Object o = h.getColumnModel()。getColumn(i).getHeaderValue();
    if(i< 0){
    selectedColumn = null;
    return;
    }
    selectedColumn = o;
    h.requestFocusInWindow();
    }
    } );
    final TableCellRenderer hr = table.getTableHeader()。getDefaultRenderer();
    header.setDefaultRenderer(new TableCellRenderer(){

    private JLabel lbl;

    @Override
    public Component getTableCellRendererComponent(
    JTable table,对象值,boolean isSelected,boolean hasFocus,int row,int column){
    if(selectedColumn == value){
    lbl =(JLabel)hr.getTableCellRendererComponent(table,value,true,true,row ,列);
    lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory.createLineBorder(Color.red,1)));
    lbl.setHorizo​​ntalAlignment(SwingConstants.LEFT);
    } else {
    lbl =(JLabel)hr.getTableCellRendererComponent(table,value,false,false,row,column);
    lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory .createEmptyBorder(0,5,0,0)));
    lbl.setHorizo​​ntalAlignment(SwingConstants.CENTER);
    }
    if(column == 0){
    lbl.setForeground(Color.red);
    } else {
    lbl.setForeground(header.getForeground());
    }
    / * return(value == selectedColumn)? hr.getTableCellRendererComponent(
    table,value,true,true,row,column):hr.getTableCellRendererComponent(
    table,value,false,false,row,column); * /
    return lbl ;
    }
    });
    table.setRowHeight(20);
    table.setPreferredScrollableViewportSize(table.getPreferredSize());
    JScrollPane scroll = new JScrollPane(table);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(scroll);
    frame.pack();
    frame.setLocation(150,150);
    frame.setVisible(true);
    }

    public static void main(String [] args){
    EventQueue.invokeLater(new Runnable(){

    @Override
    public void run(){
    SelectedTableHeader selectedTableHeader = new SelectedTableHeader();
    }
    });
    }
    }


    解决方案

    In根据我的经验,当你覆盖任何 JTable Renderer DefaultTableCellHeaderRenderer C $ C>。因此,不要直接从 Renderer 中弄乱 JLabel ,而是抓住 Renderer with super()。因此,您的代码应如下所示:

      header.setDefaultRenderer(new DefaultTableCellHeaderRenderer(){


    @Override
    public Component getTableCellRendererComponent(
    JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column){
    DefaultTableCellHeaderRenderer rendererComponent =(DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent (table,value,isSelected,hasFocus,row,column);

    if(selectedColumn == value){
    rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(),BorderFactory。 createLineBorder(Color.red,1)));
    rendererComponent.setHorizo​​ntalAlignment(SwingConstants.LEFT);
    } else {
    rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(),BorderFactory .createEmptyBorder(0,5,0,0)));
    rendererC omponent.setHorizo​​ntalAlignment(SwingConstants.CENTER);
    }
    if(column == 0){
    rendererComponent.setForeground(Color.red);
    } else {
    rendererComponent.setForeground(header.getForeground());
    }

    返回rendererComponent;
    }
    });

    尝试直接回答您的问题:



    问题1:



    问:如何正确使用客户渲染器绘制JTable中的特定单元?



    答:您当前的代码是在 JTableHeader 上设置 Renderer 。要在表格单元格上添加渲染器,代码与上面的代码类似,只需通过Column模型设置:

      table.getColumnModel()。getColumn(0).setCellRenderer(new DefaultTableCellRenderer(){
    @Override
    public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column ){
    DefaultTableCellRenderer renderer =(DefaultTableCellRenderer)super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);

    //设置代码以渲染组件。

    返回渲染器;
    }

    });

    注意: JTables 是列 - 基于,这意味着某列中的所有数据必须是相同的类型(您的SSCCE遵循此约定)。我最喜欢的是为每种类型提供自定义 Renderer 。例如,每当我有一个 Date 列时,我就会使用这个渲染器:

      import java.awt.Component; 
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import org.joda.time.LocalDate;

    / **
    *
    * @author Ryan
    * /
    公共类DateCellRenderer extends DefaultTableCellRenderer {

    String pattern ;
    public DateCellRenderer(String pattern){
    this.pattern = pattern;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column){
    DefaultTableCellRenderer renderer =( DefaultTableCellRenderer)super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
    if(value!= null&& value instanceof LocalDate){
    renderer.setText(((LocalDate)value)。toString(pattern));
    } else
    抛出新的IllegalArgumentException(仅支持的对象类型是LocalDate。);

    返回渲染器;
    }
    }

    我用类似的代码调用此代码:

      table.getColumn(Date Entered)。setCellRenderer(new DateCellRenderer(MMM dd,yyyy)); 

    问题2:



    问:特别是一个表头颜色java swing



    A:嗯..你的SSCCE好像已经弄清楚了。



    问题3:



    问:关于super.getTableCellRendererComponent(...)必须是返回前的最后一行代码行,我不能通过这些建议写出正确的渲染器,因为我只能这样工作



    A:我不确定你的意思必须是最后一个代码退货前的一行。事实并非如此,我上面给出的代码片段证实了这一点



    问题4:



    问:为Borders,Horizo​​ntalAlignment和Foreground添加了JLabel,特别是背景通过使用Component而不是JLabel引起了一些非句子,(在某种程度上不重要)



    A:好的...... DefaultTableCellHeaderRenderer 足以满足所有这些,边框,路线,前景和背景。


    Even I read and test answers by @kleopatra

    from SSCCE

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class SelectedTableHeader {
    
        private JFrame frame = new JFrame("Table Demo");
        private JTableHeader header;
        private Object selectedColumn = null;
        private String[] columnNames = {"String", "Integer", "Float", "Double", "Locale & Double", "Boolean"};
        private Object[][] data = {
            {"aaa", new Integer(12), new Float(12.15), new Double(100.05), new Double(12.05), true},
            {"bbb", new Integer(5), new Float(7.154), new Double(6.1555), new Double(417.55), false},
            {"CCC", new Integer(92), new Float(0.1135), new Double(3.1455), new Double(11.05), true},
            {"ddd", new Integer(12), new Float(31.15), new Double(10.05), new Double(23.05), true},
            {"eee", new Integer(5), new Float(5.154), new Double(16.1555), new Double(17.55), false},
            {"fff", new Integer(92), new Float(4.1135), new Double(31.1455), new Double(3.05), true}};
        private TableModel model = new DefaultTableModel(data, columnNames) {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            public Class<?> getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        private JTable table = new JTable(model);
    
        public SelectedTableHeader() {
            header = table.getTableHeader();
            header.addMouseListener(new MouseAdapter() {
    
                @Override
                public void mouseClicked(MouseEvent e) {
                    JTableHeader h = (JTableHeader) e.getSource();
                    int i = h.columnAtPoint(e.getPoint());
                    Object o = h.getColumnModel().getColumn(i).getHeaderValue();
                    if (i < 0) {
                        selectedColumn = null;
                        return;
                    }
                    selectedColumn = o;
                    h.requestFocusInWindow();
                }
            });
            final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer();
            header.setDefaultRenderer(new TableCellRenderer() {
    
                private JLabel lbl;
    
                @Override
                public Component getTableCellRendererComponent(
                        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    if (selectedColumn == value) {
                        lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column);
                        lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createLineBorder(Color.red, 1)));
                        lbl.setHorizontalAlignment(SwingConstants.LEFT);
                    } else {
                        lbl = (JLabel) hr.getTableCellRendererComponent(table, value, false, false, row, column);
                        lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0)));
                        lbl.setHorizontalAlignment(SwingConstants.CENTER);
                    }
                    if (column == 0) {
                        lbl.setForeground(Color.red);
                    } else {
                        lbl.setForeground(header.getForeground());
                    }
                    /*return (value == selectedColumn) ? hr.getTableCellRendererComponent(
                    table, value, true, true, row, column) : hr.getTableCellRendererComponent(
                    table, value, false, false, row, column);*/
                    return lbl;
                }
            });
            table.setRowHeight(20);
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane scroll = new JScrollPane(table);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(scroll);
            frame.pack();
            frame.setLocation(150, 150);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    SelectedTableHeader selectedTableHeader = new SelectedTableHeader();
                }
            });
        }
    }
    

    解决方案

    In my experience, it's better to get the DefaultTableCellHeaderRenderer when you overwrite any JTable Renderer. So, instead of messing with the JLabel from the Renderer directly, you grab the Renderer with super(). So, your code should look like this:

    header.setDefaultRenderer(new DefaultTableCellHeaderRenderer() {
    
    
        @Override
        public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            DefaultTableCellHeaderRenderer rendererComponent = (DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
            if (selectedColumn == value) {
                rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createLineBorder(Color.red, 1)));
                rendererComponent.setHorizontalAlignment(SwingConstants.LEFT);
            } else {
                rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0)));
                rendererComponent.setHorizontalAlignment(SwingConstants.CENTER);
            }
            if (column == 0) {
                rendererComponent.setForeground(Color.red);
            } else {
                rendererComponent.setForeground(header.getForeground());
            }
    
            return rendererComponent;
        }
    });
    

    To try and answer your questions directly:

    Question 1:

    Q: How do I correctly use customer renderers to paint specific cells in a JTable?

    A: Your current code is setting a Renderer on the JTableHeader. To add a Renderer on your table cells would be similar code to what's above, only you'd set it through the Column model:

    table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
            // Set your code to render your component.
    
            return renderer;
        }
    
    });
    

    Note about this: JTables are column-based, which means that all the data in a certain column must be the same type (your SSCCE follows this convention). My favorite thing to do is to provide a custom Renderer for each type. For example, whenever I have a Date column, I use this renderer:

    import java.awt.Component;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import org.joda.time.LocalDate;
    
    /**
     *
     * @author Ryan
     */
    public class DateCellRenderer extends DefaultTableCellRenderer {
    
        String pattern;
        public DateCellRenderer(String pattern){
            this.pattern = pattern;
        }
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if (value != null && value instanceof LocalDate) {
                renderer.setText(((LocalDate)value).toString(pattern));
            } else
                throw new IllegalArgumentException("Only supported Object type is LocalDate.");
    
            return renderer;
        }
    }
    

    And I call this code with something similar:

    table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy"));
    

    Question 2:

    Q: particular one table header color java swing

    A: Umm.. Your SSCCE seems to have it figured out.

    Question 3:

    Q: about super.getTableCellRendererComponent(...) must be last code line before returns, I'm not able to write correct Renderer by those suggestion, for me works only this way

    A: I'm not sure what you mean "must be last code line before returns." That is not the case, proven by the code snip I gave above

    Question 4:

    Q: JLabel is added for Borders, HorizontalAlignment and Foreground, especially Background caused me a few non_senses by using Component instead of JLabel, (not important here somehow)

    A: Ok... the DefaultTableCellHeaderRenderer is sufficient for all of those, borders, alignment, foreground and background.

    这篇关于如何使用Renderer for TableHeader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆