java - JTable 行选择后台问题。

标签 java swing jtable renderer defaulttablemodel

我有一个 JTable,为了在 JTable 和其他属性中设置图片作为背景,我使用了这段代码。

tblMainView= new JTable(dtModel){
        public Component prepareRenderer(TableCellRenderer renderer, int row, 
                   int column) 
        {
        Component c = super.prepareRenderer( renderer, row, column);
        // We want renderer component to be transparent so background image 
        // is visible
        if( c instanceof JComponent )
        ((JComponent)c).setOpaque(false);
        return c;
        }
        ImageIcon image = new ImageIcon( "images/watermark.png" );          
          public void paint( Graphics g )
        {
        // First draw the background image - tiled 
        Dimension d = getSize();
        for( int x = 0; x < d.width; x += image.getIconWidth() )
        for( int y = 0; y < d.height; y += image.getIconHeight() )
        g.drawImage( image.getImage(), x, y, null, null );
        // Now let the regular paint code do it's work
        super.paint(g);
        }       

        public boolean isCellEditable(int rowIndex, int colIndex) {
          return false;
        }
        public Class getColumnClass(int col){
            if (col == 0)  
            {  
            return Icon.class;  
            }else if(col==7){
                return String.class;
            } else
            return String.class; 
        }   
        public boolean getScrollableTracksViewportWidth() {
            if (autoResizeMode != AUTO_RESIZE_OFF) {
                if (getParent() instanceof JViewport) {
                return (((JViewport)getParent()).getWidth() > getPreferredSize().width);
                }
            } 
            return false;
            }

    };

    tblMainView.setOpaque(false);

一切正常。但是当我选择一行时,行数据隐藏了。它显示我的行,如 this

我想要这样的结果,enter image description here dtModel 是我名为 tblMainView

JTabledeafultTableModel

最佳答案

重写 prepareRenderer() 是一个 recommended为整个表格行进行自定义呈现的方法,但你不能让它做所有事情。特别是 default renderer Icon 应该做你想做的,根本没有理由重写 paint()

附录:仔细观察,您选择的字段显示为空,因为 setOpaque(false) 干扰了 DefaultTableCellRenderer 中提到的优化应用程序接口(interface)。 example您复制的内容无效。

作为引用,下面的示例覆盖了 DefaultTableModelgetColumnClass() 以获取 default renderer对于类型 IconDate

Java GUI

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.Calendar;
import java.util.Date;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

/** @see https://stackoverflow.com/questions/6873665 */
public class JavaGUI extends JPanel {

    private static final int ICON_COL = 0;
    private static final int DATE_COL = 1;
    private static final Icon icon = UIManager.getIcon("Tree.closedIcon");
    private final Calendar calendar = Calendar.getInstance();

    public JavaGUI() {
        CustomModel model = new CustomModel();
        JTable table = new JTable(model) {

            @Override
            public Component prepareRenderer(
                    TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                if (isRowSelected(row)) {
                    c.setBackground(Color.blue);
                } else {
                    c.setBackground(Color.white);
                }
                return c;
            }
        };
        for (int i = 1; i <= 16; i++) {
            model.addRow(newRow(i));
        }
        this.add(table);
    }

    private Object[] newRow(int i) {
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        return new Object[]{icon, calendar.getTime()};
    }

    private static class CustomModel extends DefaultTableModel {

        private final String[] columnNames = {"Icon", "Date"};

        @Override
        public Class<?> getColumnClass(int col) {
            if (col == ICON_COL) {
                return Icon.class;
            } else if (col == DATE_COL) {
                return Date.class;
            }
            return super.getColumnClass(col);
        }

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

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    }

    private void display() {
        JFrame f = new JFrame("JavaGUI");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JavaGUI().display();
            }
        });
    }
}

关于java - JTable 行选择后台问题。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6873665/

相关文章:

java - 我正在制作一个带有 swing 的计算器,但按钮都搞乱了

java - 异常 ArrayIndexOutOfBoundsException : 0>=0 while retrieving a value from JTable

java - 我如何构建一个分层的 JTable?

java - 如何使用 jsvc 将 java 程序转换为守护进程?

java - 打印大型 Swing 组件

java - 在 Android 中上传图像和文本文件时上传视频不起作用

java - 如何使用Java打砖 block 游戏的重置按钮

java - 使 BorderLayout 中的两个 JTable 中的行可选择?

java - 将组合框指定为输入

java - 如何防止绘制的形状在 Java 中消失?