Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8056713
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T08:48:01+00:00 2026-06-05T08:48:01+00:00

I’m trying to create a custom cell renderer that will display an image in

  • 0

I’m trying to create a custom cell renderer that will display an image in JTable’s header cell. I’ve gotten the source code to work with the Metal L&F but I am encountering problems with Nimbus. Under normal circumstances, Nimbus displays the image just fine. However, when a table is sorted, Nimbus will draw the sort icon instead of the icon I’ve specified. This is different than the Metal L&F, as that will always draw the icon I’ve provided.

Example image demonstrating error in Nimbus L&F vs Metal L&F

Does anyone know of a way to have Nimbus draw the image even if a column is sorted?

I’m using Java 6.29 & Nimbus. I can’t change the Java release or the L&F.

Also, I’ve tried to do some other workarounds, like changing the label to use HTML and and img tag to display the image, but this produces a weird visual effect. EDIT The text and image aren’t aligned well (even with a HTML align tag on the img tag) Here is a picture, notice how the text in the Temp Hi column doesn’t align:

example image of solution with HMTL and img tag

import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;


public class ImageChangeDemo extends JFrame {
    public static void main(String args[]) {
        //comment out the code below to try in Metal L&F
        try {
            for(javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.
                    getInstalledLookAndFeels()) {
                if("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ImageChangeDemo().setVisible(true);
            }
        });
    }

    public ImageChangeDemo(){
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        JScrollPane pane = new javax.swing.JScrollPane();
        JTable table = new javax.swing.JTable();
        table.setAutoCreateRowSorter(true);
        table.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"a", "q", "h", "v"},
                {"b", "m", "l", "h"},
                {"d", "c", "a", "d"},
                {"j", "o", "y", "e"}
            },
            new String [] {
                "Col 1", "Col 2", "Col 3", "Col 4"
            }
        ) {
            Class[] types = new Class [] {
                String.class, String.class, String.class, String.class
            };
            @Override
            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        pane.setViewportView(table);
        this.add(pane);

        table.getTableHeader().setDefaultRenderer(new ImageRenderer(table));

        pack();
    }

    public class ImageRenderer extends DefaultTableCellRenderer{
        TableCellRenderer orig;
        ImageIcon icon;
        ImageRenderer(JTable table){
            orig = table.getTableHeader().getDefaultRenderer();
        }
        @Override
        public Component getTableCellRendererComponent(final JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = 
                    orig.getTableCellRendererComponent(
                        table, value, isSelected, hasFocus, row, column);
            if(c instanceof JLabel){
                if(true){
                    JLabel label = (JLabel)c;
                    label.setIcon(makeIcon());
                }
            }
            return c;
        }

        public ImageIcon makeIcon(){
            if(icon == null)
            icon = new ImageIcon(
                    ImageChangeDemo.class.getResource("/resources/green_triangle_down.png"));
            return icon;
        }
    }
}

EDIT: Here is an example scenario of what my real application should do: If the table column contains certain data (such as any strings beginning with a certain word) display a warning icon next to the column name in the table header. I’ve gotten this to work fine. Now, if the user sorts a column with the image, Nimbus is removing the image and replacing it with a sort icon – I still want the original warning icon to display.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T08:48:03+00:00Added an answer on June 5, 2026 at 8:48 am

    So after much trial and error I was able to figure out a way to have my custom icon in the header row even if the column is sorted. Basically what I did was have the renderer return a custom panel containing 2 children, the image in a JLabel and the component that was originally produced by default renderer. (Note that this workaround is only necessary for Nimbus L&F, and the original example code works fine in the Metal L&F)

    This code uses StackLayout created by Romain Guy as demonstrated in his book Filthy Rich Clients – see page p245. Here is the source for StackLayout

    Here is the code I created for the renderer. Make sure to download StackLayout else this won’t compile.

    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.FontMetrics;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableCellRenderer;
    
    
    public class ImageChangeDemo extends JFrame {
        public static void main(String args[]) {
            //comment out the code below to try in Metal L&F
            try {
                for(javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.
                        getInstalledLookAndFeels()) {
                    if("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
    
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new ImageChangeDemo().setVisible(true);
                }
            });
        }
    
        public ImageChangeDemo(){
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            JScrollPane pane = new javax.swing.JScrollPane();
            JTable table = new javax.swing.JTable();
            table.setAutoCreateRowSorter(true);
            table.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {
                    {"a", "q", "h", "v"},
                    {"b", "m", "l", "h"},
                    {"d", "c", "a", "d"},
                    {"j", "o", "y", "e"}
                },
                new String [] {
                    "Col 1", "Col 2", "Col 3", "Col 4"
                }
            ) {
                Class[] types = new Class [] {
                    String.class, String.class, String.class, String.class
                };
                @Override
                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }
            });
            pane.setViewportView(table);
            this.add(pane);
    
    
            pack();
            //set renderer after pack so header row has correct default height
            table.getTableHeader().setDefaultRenderer(new ImageRenderer(table));
    
    
        }
    
        public class ImageRenderer extends DefaultTableCellRenderer{
            TableCellRenderer orig;
            private final ImageIcon icon = new ImageIcon(
                        ImageChangeDemo.class.getResource("/resources/exclamation-icon.png"));;
            private JPanel jp = new JPanel(new StackLayout());
            private final JLabel pic = new JLabel(icon);
            { //extra initialization for PIC
                pic.setHorizontalAlignment(JLabel.LEADING); //so it isn't centered in stack layout
            }
    
            ImageRenderer(JTable table){
                orig = table.getTableHeader().getDefaultRenderer();
            }
    
            @Override
            public Component getTableCellRendererComponent(final JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                Component c = 
                        orig.getTableCellRendererComponent(
                            table, value, isSelected, hasFocus, row, column);
                if(true){
                    int width  = table.getColumnModel().getColumn(column).getWidth();
                    int height = table.getTableHeader().getSize().height;
                    System.out.println("height"+height);
    
                    jp.removeAll();                //clean the JPanel
    
                    //move text in label to the left so it isn't covered by the icon
                    if(c instanceof JLabel){
                        JLabel l = (JLabel) c;
                        l.setPreferredSize(new Dimension(width, height));
    
                        FontMetrics fontMetrics = l.getFontMetrics(l.getFont());
                        int sizeOfSpace = fontMetrics.charWidth(' ');
                        int numSpaces = (int)Math.round(icon.getIconWidth() / (double)sizeOfSpace);
                        StringBuilder sb = new StringBuilder();
                        for(int i = 0; i < numSpaces; i++)
                            sb.append(' ');
    
                        //account for HTML in header messages
                        if(l.getText().toLowerCase().startsWith("<html>")){
                            l.setText(  l.getText().substring(0, "<html>".length()) +
                                        sb.toString() +
                                        l.getText().substring("<html>".length()));
                        }
                        else
                            l.setText(sb.toString()+l.getText());
                    }
    
    
                    //Add components to the JPanel & return it.
                    jp.add(c, StackLayout.BOTTOM);  //will contain modifications for spacing.
                    jp.add(pic, StackLayout.TOP);
                    return jp;
    
                }
                else
                    return c;
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to create an if statement in PHP that prevents a single post
Basically, what I'm trying to create is a page of div tags, each has
I am trying to understand how to use SyndicationItem to display feed which is
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I need a function that will clean a strings' special characters. I do NOT
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I am trying to render a haml file in a javascript response like so:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.