天道酬勤,学无止境

Using TableCellRenderer and getColumnClass together

when i add getcolumn class to my abstracttablemodel, i couldnt use my custom TableCellRenderer to set background color. (i use this for sorting,alignment numeric columns)

public Class getColumnClass(int columnIndex) {
        Object o = getValueAt(0, columnIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }

This is full of my code.

import java.awt.*;
import java.text.DecimalFormat;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.table.*;

public class DemoRenderer extends JFrame {

    public static void main( String[] args ) {
        DemoRenderer frame = new DemoRenderer();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible( true );
    }

    public DemoRenderer() {

                JTable table = new JTable();
                table.setModel(new MyTablemodel());
                table.setDefaultRenderer(Object.class, new MyCustomTableCellRenderer());

                // Tell the table what to use to render our column of doubles

                table.repaint();
                //table.getColumnModel().getColumn(1).setCellRenderer(new DecimalFormatRenderer() );                
        getContentPane().add(new JScrollPane(table));
    }

}

/**
         Here is our class to handle the formatting of the double values
         */

class MyCustomTableCellRenderer extends DefaultTableCellRenderer{

    private static final DecimalFormat formatter = new DecimalFormat( "#0.00" );

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

        if(column==1) obj = formatter.format((Number)obj);        
        Component cell = super.getTableCellRendererComponent(
            table, obj, isSelected, hasFocus, row, column);
    if (isSelected) {
    cell.setBackground(Color.green);
    } 
    else {
    if (row % 2 == 0) {
    cell.setBackground(Color.cyan);
    }
    else {
    cell.setBackground(Color.lightGray);
    }
    }    
    return cell; 
    }
}

class MyTablemodel extends AbstractTableModel{

    Object[] columnNames = { "A", "B", "C" };
    Object[][] data = {
    { "1abc", new Double(850.503), 53 },
    { "2def", new Double(36.23254), 6 },
    { "3ghi", new Double( 8.3 ), 7 },
    { "4jkl", new Double( 246.0943 ), 23 }};

    @Override
    public int getRowCount() {
        return data.length;
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return data[rowIndex][columnIndex];
    }


