自定义表格单元格渲染器无效

时间:2014-03-27 07:46:36

标签: java swing jtable tablecellrenderer

我尝试从here实现自定义TableCellRenderer的示例(我也尝试了其他示例)。无论我做了什么,我的自定义TableCellRenderer都没有任何影响,所以我认为我在不同的层面上做错了什么。任何人都可以向我解释一下我究竟做错了什么?这是我的代码:

import java.text.DecimalFormat;
import java.util.Random;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

public class Test {
  public static void main(String[] args) {
    // Show GUI
    java.awt.EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        GUI gui = new GUI();

        int numRows = 5;
        int numCols = 5;

        DefaultTableModel tableModel = new DefaultTableModel(0,
          numCols);

        // Add rows
        for (int i = 0; i < numRows; i++) {
          Float[] row = new Float[numCols];

          // Build columns
          for (int j = 0; j < numCols; j++) {
            Random random = new Random();
            row[j] = random.nextFloat();
          }
          tableModel.addRow(row);
        }

        JTable table = new JTable(tableModel);
        table.setDefaultRenderer(Float.class, new DecRenderer(
          new DecimalFormat("##")));

        JScrollPane scrollPane = new JScrollPane(table);
        gui.getContentPane()
          .add(scrollPane, BorderLayout.CENTER);

      }
    });
  }
}

class GUI extends JFrame {
  private static final long serialVersionUID = 1L;

  public GUI() {
    setTitle("GUI");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 350, 400);
    setLocationRelativeTo(null);
    setVisible(true);

    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
    contentPane.setLayout(new BorderLayout(0, 0));

    setContentPane(contentPane);
  }
}

// Source: https://stackoverflow.com/questions/2833482/
// how-to-represent-double-values-as-circles-in-a-2d-matrix-in-java/
// 2834484#2834484
@SuppressWarnings("serial")
class DecRenderer extends DefaultTableCellRenderer implements
  Icon {

  private static final int SIZE = 32;
  private static final int HALF = SIZE / 2;
  DecimalFormat            df;

  public DecRenderer(DecimalFormat df) {
    this.df = df;
    this.setIcon(this);
    this.setHorizontalAlignment(SwingConstants.RIGHT);
    this.setBackground(Color.lightGray);
  }

  @Override
  protected void setValue(Object value) {
    setText((value == null) ? "" : df.format(value));
  }

  @Override
  public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setColor(Color.blue);
    double v = Double.valueOf(this.getText());
    int d = (int) (v * SIZE);
    int r = d / 2;
    g2d.fillOval(x + HALF - r, y + HALF - r, d, d);
  }

  @Override
  public int getIconWidth() {
    return SIZE;
  }

  @Override
  public int getIconHeight() {
    return SIZE;
  }
}

2 个答案:

答案 0 :(得分:1)

这是因为DefaultTableModel中的getColumnClass会为您的所有列返回Object.class(在您的情况下)。

快速修复是下一个更改模型:

 DefaultTableModel tableModel = new DefaultTableModel(0,numCols) {
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return Float.class;
        }
    };

答案 1 :(得分:-1)

在您的DecRenderer类中添加此api。我没有测试过代码,所以请解决一些变量编译错误。

    public Component getTableCellRendererComponent(JTable table,
                                          Object value,
                                          boolean isSelected,
                                          boolean hasFocus,
                                          int row,
                                          int column) {
    return new JPanel() {
    @Override
      public void paintComponent(Component c, Graphics g, int x, int y) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
          RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.blue);
        double v = Double.valueOf(DecRenderer.this.getText());
        int d = (int) (v * SIZE);
        int r = d / 2;
        g2d.fillOval(x + HALF - r, y + HALF - r, d, d);
      }
}
}