自定义 TableCellRenderer 与 prepareRenderer 或如何解决行突出显示问题?
Custom TableCellRenderer vs. prepareRenderer or how to fix row highlighting issue?
简而言之:
这是关于什么的
我有一个带有模型的 JTable,它显示从 SAP 系统获取的数据。
我的目标是在特定列中仅显示模型中的部分数据。例如模型的行有 Object["a","b"] 但用户只应该看到 a。
所以我在 Whosebug 上阅读了很多主题以及很多关于如何使用自定义 tablecellrenderer 和编辑器等的教程,但我无法解决我的问题,即单元格我注册渲染器的地方在选择时不会突出显示。
描述了一个可能的解决方案 HERE 但这对我不起作用。
这是我的自定义渲染器:
public class SapChangeNumberCellRenderer extends DefaultTableCellRenderer{
private static final long serialVersionUID = -2649719064483586819L;
private SapChangeNumberTable table;
private int valuesSize;
public final static String ASM_AMOUNT = LanguageServer.getString("71", "Baugruppen");
public SapChangeNumberCellRenderer(SapChangeNumberTable table) {
super();
this.table = table;
}
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected,
final boolean hasFocus,
final int row, final int column) {
// components & Layout
JPanel panel = new JPanel(new BorderLayout());
JButton buttonDots = new JButton("...");
JLabel text = new JLabel();
List<String> values = (List<String>) value;
valuesSize = values.size();
if (valuesSize > 0) {
// set values
buttonDots.setPreferredSize(new Dimension(14, 14));
text.setText(values.get(0));
} else {
text.setText("");
}
if (valuesSize > 1) {
// button to open dialog only if we have more than 1 item
panel.add(buttonDots, BorderLayout.EAST);
}
panel.add(text, BorderLayout.WEST);
panel.setOpaque(true);
return panel;
}
@Override
public String getToolTipText(MouseEvent e) {
String toolTip = String.valueOf(valuesSize) + Initializer.SPACE + ASM_AMOUNT;
return toolTip;
}
public SapChangeNumberTable getTable() {
return table;
}
}
正如您所看到的,根据值的列表大小,我操纵将从该方法返回的组件。 setOpaque(true) 方法并没有达到我的目标。
这是相应的 JTabel(注意:BaseTable 只是 JTable 的包装器,带有一些我需要的好东西……这里没什么特别的)
public class SapChangeNumberTable extends BaseTable {
/** the model */
private SapChangeNumberTableModel model = new SapChangeNumberTableModel();
/** parent frame */
private SapPanel parent = null;
public SapChangeNumberTable(SapPanel parent) {
this.parent = parent;
this.init();
}
/**
* init the table
*/
private void init() {
// set model (not filled yet)
this.setModel(model);
// set renderer
setRendererAndEditor();
// add search filter row, enabling sorting is included
this.addFilterSearchRowPanel();
// single selection
this.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// hide
this.hideColumns();
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
/**
* sets the default table cell renderer
*/
private void setRendererAndEditor() {
getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
.setCellRenderer(new SapChangeNumberCellRenderer(this));
getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
.setCellEditor(new SapChangeNumberAsmRefTableCellEditor(this));
}
@Override
public void setStatusBarDataCount(boolean value) {
}
@Override
public void hideColumns() {
}
@Override
public int getColModelSortIndex() {
return 0;
}
@Override
public void load() {
}
@Override
public SapChangeNumberTableModel getModel() {
return model;
}
public boolean isChanging() {
return model.isFilling();
}
public SapFactoryChange getRow(int row) {
return model.getSapFactoryChange(row);
}
@Override
public void clear() {
model.clear();
}
@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);
if (vColIndex == SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER) {
//what the hack to do here to manipulate the comp ? I can't add a JPanel to a plain Component
}
return comp;
}
}
在 table 中,我用 prepareRenderer 尝试了一些东西,但在这里我无法操作数据(值)和我在自定义渲染器中做的所有其他事情。也许我对如何处理这个问题有一个基本的理解问题。感谢您提供任何提示!
我刚刚找到了一个非常简单的解决方案,我认为它会覆盖我想要的行为,但事实并非如此。
刚刚将其实施到 Table:
@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);
if (isRowSelected(rowIndex)) {
comp.setBackground(Color.ORANGE);
}
return comp;
}
工作起来很有魅力!
简而言之:
这是关于什么的
我有一个带有模型的 JTable,它显示从 SAP 系统获取的数据。 我的目标是在特定列中仅显示模型中的部分数据。例如模型的行有 Object["a","b"] 但用户只应该看到 a。
所以我在 Whosebug 上阅读了很多主题以及很多关于如何使用自定义 tablecellrenderer 和编辑器等的教程,但我无法解决我的问题,即单元格我注册渲染器的地方在选择时不会突出显示。 描述了一个可能的解决方案 HERE 但这对我不起作用。
这是我的自定义渲染器:
public class SapChangeNumberCellRenderer extends DefaultTableCellRenderer{
private static final long serialVersionUID = -2649719064483586819L;
private SapChangeNumberTable table;
private int valuesSize;
public final static String ASM_AMOUNT = LanguageServer.getString("71", "Baugruppen");
public SapChangeNumberCellRenderer(SapChangeNumberTable table) {
super();
this.table = table;
}
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected,
final boolean hasFocus,
final int row, final int column) {
// components & Layout
JPanel panel = new JPanel(new BorderLayout());
JButton buttonDots = new JButton("...");
JLabel text = new JLabel();
List<String> values = (List<String>) value;
valuesSize = values.size();
if (valuesSize > 0) {
// set values
buttonDots.setPreferredSize(new Dimension(14, 14));
text.setText(values.get(0));
} else {
text.setText("");
}
if (valuesSize > 1) {
// button to open dialog only if we have more than 1 item
panel.add(buttonDots, BorderLayout.EAST);
}
panel.add(text, BorderLayout.WEST);
panel.setOpaque(true);
return panel;
}
@Override
public String getToolTipText(MouseEvent e) {
String toolTip = String.valueOf(valuesSize) + Initializer.SPACE + ASM_AMOUNT;
return toolTip;
}
public SapChangeNumberTable getTable() {
return table;
}
}
正如您所看到的,根据值的列表大小,我操纵将从该方法返回的组件。 setOpaque(true) 方法并没有达到我的目标。
这是相应的 JTabel(注意:BaseTable 只是 JTable 的包装器,带有一些我需要的好东西……这里没什么特别的)
public class SapChangeNumberTable extends BaseTable {
/** the model */
private SapChangeNumberTableModel model = new SapChangeNumberTableModel();
/** parent frame */
private SapPanel parent = null;
public SapChangeNumberTable(SapPanel parent) {
this.parent = parent;
this.init();
}
/**
* init the table
*/
private void init() {
// set model (not filled yet)
this.setModel(model);
// set renderer
setRendererAndEditor();
// add search filter row, enabling sorting is included
this.addFilterSearchRowPanel();
// single selection
this.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
// hide
this.hideColumns();
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
/**
* sets the default table cell renderer
*/
private void setRendererAndEditor() {
getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
.setCellRenderer(new SapChangeNumberCellRenderer(this));
getColumnModel().getColumn(convertColumnIndexToView(SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER))
.setCellEditor(new SapChangeNumberAsmRefTableCellEditor(this));
}
@Override
public void setStatusBarDataCount(boolean value) {
}
@Override
public void hideColumns() {
}
@Override
public int getColModelSortIndex() {
return 0;
}
@Override
public void load() {
}
@Override
public SapChangeNumberTableModel getModel() {
return model;
}
public boolean isChanging() {
return model.isFilling();
}
public SapFactoryChange getRow(int row) {
return model.getSapFactoryChange(row);
}
@Override
public void clear() {
model.clear();
}
@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);
if (vColIndex == SapChangeNumberTableModel.COL_ID_SPM_ASM_NUMBER) {
//what the hack to do here to manipulate the comp ? I can't add a JPanel to a plain Component
}
return comp;
}
}
在 table 中,我用 prepareRenderer 尝试了一些东西,但在这里我无法操作数据(值)和我在自定义渲染器中做的所有其他事情。也许我对如何处理这个问题有一个基本的理解问题。感谢您提供任何提示!
我刚刚找到了一个非常简单的解决方案,我认为它会覆盖我想要的行为,但事实并非如此。
刚刚将其实施到 Table:
@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
Component comp = super.prepareRenderer(renderer, rowIndex, vColIndex);
if (isRowSelected(rowIndex)) {
comp.setBackground(Color.ORANGE);
}
return comp;
}
工作起来很有魅力!