Home > Net >  JTable becomes opaque even if specified otherwise, because of DefaultTableModel getColumnClass overr
JTable becomes opaque even if specified otherwise, because of DefaultTableModel getColumnClass overr

Time:02-24

My project requires that a table be drawn as transparent to reveal an image underneath. When I override the function getColumnClass in DefaultTableModel, it seems like table.setOpaque(false) no longer does anything. I need each cell to only draw images within, which works fine. Here is the table model:

JTable table = new JTable(model) {
            @Override
            public boolean isCellEditable(int row, int column) {
                //all cells false
                return false;
            }
            @Override
            public Class<?> getColumnClass(int column) {
                return ImageIcon.class;
            }
        };

There is a small portion of the table visible while scrolling, but the moment the table updates when I move it around or click on it, it becomes opaque.

I have a simple goal, where i am to overlay a translucent image in a cell, over an image underneath the table, as if like a selection. The image would toggle off and on and is handled in this mouse adapter:

@Override
public void mouseClicked(MouseEvent e) {
    int row = table.rowAtPoint(e.getPoint());//get mouse-selected row
    int col = table.columnAtPoint(e.getPoint());//get mouse-selected col

    String string = row "|" col;

    if(selectedCells.contains(string)){
    
        //cell was already selected, deselect it
        selectedCells.remove(string);
        table.setValueAt(null, row, col);
        System.out.println("Removed Cell "   string);
        
    } else {
    
        //cell was not selected
        selectedCells.add(string);
        table.setValueAt(PrimaryWindow.selection, row, col);
        System.out.println("Added Cell "   string);
    }
}

I paint the image underneath by overriding the panel the table is in, which looks like this:

JPanel background = new JPanel( new BorderLayout() )
        {
            @Override
            protected void paintComponent(Graphics g)
            {
                super.paintComponent(g);

                g.drawImage(icon.getImage(), 0, 0, scale*32, scale*32, this);
            }
        };

And then add the table in above: background.add(table);

I do have this set:

DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)table.getDefaultRenderer(Object.class);
        renderer.setOpaque(false);

And this set:

table.setOpaque(false);

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Object[][] data = new Object[32][32];
                    String[] names = new String[32];
                    DefaultTableModel model = new DefaultTableModel(data, names) {
                        @Override
                        public Class<?> getColumnClass(int columnIndex) {
                            return Icon.class;
                        }

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

                    JTable table = new JTable(model);
                    table.setOpaque(false);

                    table.setDefaultRenderer(Icon.class, new TransparentTableCellRenderer());

                    JScrollPane scrollPane = new JScrollPane(table);
                    scrollPane.setOpaque(false);
                    scrollPane.getViewport().setOpaque(false);

                    LinkedList<String> selectedCells = new LinkedList<>();

                    BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
                    Graphics2D g2d = img.createGraphics();
                    g2d.setColor(Color.RED);
                    g2d.fillRect(0, 0, 100, 100);
                    g2d.dispose();

                    Icon icon = new ImageIcon(img);

                    table.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            int row = table.rowAtPoint(e.getPoint());
                            int col = table.columnAtPoint(e.getPoint());

                            String string = row   "|"   col;

                            if (selectedCells.contains(string)) {
                                //cell was already selected, deselect it
                                selectedCells.remove(string);
                                table.setValueAt(null, row, col);
                                System.out.println("Removed Cell "   string);
                            } else {
                                //cell was not selected
                                selectedCells.add(string);
                                table.setValueAt(icon, row, col);
                                System.out.println("Added Cell "   string);
                            }
                        }
                    });

                    JFrame frame = new JFrame();
                    // Supply your own back ground image
                    frame.setContentPane(new BackgroundPane(ImageIO.read(Main.class.getResource("/images/Mando01.jpeg"))));
                    frame.add(scrollPane);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class TransparentTableCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            setOpaque(false);
            if (value instanceof Icon) {
                setIcon((Icon)value);
            } else {
                setIcon(null);
            }
            return this;
        }

    }

    public class BackgroundPane extends JPanel {

        private Image background;

        public BackgroundPane(Image background) {
            setLayout(new BorderLayout());
            this.background = background;
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(this), background.getHeight(this));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(background, 0, 0, this);
            g2d.dispose();
        }

    }
}
  • Related