As MadProgrammer suggested, JLayer really works:
import java.awt.*; import javax.swing.*; import javax.swing.plaf.*; public class FixedImageLayerUI extends LayerUI<JComponent> { @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); Graphics2D g2 = (Graphics2D) g.create(); g2.setColor( Color.RED ); g2.fillOval(0, 0, 10, 10); g2.dispose(); } private static void createAndShowUI() { String[] data = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; JList<String> list = new JList<String>( data ); JScrollPane scrollPane = new JScrollPane( list ); LayerUI<JComponent> layerUI = new FixedImageLayerUI(); JLayer<JComponent> layer = new JLayer<JComponent>(scrollPane, layerUI); JFrame frame = new JFrame("FixedImage"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add( layer ); frame.pack(); frame.setLocationByPlatform( true ); frame.setVisible( true ); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } }
Also, as MadProgrammer noted, overriding the JScrollPane drawing method does not work. However, if you make the JList opaque, it works:
import java.awt.*; import javax.swing.*; import javax.swing.plaf.*; public class FixedImageScrollPane { private static void createAndShowUI() { String[] data = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; JList<String> list = new JList<String>( data ); list.setOpaque( false ); JScrollPane scrollPane = new JScrollPane( list ) { @Override public void paint(Graphics g) { super.paint(g); g.setColor( Color.RED ); g.fillOval(0, 0, 10, 10); } }; JFrame frame = new JFrame("FixedImage"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add( scrollPane ); frame.pack(); frame.setLocationByPlatform( true ); frame.setVisible( true ); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } }