How do I make a JSlider background transparent? or How do I properly overlay JComponents in JLayeredPane?

StackOverflow https://stackoverflow.com/questions/14534910

Pergunta

I am trying to overlay a JSlider on top of a JProgressBar. I am using a JLayeredPane to hold the two components. I am adding the JProgressBar to the JLayeredPane and then adding the JSlider. So far, I have attempted to make the JSlider transparent by setting opaque to false and overriding the paintComponent method. What I end up with is that the slider handle is the only part that becomes transparent while the background stays opaque. It is possible that I am not using the JLayeredPane correctly, but my tests with JLabels seemed to work. How do I get the background of the JSlider to be transparent?

JSlider slider = new JSlider()
{

    @Override
    public void paintComponent(java.awt.Graphics g)
    {
        java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
        g2.setComposite(AlphaComposite.getInstance(
                AlphaComposite.SRC_OVER, (float) 0.5));

        super.paintComponent(g2);
    }

};

Thank you all for your help. Through your examples, I have discovered that my issue is with the JLayeredPane that I am using. I recognize that the JSlider background can be made transparent, however, I still cannot get the components on layers beneath to show through. This is my example:

public class SliderTest extends JFrame
{

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args)
{
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            try
            {
                SliderTest frame = new SliderTest();
                frame.setVisible(true);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public SliderTest()
{
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JPanel panel = new JPanel();
    contentPane.add(panel, BorderLayout.CENTER);
    panel.setLayout(new BorderLayout(0, 0));

    JLayeredPane layeredPane = new JLayeredPane();

    panel.add(layeredPane, BorderLayout.CENTER);
    layeredPane.setLayout(new BorderLayout(0, 0));

    JProgressBar progressBar = new JProgressBar();
    progressBar.setValue(50);
    layeredPane.add(progressBar);
    layeredPane.setLayer(progressBar, 0);

    JSlider slider = new JSlider()
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(getBackground());
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();

            super.paintComponent(g);
        }

    };
    layeredPane.setLayer(slider, 1);
    slider.setOpaque(false);

    // layeredPane.setLayer(slider, 1);
    layeredPane.add(slider, BorderLayout.CENTER);

}

}

Foi útil?

Solução

This will depend upon what it is you want to achieve. By default JSlider is transparent.

What's important here is that the opaque property MUST be false, otherwise the repaint manager will not paint behind the components...

enter image description here

  • Top slider, transparent background (blue), opaque control
  • Middle slider, transparent background (green), transparent control
  • Bottom slider, normal JSlider

    public class TestSlider {

    public static void main(String[] args) {
        new TestSlider();
    }
    
    public TestSlider() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
    
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
    
        });
    }
    
    public class TestPane extends JPanel {
    
        public TestPane() {
            setBackground(Color.RED);
    
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
    
            add(new TransparentBackgroundSlider(), gbc);
            add(new TransparentSlider(), gbc);
            add(new JSlider(), gbc);
    
        }
    
    }
    
    public class TransparentBackgroundSlider extends JSlider {
    
        public TransparentBackgroundSlider() {
            // Important, we taking over the filling of the
            // component...
            setOpaque(false);
            setBackground(Color.BLUE);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(getBackground());
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
    
            super.paintComponent(g);
        }
    
    }
    
    public class TransparentSlider extends JSlider {
    
        public TransparentSlider() {
            // Important, we taking over the filling of the
            // component...
            setOpaque(false);
            setBackground(Color.GREEN);
        }
    
        @Override
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
            super.paint(g2d);
            g2d.dispose();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            // We need this because we've taken over the painting of the component
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(getBackground());
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
    
            super.paintComponent(g);
        }
    
    }
    

    }

Update with layer example

enter image description here

public class TestSlider {

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

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JLayeredPane {

        private JProgressBar pb;
        private JSlider slider;

        public TestPane() {

            pb = new JProgressBar();
            slider = new JSlider();

            add(pb, new Integer(0));
            add(slider, new Integer(1));

        }

        @Override
        public Dimension getPreferredSize() {
            Dimension size = pb.getPreferredSize();
            size.height *= 4;
            size.width = Math.max(size.width, slider.getPreferredSize().width);
            return size;
        }

        @Override
        public void doLayout() {
            super.doLayout();

            int width = getWidth();
            int height = getHeight();

            Dimension size = pb.getPreferredSize();

            int x = 10;
            int y = (getHeight() - size.height) / 2;

            pb.setLocation(x, y);
            size.width = getWidth() - 21;
            pb.setSize(size);

            size = slider.getPreferredSize();
            x = (getWidth() - size.width) / 2;
            y = (getHeight() - size.height) / 2;
            slider.setBounds(x, y, size.width, size.height);

        }

    }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top