如何使JSlider背景透明?或者如何在JLayeredPane中正确覆盖JComponents?

时间:2013-01-26 07:35:42

标签: java swing transparent jslider jlayeredpane

我正在尝试将JSlider叠加在JProgressBar之上。我使用JLayeredPane来保存这两个组件。我将JProgressBar添加到JLayeredPane,然后添加JSlider。到目前为止,我试图通过将opaque设置为false并覆盖paintComponent方法来使JSlider透明。我最终得出的结果是,滑块手柄是唯一一个在背景保持不透明时变得透明的部分。我可能没有正确使用JLayeredPane,但我对JLabels的测试似乎有效。如何让JSlider的背景变得透明?

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

};

谢谢大家的帮助。通过您的示例,我发现我的问题在于我正在使用的JLayeredPane。我认识到JSlider背景可以变得透明,但是,我仍然无法获得下面层上的组件来显示。这是我的例子:

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 个答案:

答案 0 :(得分:4)

这取决于你想要达到的目标。默认情况下,JSlider是透明的。

这里重要的是opaque属性必须是false,否则重绘管理器不会在组件后面绘制......

enter image description here

  • 顶部滑块,透明背景(蓝色),不透明控件
  • 中间滑块,透明背景(绿色),透明控制
  • 底部滑块,正常JSlider

    公共类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);
        }
    
    }
    

    }

使用图层示例进行更新

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

        }

    }

}