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

旧巷老猫 提交于 2019-12-13 02:26:22

问题


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);

}

}


回答1:


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...

  • 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

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);

        }

    }

}


来源:https://stackoverflow.com/questions/14534910/how-do-i-make-a-jslider-background-transparent-or-how-do-i-properly-overlay-jco

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!