简体   繁体   English

JTable:如何将单元格作为给定位置的组件

[英]JTable: How to get the cell as a component for a given position

I made an interactive Calendar as JTable, however, I would like to change the background colour for some of the cells based on data I have. 我创建了一个交互式日历作为JTable,但是,我想根据我拥有的数据更改某些单元格的背景颜色。 I figured out how I can get the position of the cell I need to edit but I have no idea how to get the cell at that position as a component so I can edit the cell background and foreground. 我想出了如何获得我需要编辑的单元格的位置,但我不知道如何将单元格作为一个组件放在该位置,这样我就可以编辑单元格背景和前景。

So basically I have the (x,y) position of the cell. 所以基本上我有单元格的(x,y)位置。 I want to use that and get the cell to change its background colour. 我想使用它并让细胞改变它的背景颜色。

This is how I create my calendar: 这就是我创建日历的方式:

public static JTable createInteractiveCalender(int month, int year) {       

    JTable calender =  new JTable(Calender.getMonthsCalender(month, year), new String[] {"Su","Mo","Tu","Wed","Th","Fri","Sat"}){
         public boolean isCellEditable(int row, int column) {                
                return false;               
        };
    };
    calender.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    calender.setCellSelectionEnabled(true);

    return calender;
}

This is how I get the dates I want to be marked: 这就是我得到我想要标记的日期的方式:

public static ArrayList<Date> getDatesInSpecificMonth(ArrayList<Date> allDates, int month) {

DateFormat df = new SimpleDateFormat("MM");
ArrayList<Date> dates = allDates;
for (Date d: dates)
    if(Integer.parseInt(df.format(d)) != month)
        dates.remove(d);
    return dates;
}

This is where I got stuck trying to mark the dates on the calendar: 这是我试图在日历上标记日期时遇到的问题:

public static void markDatesOnCalender(DefaultTableModel model, Section sec, int datesToMark, int month, int year) {
        ArrayList<Date> dates = Calender.getDatesInSpecificMonth(sec.getSelectedDatesforSection(datesToMark),month);
        DateFormat df = new SimpleDateFormat("dd");

        for (Date d: dates) {
            model.getValueAt(getCellPosition(model,df.format(d))[0],getCellPosition(model, d

f.format(d))[1]);



/*
         I have method that gets the cell position of 'd', however I need to get the                    
         */
        }                       
    //TODO 1
}

Thank you 谢谢

The cells of a JTable are not components in the conventional sense, ie you can't get them as child components of the JTable component. JTable的单元格不是传统意义上的组件,即您不能将它们作为JTable组件的子组件。

Instead, when the JTabel is rendered, for each cell a TableCellRenderer provides a JComponent which is used to paint that cell at the required position, in the method TableCellRenderer.getTableCellRendererComponent(...) . 相反,当渲染JTabel时, TableCellRenderer为每个单元格提供一个JComponent,用于在方法TableCellRenderer.getTableCellRendererComponent(...)将该单元格绘制在所需位置。

Note that the JComponent provided by TableCellRenderer.getTableCellRendererComponent(...) is not added to the component tree, but is used ad hoc to paint the corresponding table cell. 请注意, TableCellRenderer.getTableCellRendererComponent(...)提供的JComponent 添加到组件树中,而是专门用于绘制相应的表格单元格。 In fact, most TableCellRenderer implementations use the same component instance for all cells, setting anew the relevant properties (most notably the text to be displayed) for each cell. 实际上,大多数TableCellRenderer实现对所有单元使用相同的组件实例,重新设置每个单元的相关属性(最值得注意的是要显示的文本)。

So, in your case, what you have to do is to store the relevant properties that drive the coloring of the cells in the cell data, then use a custom TabelCellRenderer. 因此,在您的情况下,您需要做的是存储驱动单元格数据中单元格着色的相关属性,然后使用自定义TabelCellRenderer。 The renderer reads those properties and returns a JComponent which is configured based on those properties. 渲染器读取这些属性并返回基于这些属性配置的JComponent。

For example: The class Cell represents the content of your table cells. 例如: Cell类表示表格单元Cell的内容。 What class exactly you use here depends on the table model you want to use. 您在这里使用的是什么类取决于您要使用的表模型。 It could be as simple as String , but if you want to render your table cells based on some property, you need to use a table model based on a class which can hold that property, hence the custom class Cell : 它可以像String一样简单,但是如果你想根据某些属性渲染表格单元格,你需要使用一个基于类可以容纳该属性的表模型,因此自定义类Cell

class Cell{
   ...
   String text;
   boolean isHighlighted;
   ...
}

class MyTableCellRenderer implements TableCellRenderer{
    // cellLabel will be used to render each cell. Note that
    // this component is re-used for painting each cell, we
    // don't have separate instances for all cells.
    private JLabel cellLabel=new JLabel();

    @Override
    public Component getTableCellRendererComponent(
        JTable table,
        Object value,
        boolean isSelected,
        boolean hasFocus,
        int row,
        int column) {

        Cell cell=(Cell)value;
        cellLabel.setText(cell.getText());
        if(cell.isHighlighted)
            cellLabel.setForeground(Color.RED);
    }    
}         

Note that you have to set the TableCellRenderer , and you can do it for specific column classes: 请注意,您必须设置TableCellRenderer ,并且可以针对特定的列类执行此操作:

table.setDefaultRenderer(columnClass, renderer);

And lastly, once you have changed the properties of cells, you have to force a repaint of the JTable. 最后,一旦你改变了细胞的属性,就必须强制重新绘制JTable。 As @trashgod pointed out, when you correctly update your table model and notify its listeners, the JTable should repaint automatically (as it is a TableModelListener which registers with the model and listens for changes to the model). 正如@trashgod指出的那样,当您正确更新表模型并通知其监听器时,JTable应自动重新绘制(因为它是一个TableModelListener ,它注册模型并侦听模型的更改)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM