【问题标题】:How to Insert Image into JTable Cell如何将图像插入 JTable 单元格
【发布时间】:2021-08-28 00:17:46
【问题描述】:

有人可以指出如何将图像添加到 Java 表格单元格中的正确方向吗?

【问题讨论】:

    标签: java swing icons jtable


    【解决方案1】:

    我创建了自己的实现 TableCellRenderer 的类。我可以从 JLabel 扩展这个类,但我更喜欢保持它独立并使用 JLabel 'label' 作为类组件。

    public class GLabel implements TableCellRenderer{
        //The JLabel that is used to display image
        private final JLabel label = new JLabel();  
        
        /**
         * 
         * @param text
         * @param image 
         */
        public GLabel(String text, ImageIcon image) {
            label.setText(text);
            label.setIcon(image);
        }
        
        public GLabel(){}
    
        public JLabel getLabel() {
            return label;
        }      
    
        /**
         *
         * @param table the JTable that is asking the renderer to draw; can be null
         * @param value the value of the cell to be rendered. 
         * It is up to the specific renderer to interpret and draw the value. 
         * For example, if value is the string "true", it could be rendered as a string or it could be rendered as a check box that is checked. 
         * null is a valid value
         * @param isSelected true if the cell is to be rendered with the selection highlighted; otherwise false
         * @param hasFocus if true, render cell appropriately. For example, put a special border on the cell, if the cell can be edited, render in the color used to indicate editing
         * @param row the row index of the cell being drawn. When drawing the header, the value of row is -1
         * @param column the column index of the cell being drawn
         * @return 
         */
        @Override
        public Component getTableCellRendererComponent(JTable table,
                                          Object value,
                                          boolean isSelected,
                                          boolean hasFocus,
                                          int row,
                                          int column) {
            GLabel gLabel = (GLabel)value;
            return (Component) gLabel.getLabel();
        }
    }
    

    我创建了一个新的 DefaultTableModel 对象。我重写了 getColumnClass() 方法以在运行时传递适当的类。

    private final DefaultTableModel tblmodel = new DefaultTableModel() {        
            /**
             * This method is called by table cell renderer.
             * The method returns class of the cell data. This helps the renderer to display icons and 
             * other graphics in the table.
             */
            @Override
            public Class getColumnClass(int column)
            {
                for(int i = 0; i < tblmodel.getRowCount(); i++)
                {
                    //The first valid value of a cell of given column is retrieved.
                    if(getValueAt(i,column) != null)
                    {
                        return getValueAt(i, column).getClass();
                    }
                }
                //if no valid value is found, default renderer is returned.
                return super.getColumnClass(column);
            }
            
        };
    

    我使用我创建的 DefaultTableModel 创建了 JTable 对象。

    JTable jtable = new JTable(tblmodel);
    

    我为 GLabel 类设置了默认渲染器

    jtable.setDefaultRenderer(GLabel.class, new GLabel());
    

    我创建了新的 GLabel 对象。

    GLabel glabel = new GLabel("testing", new ImageIcon("c://imagepath"));
    

    最后,我使用 TableModel 的 addRow(Object[] rowData) 方法将 GLabel 添加到 JTable 中。

    【讨论】:

    • (1-) 不要将组件添加到 TableModel。模型应该只包含数据并使用渲染器来显示数据。
    【解决方案2】:

    1- 为 jtable 添加标签(为此创建类)

     class LabelRendar implements TableCellRenderer{
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
          //  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            return (Component)value;
        }
    
    }
    

    2- 代码 jButton 添加图片

    DefaultTableModel m = (DefaultTableModel) jTable1.getModel();
          jTable1.getColumn("image").setCellRenderer(new LabelRendar());  // call class 
          JLabel lebl=new JLabel("hello");
          lebl.setIcon(new javax.swing.ImageIcon(getClass().getResource("/main/bslogo120.png"))); // NOI18N
              m.addRow(new Object[]{"", "","",lebl});
    

    【讨论】:

    • (1-) 不要将组件添加到 TableModel。模型应该只包含数据并使用渲染器来显示数据。
    【解决方案3】:

    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)
            {
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
                public Class getColumnClass(int column)
                {
                    return getValueAt(0, column).getClass();
                }
            };
            JTable table = new JTable( model );
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
    
            JScrollPane scrollPane = new JScrollPane( table );
            add( scrollPane );
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("Table Icon");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new TableIcon());
            frame.setLocationByPlatform( true );
            frame.pack();
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowGUI();
                }
            });
        }
    
    }
    

    【讨论】:

    • 是的,它有效!谢谢。问题:为什么是 setPreferredScrollableViewportSize 行?没有它似乎工作正常。
    • @StefanReich,它与在表格中显示图标无关。执行 pack() 时,框架的大小不同。是否使用该方法取决于您的要求。
    • @camickr 啊,是关于pack(),好的。
    【解决方案4】:

    要么在前面创建图像图标:

    ImageIcon icon = new ImageIcon("image.gif");
    table.setValueAt(icon, row, column);
    

    或者您可以尝试覆盖图标字段的渲染器:

    static class IconRenderer extends DefaultTableCellRenderer {
      public IconRenderer() { super(); }
    
      public void setValue(Object value) {
        if (value == null) {
          setText("");
        }
        else
        {
          setIcon(value);
        }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    相关资源
    最近更新 更多