Java 如何为TableHeader使用渲染器

Java 如何为TableHeader使用渲染器,java,swing,jtable,tablecellrenderer,jtableheader,Java,Swing,Jtable,Tablecellrenderer,Jtableheader,甚至我也阅读并测试了@kleopatra的答案 关于super.gettableCellRenderComponent(…)必须是返回之前的最后一行代码,我无法根据这些建议编写正确的渲染器,对我来说只能这样工作 JLabel是为边框、水平对齐和前景添加的,尤其是使用组件而不是JLabel,背景使我产生了一些不感兴趣的感觉(不知何故,这里并不重要) 从 import java.awt.*; 导入java.awt.event.*; 导入javax.swing.*; 导入javax.sw

甚至我也阅读并测试了@kleopatra的答案

  • 关于
    super.gettableCellRenderComponent(…)
    必须是返回之前的最后一行代码,我无法根据这些建议编写正确的渲染器,对我来说只能这样工作

  • JLabel
    是为边框、水平对齐和前景添加的,尤其是使用组件而不是
    JLabel
    ,背景使我产生了一些不感兴趣的感觉(不知何故,这里并不重要)

import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.table.*;
公共类SelectedTableHeader{
私有JFrame=新JFrame(“表演示”);
私有JTableHeader;
私有对象selectedColumn=null;
私有字符串[]columnNames={“字符串”、“整数”、“浮点”、“双精度”、“区域设置和双精度”、“布尔值”};
私有对象[][]数据={
{“aaa”、新整数(12)、新浮点(12.15)、新双精度(100.05)、新双精度(12.05)、真},
{“bbb”、新整数(5)、新浮点(7.154)、新双精度(6.1555)、新双精度(417.55)、假},
{“CCC”,新整数(92),新浮点(0.1135),新双精度(3.1455),新双精度(11.05),真},
{“ddd”、新整数(12)、新浮点(31.15)、新双精度(10.05)、新双精度(23.05)、真},
{“eee”、新整数(5)、新浮点(5.154)、新双精度(16.1555)、新双精度(17.55)、假},
{“fff”、新整数(92)、新浮点(4.1135)、新双精度(31.1455)、新双精度(3.05)、真};
private TableModel model=新的DefaultTableModel(数据、列名){
私有静态最终长serialVersionUID=1L;
@凌驾
公共类getColumnClass(int列){
返回getValueAt(0,列).getClass();
}
};
专用JTable表=新JTable(模型);
public SelectedTableHeader(){
header=table.getTableHeader();
header.addMouseListener(新的MouseAdapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
JTableHeader h=(JTableHeader)e.getSource();
inti=h.columnAtPoint(如getPoint());
对象o=h.getColumnModel().getColumn(i).getHeaderValue();
if(i<0){
selectedColumn=null;
返回;
}
selectedColumn=o;
h、 requestFocusInWindow();
}
});
final TableCellRenderer hr=table.getTableHeader().getDefaultRenderer();
header.setDefaultRenderer(新的TableCellRenderer(){
私人JLabel-lbl;
@凌驾
公共组件GetTableCellRenderComponent(
JTable表,对象值,布尔值为选定值,布尔值为焦点,整数行,整数列){
如果(selectedColumn==值){
lbl=(JLabel)hr.getTableCellRenderComponent(表、值、真、真、行、列);
setboorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory.createLineBorder(Color.red,1));
lbl.设置水平对齐(左摆角);
}否则{
lbl=(JLabel)hr.getTableCellRenderComponent(表、值、false、false、行、列);
setboorder(BorderFactory.createCompoundBorder(lbl.getBorder(),BorderFactory.createEmptyBorder(0,5,0,0));
lbl.设置水平对齐(旋转约束中心);
}
如果(列==0){
lbl.设置前景(颜色为红色);
}否则{
set前台(header.get前台());
}
/*返回(值==selectedColumn)?hr.getTableCellRenderComponent(
表,值,真,真,行,列):hr.getTableCellRenderComponent(
表、值、假、假、行、列)*/
返回lbl;
}
});
表2.设置行高(20);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scroll=新的JScrollPane(表);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(滚动);
frame.pack();
帧设置位置(150150);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
SelectedTableHeader SelectedTableHeader=新建SelectedTableHeader();
}
});
}
}

我过去曾遇到过这种情况,我确信这与单元格渲染器有关,但
ArraysXxxException
类异常一直困扰着我,因为我忘记了在添加/删除行之前取消选择并停止编辑单元格。您应该尝试
clearSelection()
table.getCellEditor().stopCellEditing()JTable
上添加code>,看看这是否解决了您的问题

当然,首先要确保它正在编辑:

if (table.isEditing()) {
    table.getCellEditor().stopCellEditing();
}

根据我的经验,在覆盖任何
JTable
渲染器时,最好使用
DefaultTableCellHeaderRenderer
。因此,与直接从
渲染器
中处理
JLabel
不同,您可以使用
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.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;
    }
});
要尝试直接回答您的问题,请执行以下操作:

问题1:

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

答:您当前的代码正在
JTableHeader
上设置一个
渲染器。在表格单元格中添加渲染器的代码与上面的代码类似,只需通过列模型进行设置:

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;
    }

});
请注意:
JTables
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;
    }

});
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;
    }
}
table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy"));