JTable:如何将单元格作为给定位置的组件
JTable: How to get the cell as a component for a given position
我制作了一个交互式日历作为 JTable,但是,我想根据我拥有的数据更改某些单元格的背景颜色。我想出了如何获得我需要编辑的单元格的位置,但我不知道如何将该位置的单元格作为一个组件,以便我可以编辑单元格背景和前景。
所以基本上我有单元格的 (x,y) 位置。我想使用它并让单元格更改其背景颜色。
这是我创建日历的方式:
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;
}
这就是我获取要标记的日期的方式:
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;
}
这是我在日历上标记日期时遇到的问题:
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
}
谢谢
JTable 的单元格不是传统意义上的组件,即您不能将它们作为 JTable 组件的子组件。
相反,当呈现 JTabel 时,TableCellRenderer
为每个单元格提供一个 JComponent,用于在方法 TableCellRenderer.getTableCellRendererComponent(...)
.[=21= 中在所需位置绘制该单元格]
注意TableCellRenderer.getTableCellRendererComponent(...)
提供的JComponent
是不是添加到组件树中,而是用于临时绘制相应的 table 单元格。事实上,大多数 TableCellRenderer 实现对所有单元格使用相同的组件实例,为每个单元格重新设置相关属性(最值得注意的是要显示的文本)。
因此,在您的情况下,您要做的是存储驱动单元格数据中单元格着色的相关属性,然后使用自定义 TabelCellRenderer。渲染器读取这些属性和 returns 一个基于这些属性配置的 JComponent。
例如:class Cell
表示您的 table 单元格的内容。 class 您在这里具体使用什么取决于您要使用的 table 模型。它可以像 String
一样简单,但是如果你想根据一些 属性 渲染你的 table 单元格,你需要使用基于 [=] 的 table 模型39=] 可以容纳 属性,因此自定义 class 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);
}
}
请注意,您必须设置 TableCellRenderer
,您可以针对特定列 classes:
table.setDefaultRenderer(columnClass, renderer);
最后,一旦更改了单元格的属性,就必须强制重新绘制 JTable。正如@trashgod 指出的那样,当您正确更新 table 模型并通知其侦听器时,JTable 应该会自动重新绘制(因为它是一个 TableModelListener
,它向模型注册并侦听模型的更改) .
我制作了一个交互式日历作为 JTable,但是,我想根据我拥有的数据更改某些单元格的背景颜色。我想出了如何获得我需要编辑的单元格的位置,但我不知道如何将该位置的单元格作为一个组件,以便我可以编辑单元格背景和前景。
所以基本上我有单元格的 (x,y) 位置。我想使用它并让单元格更改其背景颜色。
这是我创建日历的方式:
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;
}
这就是我获取要标记的日期的方式:
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;
}
这是我在日历上标记日期时遇到的问题:
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
}
谢谢
JTable 的单元格不是传统意义上的组件,即您不能将它们作为 JTable 组件的子组件。
相反,当呈现 JTabel 时,TableCellRenderer
为每个单元格提供一个 JComponent,用于在方法 TableCellRenderer.getTableCellRendererComponent(...)
.[=21= 中在所需位置绘制该单元格]
注意TableCellRenderer.getTableCellRendererComponent(...)
提供的JComponent
是不是添加到组件树中,而是用于临时绘制相应的 table 单元格。事实上,大多数 TableCellRenderer 实现对所有单元格使用相同的组件实例,为每个单元格重新设置相关属性(最值得注意的是要显示的文本)。
因此,在您的情况下,您要做的是存储驱动单元格数据中单元格着色的相关属性,然后使用自定义 TabelCellRenderer。渲染器读取这些属性和 returns 一个基于这些属性配置的 JComponent。
例如:class Cell
表示您的 table 单元格的内容。 class 您在这里具体使用什么取决于您要使用的 table 模型。它可以像 String
一样简单,但是如果你想根据一些 属性 渲染你的 table 单元格,你需要使用基于 [=] 的 table 模型39=] 可以容纳 属性,因此自定义 class 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);
}
}
请注意,您必须设置 TableCellRenderer
,您可以针对特定列 classes:
table.setDefaultRenderer(columnClass, renderer);
最后,一旦更改了单元格的属性,就必须强制重新绘制 JTable。正如@trashgod 指出的那样,当您正确更新 table 模型并通知其侦听器时,JTable 应该会自动重新绘制(因为它是一个 TableModelListener
,它向模型注册并侦听模型的更改) .