    public Class getColumnClass(int columnIndex) {
        Object o = getValueAt(0, columnIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }

}

thank you very much for your opinions.

评论

Your getColumnClass() method will return: String.class, Double.class and Integer.class for columns 0, 1, 2.

JTable will provide the default renderer for the Double and Integer columns.

If you want to use your custom renderer for all your columns then you need to do:

MyCustomTableCellRenderer renderer = new MyCustomTableCellRenderer();
table.setDefaultRenderer(Object.class, renderer); // or you could use "String.class"
table.setDefaultRenderer(Double.class, renderer);
table.setDefaultRenderer(Integer.class, renderer);

When you use "Object.class" it means use the Object renderer as a last resort renderer, only if no other custom renderer for the specific class has been added to the table.

Use TableColumn#setCellRenderer() to draw individual values for each column.

Just add below lines in your code

MyCustomTableCellRenderer cellRenderer = new MyCustomTableCellRenderer();
for (int i = 0; i < table.getColumnCount(); i++) {
    table.getColumnModel().getColumn(i).setCellRenderer(cellRenderer);
}

instead of

table.setDefaultRenderer(Object.class, new MyCustomTableCellRenderer());

and your problem will be solved.

Note: You are using DefaultTableCellRenderer that will apply on cell hence use setCellRenderer() instead of setDefaultRenderer().

screenshot: (one row is selected)

enter image description here

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何将图像插入JTable单元格(How to Insert Image into JTable Cell)
    问题 有人可以向我指出如何向Java Table单元中添加图像的正确方向。 回答1 JTable已经为图标提供了默认的渲染器。 您只需要告诉表在给定列中存储了哪些数据,以便它可以选择适当的渲染器。 这是通过重写getColumnClass(...)方法来完成的: import java.awt.*; import javax.swing.*; import javax.swing.table.*; public class TableIcon extends JPanel { public TableIcon() { Icon aboutIcon = new ImageIcon("about16.gif"); Icon addIcon = new ImageIcon("add16.gif"); Icon copyIcon = new ImageIcon("copy16.gif"); String[] columnNames = {"Picture", "Description"}; Object[][] data = { {aboutIcon, "About"}, {addIcon, "Add"}, {copyIcon, "Copy"}, }; DefaultTableModel model = new DefaultTableModel(data, columnNames) {
  • JTable 中的日期排序无效(Invalid sorting on Date in JTable)
    问题 请看下面的代码 import java.awt.*; import java.awt.event.*; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; import javax.swing.table.*; public class TableBasic extends JFrame { public TableBasic() { String[] columnNames = {"Date", "String", "Long", "Boolean"}; Object[][] data = { {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE }, {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE}, {getJavaDate("12-11-2015"), "C", new Long
  • 如何为 JTable 中的特定行着色(How to color specific rows in a JTable)
    问题 我希望能够突出显示JTable某些行,具体取决于行本身中的值。 例如,如果现有数量< reorder level ,则该行应在JTable突出显示。 我知道有一个表格方法tblItems.setSelectionBackground(Color.yellow); 这在选择行时有效,但是是否有类似的方法不依赖于选择的行以不同的颜色显示它们? public class MyTableCellRenderer implements TableCellRenderer { @Override public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Object ob=table.getValueAt(row, column); if(ob.toString().equals("yes")){ //need to colour the entire row } return } } 回答1 您可以使用我的答案来更改单元格的颜色。 可以使用相同的技术将其应用于行中的每个单元格。 这也是prepareRenderer例子 import javax.swing.*
  • TableCellRenderer以及如何在不使用JTable.repaint()的情况下刷新单元格背景(TableCellRenderer and how to refresh Cell background without using JTable.repaint())
    问题 可以根据外部的值正确刷新背景,而无需强制重新绘制table.repaint(); 基于kleopatra和Hovercraft Full Of Eels编写的出色代码进行了基础,使用和测试对Java6 / 7有效,因为API没有任何更改 我的SSCCE正常工作,由JTable.repaint()重新绘制 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.GridLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table
  • 带有数据类型不同的单元格的Jtable(Jtable with different types of cells depending on data type)
    问题 如何根据特定行显示的输入类型,用不同类型的单元格编辑器实现JTable? 例如 有些行可能是复选框(对于布尔类型) 有些行可能是组合框(如果我想提供一组固定的选项供您选择) 有些行可能是文本字段(如果我允许任意数据)。 目前,我已经实现了AbstractTableModel ,该模型从我的对象中获取一组自定义字段对象,并将行添加到表中。 我想通过设置特定类型的单元格来进一步自定义表格。 我可以根据行包含的字段类型来确定要使用的单元格类型。 该表模型是在运行时动态创建的。 回答1 有些行可能是复选框(对于布尔类型) 有些行可能是组合框(如果我想提供一组固定的选项供您选择) 有些行可能是文本字段(如果我允许任意数据)。 例如 import java.awt.EventQueue; import java.util.Date; import javax.swing.JFrame; import static javax.swing.JFrame.EXIT_ON_CLOSE; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; public
  • 如何使 JTable 列包含复选框?(How to make JTable column contain checkboxes?)
    问题 前言:我对 java 很糟糕,对 java ui 组件更糟。 我找到了几个关于如何向表格添加按钮的不同教程,但是我正在努力添加复选框。 我需要有一列绘制一个默认勾选的文本框(我认为单元格渲染器可以处理),然后点击勾选框,取消勾选框,重绘所述框,并在我可以跟踪的地方触发一个事件。 目前我有一个自定义的 cellrenderer: public class GraphButtonCellRenderer extends JCheckBox implements TableCellRenderer { public GraphButtonCellRenderer() { } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if(isSelected) setSelected(true); else setSelected(false); setMargin(new Insets(0, 16, 0, 0)); setIconTextGap(0); setBackground(new Color(255,255,255,0)); return this; }}
  • 有没有像 JTable 中的 getColumnClass 这样的方法来设置行特定的数据类型?(Is there any method like getColumnClass in JTable to set row specific data types?)
    问题 我有一个带有两列的 JTable:一个键名和一个值。 在值列中允许多种数据类型,如下图所示: 所以在第 1 列中,我可能在第 1 行有一个布尔值,在第 2 行有一个字符串。但是getColumnClass(...)方法只允许我为完整列设置数据类型。 有没有办法设置列行特定的数据类型? 问候,神话 回答1 同一列不能有两种数据类型。 但是对于您的情况,我的建议是使用渲染。 阅读有关编辑器和渲染器的信息。 将列数据类型定义为包含JPanel的组件类。 渲染列。 您的 Renderer 类将面板返回到该列。 它应该有一个constraint ,基于你应该将组件添加到面板并返回面板。 这个例子展示了如何在这些情况下使用渲染。 class PanelCellRenderer extends JPanel implements TableCellRenderer { public Component getTableCellRendererComponent(final JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // row number is used as a constraint. if(row == 0) { this.add( new
  • TableCellRenderer and how to refresh Cell background without using JTable.repaint()
    is possible to refresh background based on value from outside correctly, without to force for repaint table.repaint(); Based, used and tested with great code made by kleopatra and Hovercraft Full Of Eels valid for Java6/7, because there weren't any changes in APIs my SSCCE works correctly, repainted by JTable.repaint() import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.GridLayout; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax
  • 仅一个 JTable 单元格中的复选框(Checkbox in only one JTable Cell)
    问题 我想创建一个带有 2 列的JTable ,它看起来像一个调查。 所以左边是问题,右边是用户可以给出他的答案。 但是在一行的右侧应该有一个复选框,以便用户只能回答是或否。 这可能与JTable ,我该如何实现? 问候 回答1 您在评论中表示: 我用一列 JCheckboxes 尝试过它可以工作,但我只想要它在一个单元格中 请注意,此要求有点棘手。 我认为你可以覆盖 getCellRenderer(int row, int column) 和 getCellEditor(int row, int column) 方法来询问单元格值的类。 这样,即使表格的行已排序或表格的列重新排列,单元格渲染器/编辑器也将是JCheckbox 。 像这样的东西: JTable table = new JTable(model) { @Override public TableCellRenderer getCellRenderer(int row, int column) { if(getValueAt(row, column) instanceof Boolean) { return super.getDefaultRenderer(Boolean.class); } else { return super.getCellRenderer(row, column); } } @Override
  • JTable:按整数排序(JTable: sorting by Integer)
    问题 我有一个JTable,我想有时按整数(大小列),有时按字符串(文件路径)对行进行排序。 因此,我在Google上进行了搜索,并且已经到达了这里。 我知道我必须重写DefaultTableModel方法,称为getColumnClass 。 所以我在这里链接我的代码。 class Personal_model extends DefaultTableModel{ Personal_model(String[][] s,String[] i){ super(s,i); } @Override public Class<?> getColumnClass(int columnIndex){ if (columnIndex!=2) return String.class; else return Integer.class; } } 这里是由模型“ Personal_model”创建表的代码; 我也设置rowsorter。 但是所有这些都不起作用!!!!! 帮帮我 modeltable = new Personal_model(data,col); table = new JTable(modeltable); table.setRowSorter(new TableRowSorter<Personal_model>(modeltable)); 正常情况下,没有我的排序器
  • 如何在 JTable 中呈现复选框?(How to render a checkbox in a JTable?)
    问题 这是我渲染 JTable 并更改行颜色的代码,但它在第 6 列中没有显示复选框,只有字符串 (true,false)。 你能提供解决这个问题的解决方案吗? 提前致谢。 public class JLabelRenderer extends JLabel implements TableCellRenderer { private MyJTable myTable; /** * Creates a Custom JLabel Cell Renderer * @param t your JTable implmentation that holds the Hashtable to inquire for * rows and colors to paint. */ public JLabelRenderer(MyJTable t) { this.myTable = t; } /** * Returns the component used for drawing the cell. This method is * used to configure the renderer appropriately before drawing. * see TableCellRenderer.getTableCellRendererComponent(...); for more
  • 为 JTable 中的 JCheckBox 单元格设置颜色(Setting the color for a JCheckBox cell in a JTable)
    问题 我有一个 JCheckBox 在 JTable 的最后一列中工作。 但是当我为该列中的单元格设置颜色时,它似乎覆盖了渲染对象(JCheckBox)。 下面的代码片段是我想要做的: //Overriding these methods using the DefaultTableModel constructor works . DefaultTableModel model = new DefaultTableModel(data, columnNames) { @Override public Class getColumnClass(int col) { return getValueAt(1, col).getClass(); } @Override public boolean isCellEditable(int rowIndex, int colIndex) { return (colIndex == CHECK_COL); } }; JTable table = new JTable(model); //Constructing and setting a render background and foreground color DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(
  • 试图从mysql到jtable检索文本和blob(trying to retrieve both text and blob from mysql to jtable)
    问题 因此,我试图以一种不错的方式从jtable内的数据库中检索文本和blob(image)。 出于某种原因,每当我尝试检索blob时,我都会得到以下信息: java.io.ByteArrayInputStream@1cb63183 在所有其他列中,尽管我已指定blob在8号上! 这是屏幕截图: http://s24.postimg.org/t71o3izlh/Screen_Shot_2016_01_28_at_1_26_55_PM.png 这是我的代码 sql = "SELECT * FROM Products"; ResultSet rs = stmt.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); // getting the columns number int columnsNumber = rsmd.getColumnCount(); // setting a vector with columns number Vector columns = new Vector(columnsNumber); // adding column names for(int i=1; i<=columnsNumber; i++) columns.add(rsmd.getColumnName(i)); //
  • Table Cell renderer using Nimbus and Scala
    I asked this question about a problem I was seing with a cell renderer using the Nimbus look and feel and the issue has turned out to be possibly to do with Scala. Basically I have a cell renderer which extends Panel (as opposed to DefaultTableCellRenderer) and it is behaving oddly: it is not rendering the alternate row colors properly whereas an equivalent Java program behaves just fine. If anyone is interested, here is some Scala code to run: import com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel import java.awt.{Dimension, Color} import java.lang.String import javax.swing.table
  • 具有标题行和列的JTable(JTable with titled rows and columns)
    问题 我怎样才能有一个JTable的列和行都有标题? 像这样的东西: +------+------+------+------+ |/\/\/\| col1 | col2 | col3 | +------+------+------+------+ | row1 | | | | +------+------+------+------+ | row2 | | | | +------+------+------+------+ | row3 | | | | +------+------+------+------+ 谢谢 回答1 我认为您正在搜索RowTable import java.awt.*; import java.awt.event.ActionEvent; import javax.swing.*; import javax.swing.UIManager.*; import javax.swing.event.*; import javax.swing.table.*; public class JTableRowHeader { private JFrame frame = new JFrame("JTable RowHeader"); private JScrollPane scrollPane; private JTable table; private
  • 使用 Nimbus 和 Scala 的表格单元渲染器(Table Cell renderer using Nimbus and Scala)
    问题 我问这个问题是关于我在使用 Nimbus 外观和感觉的单元渲染器中看到的问题,结果证明该问题可能与 Scala 有关。 基本上我有一个单元格渲染器,它扩展了Panel (而不是DefaultTableCellRenderer )并且它的行为很奇怪:它没有正确渲染备用行颜色,而等效的 Java 程序表现得很好。 如果有人感兴趣,这里有一些Scala代码可以运行: import com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel import java.awt.{Dimension, Color} import java.lang.String import javax.swing.table.{DefaultTableCellRenderer, AbstractTableModel, TableCellRenderer} import javax.swing.{UIManager, JComponent, JLabel, JTable} import swing.{Component, MainFrame, Label, BorderPanel, Panel, Table, ScrollPane, Frame, SimpleGUIApplication} object SwingTest extends
  • JTable TableCellRenderer 不适用于新行(JTable TableCellRenderer doesn't work for new rows)
    问题 我正在尝试使用此教程代码将按钮添加到 JTable 的最后一列: http://www.java2s.com/Code/Java/Swing-Components/ButtonTableExample.htm 它适用于具有“静态”数据的表,但是当我尝试动态添加新行时,它无法正常工作。 有没有办法做到这一点? 这是代码: import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.table.*; import java.util.*; public class TestTableButton extends JFrame { PlayersTableModel tableModel = new PlayersTableModel(); JTable table = new JTable(tableModel); public TestTableButton() { ButtonColumn bc = new ButtonColumn(table, new AbstractAction(){ public void actionPerformed(ActionEvent e){ JTable table = (JTable)e.getSource(); int
  • 如何将控件放入JTable的JTableHeader中?(How can I put a control in the JTableHeader of a JTable?)
    问题 给定一个JTable,其列的类型为Boolean.class ,则默认渲染器为JCheckBox 。 根据用户选择来选择单个单元格很容易,但是也可以很方便地选择全部或不选择任何复选框。 这些最近的示例在表头中提到了使用JCheckBox的情况,但是实现笨拙且缺乏吸引力。 如果不需要对列进行排序,如何在JTableHeader中放置行为良好的控件? 附录:为了方便,我已经添加了我的SSCCE作为一个答案,但我很高兴地接受了,他说的地址问题的乖巧方面。 回答1 问题有两个部分(如我所见:-) 可用性:发明UI交互/元素容易使用户感到困惑。 没有特别的顺序: 列标题标题用于描述列的内容,当用动作描述替换它时,该内容描述会丢失并不是立即(对我来说,这是世界上最愚蠢的用户:-)立即清除标题单元格具有切换按钮的功能。 意外单击它会失去该列中所有较早的内容状态 因此,即使互动分析明确提出了我们需要/想要的内容, 仅在内容之外采取行动使用更清晰的小部件(例如,所有/取消选择的混合状态的三态复选框)。 同样,必须同时从混合内容中进行取消/选择。 再次考虑,复选框可能也不是最好的选择,也没有进一步研究最小化意外更改(仅对我而言:-)(例如,通过将活动区域(复选框图标清晰可见)与“正常标题”区域)更改批量状态的可能性。 技术方面 TableHeader不适用于“实时”组件。
  • 为JComboBox的Items中的值设置工具提示,作为JTable中的CellEditor(Setting a tooltip for a value from JComboBox's Items as CellEditor in JTable)
    问题 我想为自定义组合框中的值设置工具提示值。 基本上,我的组合框包含一个姓名缩写的列表-当他们将鼠标悬停在上方时,我希望它显示该姓名的全名。 我的组合框基本上是具有自己的TableCellRenderer和DefaultCellEditor的JTable的单元格/列。 该列表是一个JList(模型中的内部类)-iv尝试直接设置'setToolTipText'方法,但这似乎不起作用。 这是代码: * JTable中的代码:* public void setupUserCombo(Container container){ TableColumn col = getColumnModel().getColumn(3); Set<ComboUser> values = new LinkedHashSet<ComboUser>(); ComboUser comboUser = new ComboUser(new User("Test User")); values.add(comboUser); col.setCellEditor(new MyComboBoxEditor((ComboUser[])values.toArray(new ComboUser[0]))); col.setCellRenderer(new MyComboBoxRenderer((ComboUser[]
  • 覆盖 JTable 的 DefaultTableCellRenderer 以将 JTable 中的所有单元格居中(Overriding JTable's DefaultTableCellRenderer to center all the cells in a JTable)
    问题 我有一个无法摆脱的问题。 只是让您知道,我对使用 JTables 还很陌生,所以答案可能很简单,但我找不到解决方案:/ 所以,我有一个使用 AbstractTableModel 的 JTable,它覆盖了 public Class<?> getColumnClass(int columnIndex_p) 方法,告诉要显示的每一列的类型。 其中之一是布尔值。 当我创建一个简单的 JTable 时,使用 table_l = new JTable(new MyTableModel()); 一切正常,使用复选框(开/关)正确显示布尔值。 现在,我想将每个单元格上的文本居中(以后可能还有更多选项)。 所以我为每一列定义了一个新的 DefaultTableCellRenderer,如下所示: DefaultTableCellRenderer cellRenderer_l = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // delegate the rendering part to the