我可以找到自定义TableCellRenderer的所有示例都显示为DefaultTableCellRenderer。我猜,没错,除了你没有扩展当前外观和感觉的TableCellRenderer
功能。这是不好的。那么你的TableCellRenderer
并不是L& F意识。
这实际上就是我想要做的事情:我想创建一个L& F意识的自定义TableCellRenderer
,所以不应该扩展DefaultTableCellRenderer
它应该扩展(或装饰)任何东西L& F默认为给定的类类型安装的TableCellRenderer
。
我可以通过myJTable.getDefaultRenderer(...)来做到这一点,但这不会给我一个新课程的实例,它只会让L& F' master'表格单元格渲染器用于该类型的类。我开始创建一个自定义TableCellRenderer的解决方案,它包装了我从上述方法中获得的实例(实际上使用了Decorator模式),直到我意识到我没有自己的渲染器私有实例。如果我弄乱了渲染器的这个实例,我不能进行特定于列的渲染,因为我在该实例上所做的任何更改都会影响比预期更多的列。
所以我得出结论,我需要做的是为该类型创建一个全新的L& F TableCellRenderer
实例。 (在我的例子中类类型= Object
)。我相信我可以从UIManager
的某处找到相关的班级名称,但我不知道要使用哪个键。其次 - 不幸的是 - 我相信我必须使用Reflection实际实例化该TableCellRenderer类的对象。
我的假设是否正确,即不幸的是没有TableCellRenderers的工厂?以及如何为类型TableCellRenderer
实际实例化当前L& F Object
的新实例? (我知道如何使用Reflection,如果这是唯一的方法)
您可能已经猜到我使用专有的L& F以及标准的L& F进行测试。这个特别的专有L& F安装了自己的TableCellRenderers,这是完全合法的IMO。 Java Synth L& F也是如此。所以我不想让这个问题成为一个特定的L& F.
测试:我创建了一个包含两个String
列的表。我在其中一列上安装了自己的自定义单元格渲染器,但没有在另一列上安装。我的自定义渲染器如下所示:
public class CustomCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
如您所见,自定义渲染器不执行任何操作。由于它什么都不做,我应该在两个表列上获得相同的渲染效果。我不是!原因当然是简单地延长DefaultTableCellRenderer
我不会继承' L& F自己的TableCellRenderers应该有一个/一个。在很多很多L& F上面,上述测试实际上会以相同的方式呈现两列,但这更偶然。我想以正确的方式做事。扩展DefaultTableCellRenderer
产生大多数L& Fs的预期结果这一事实对我来说还不够。 : - )
答案 0 :(得分:1)
我的假设是否正确,即不幸的是没有工厂 TableCellRenderers?我将如何实际实例化一个新的 类型对象的当前L& F的TableCellRenderer的实例? (我知道如何使用Reflection,如果这是唯一的方法)
我会说你的假设是关闭的,例如,以下屏幕截图使用完全相同的代码用于Cross平台/金属,系统/ MacOS和Nimbus(Synth)。
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class Test101 {
public static void main(String[] args) {
new Test101();
}
public Test101() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultTableModel model = new DefaultTableModel();
for (int index = 0; index < 10; index++) {
model.addColumn(Character.toString((char)('A' + index)));
}
for (int row = 0; row < 10; row++) {
Vector rowData = new Vector(10);
for (int col = 0; col < 10; col++) {
rowData.add(row + "x" + col);
}
model.addRow(rowData);
}
JTable table = new JTable(model);
table.setDefaultRenderer(String.class, new DefaultTableCellRenderer());
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer());
// Just so you don't tell me that the lookup doens't work
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
如果您从AbstractTableCellRenderer
或DefaultTableCellRenderer
延伸,则应使用JTable
及其属性(字体,颜色等)或UIManager
属性{} {{ 1}}没有为您提供所需的信息。
所以我得出结论,我需要做的是创造一个全新的 该类型的L&amp; F的TableCellRenderer的实例。 (在我的 case class type = Object)。我相信我可以上相关课程 从UIManager的某个地方命名,但我不知道哪个键 使用。其次 - 不幸的是 - 我相信我必须使用 实际实例化该TableCellRenderer的对象的反射 类。
如果您真的打算创建自己的外观,那么您只需要这样做。每天提供您自己的JTable
,这是根据提供的TableCellRenderer
的属性配置的,并且在极少数情况下,修改JTable
中存在的属性应该足够......
答案 1 :(得分:0)
我们这样解决了这个问题:
public class CustomCellRenderer implements TableCellRenderer {
//Use appropriate class here
private final TableCellRenderer defaultTableCellRenderer= new JTable().getDefaultRenderer(Object.class);
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component c = defaultTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// do custom stuff to c here ...
return c;
}
}
如果您没有为TableCellRenderer创建新实例,则可以获得时髦的效果,因为您更改了表的默认实例。