1

I want to make a translucent JPanel for which I can choose the x-coordinate, y-coordinate, width and height. I have found some material that made a translucent JPanel that filled its parent container, but I don't need this effect. I need a translucent JPanel whose position can be specified in the parent container, such that only this area is translucent, while others in the parent container are opaque. I tried this code but it is incorrect. The resultant area is smaller than the area I intend. What is wrong, or how I can get this effect?

public class TranslucentJPanel extends JPanel {

    private float transparency;

    public TranslucentJPanel(){
    }



    /**set the transparency
     * 
     * @param transparency:the transparency you want to set
     * 
     * @return void
     */
    public void setTransparent(float transparency) {
        this.transparency = transparency;
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);

        Graphics2D graphics2d = (Graphics2D) g.create();
        graphics2d.setComposite(AlphaComposite.SrcOver.derive(transparency));

        graphics2d.fill(getBounds());
        graphics2d.dispose();
    }
}
Alden
  • 837
  • 1
  • 6
  • 15
  • You could use a `JLayer` (AKA `JXLayer`) to paint over the top of other components in a container, for [example](http://stackoverflow.com/questions/25274566/how-can-i-change-the-highlight-color-of-a-focused-jcombobox/25276658#25276658), otherwise you will need to use the glass pane – MadProgrammer Aug 26 '15 at 01:36
  • This [example](http://stackoverflow.com/questions/12127422/inner-transparent-selection-window-in-java-using-glasspane/12127579#12127579) is kind of the reverse of what you want (creates a whole in a translucent panel), but it might give you some ideas – MadProgrammer Aug 26 '15 at 01:38
  • @MadProgrammer Thanks for your help.The first idea you given me is so difficult for me because I haven't known that class,And I will realize it now.The second example that you given is good,and I did get some idea.But after I have a translucency JPanel,I will add some component over it.And that method is too tedious.So I'm sorry. – Alston Williams Aug 26 '15 at 02:26
  • I thought you were adding the "transaprent" area over a preexisting container? Can you provide some more details about what you are trying to achieve? Maybe a use-case? Might help solve the issue – MadProgrammer Aug 26 '15 at 02:27
  • @MadProgrammer I have added background in my `JFrame`,and I have add a JPanel as parameter of `setContentPane()` method.In this JPanel ,I add another JPanel that I want to appoint position to show a Jlist,and I need this JPanel to be translucence. – Alston Williams Aug 26 '15 at 02:40
  • I'm sorry that I want to show a picture but I don't know how to show it. – Alston Williams Aug 26 '15 at 02:50

1 Answers1

3

So, two things come to mind immediately...

First, don't use getBounds, the Grapghics context is already translated to the components x/y position, so you're doubling that up. Instead, simply use 0x0 and provide the width and height, something like...

graphics2d.fillRect(0, 0, getWidth(), getHeight());

Also, remember, most Swing components are opaque by default, this includes the JList, JScrollPane and it's JViewport, you need to set these to be transparent if you want them to be see through at all.

Also, the "default" renderer that the JList uses also renderers it self as opaque, so you need to be able to supply your own if you want the items to be transparent...

Translucent

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                DefaultListModel<String> model = new DefaultListModel<>();
                model.addElement("Bananas");
                model.addElement("Apples");
                model.addElement("Pears");
                model.addElement("Grapes");
                model.addElement("Tim Tams");

                JList list = new JList(model);
                list.setCellRenderer(new DefaultListCellRenderer() {

                    @Override
                    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                        setOpaque(isSelected);
                        return this;
                    }

                });
                list.setOpaque(false);
                JScrollPane sp = new JScrollPane(list);
                sp.setOpaque(false);
                sp.getViewport().setOpaque(false);

                TranslucentPane tp = new TranslucentPane();
                tp.setLayout(new GridBagLayout());
                tp.setLayout(new BorderLayout());
                tp.add(sp);

                JFrame frame = new JFrame("Testing");
                frame.setContentPane(new BackgroundPane());
                frame.setLayout(new GridBagLayout());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TranslucentPane extends JPanel {

        private float alpha = 0.75f;

        public TranslucentPane() {
            setOpaque(false);
            setBorder(new EmptyBorder(5, 5, 5, 5));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));

            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
        }

    }

    public class BackgroundPane extends JPanel {

        private BufferedImage background;

        public BackgroundPane() {
            try {
                background = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\MegaTokyo\\thumnails\\megatokyo_omnibus_1_3_cover_by_fredrin-d4oupef.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(background.getWidth(), background.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = (getWidth() - background.getWidth()) / 2;
            int y = (getHeight() - background.getHeight()) / 2;
            g.drawImage(background, x, y, this);
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366