Swing:GlassPane和自定义涂漆的半透明按钮

时间:2017-11-30 09:39:49

标签: java swing jbutton transparency glasspane

我的应用程序左侧有一个简短的工具栏。当用户指向此工具栏时,我打开一个半透明的完整工具栏(我使用GlassPane来执行此操作)。除半透明外,其他所有工作都正常。

以下是我的示例程序的屏幕截图:

My example app screen

如您所见,第一个按钮被正确绘制,但所有其他按钮都具有完全透明的背景。

这是我的代码(SSCCE):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.metal.MetalLookAndFeel;

/**
 * <code>FlyOutExample</code>.
 */
public class FlyOutExample implements Runnable {

    private static final String[] BUTTONS = {"First button", "Second", "Another button", "Last Button", "End"};

    private static final Color HT_BLUE = new Color(0, 0, 255, 160); // half transparent blue

    private JPanel shortPanel = new JPanel(new GridLayout(5, 1));

    private JPanel fullPanel = new JPanel(new GridLayout(5, 1));

    private JPanel fullPanelWrapper = new JPanel(new BorderLayout());

    private JPanel shortPanelWrapper = new JPanel(new BorderLayout());

    private JFrame frm;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new FlyOutExample());
    }

    @Override
    public void run() {
        try {
            UIManager.setLookAndFeel(MetalLookAndFeel.class.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (String s : BUTTONS) {
            JButton b = new JButton(s.substring(0, 1));
            b.setBackground(Color.BLUE);
            b.setForeground(Color.RED);
            b.setUI(new BasicButtonUI());
            shortPanel.add(b);
            b = new JButton(s);
            b.setForeground(Color.RED);
            b.setOpaque(false);
            b.setHorizontalAlignment(SwingConstants.LEADING);
            b.setBackground(HT_BLUE);
            b.setUI(new BasicButtonUI() {
                @Override
                public void update(Graphics g, JComponent c) {
                    Color old = g.getColor();
                    g.setColor(HT_BLUE);
                    g.fillRect(0, 0, c.getWidth(), c.getHeight());
                    g.setColor(old);
                    paint(g, c);
                }
            });
            fullPanel.add(b);
        }
        frm = new JFrame("Flyout example");
        shortPanelWrapper.setOpaque(false);
        shortPanelWrapper.add(shortPanel, BorderLayout.NORTH);
        JPanel bluePanel1 = new JPanel();
        bluePanel1.setOpaque(true);
        bluePanel1.setBackground(Color.BLUE);
        shortPanelWrapper.add(bluePanel1);
        fullPanel.setOpaque(false);
        fullPanelWrapper.setOpaque(false);
        fullPanelWrapper.add(fullPanel, BorderLayout.NORTH);
        JPanel bluePanel2 = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                Color old = g.getColor();
                g.setColor(HT_BLUE);
                g.fillRect(0, 0, getWidth(), getHeight());
                g.setColor(old);
            }
        };
        bluePanel2.setOpaque(false);
        fullPanelWrapper.add(bluePanel2);
        MouseListener openListener = new OpenSideBarListener();
        for (Component c : shortPanel.getComponents()) {
            c.addMouseListener(openListener);
        }
        bluePanel1.addMouseListener(openListener);
        MouseListener closeListener = new CloseSideBarListener();
        for (Component c : fullPanel.getComponents()) {
            c.addMouseListener(closeListener);
        }
        bluePanel2.addMouseListener(closeListener);
        JPanel topPanel = new JPanel();
        topPanel.setBackground(Color.GREEN);
        topPanel.setPreferredSize(new Dimension(0, 30));
        JPanel bottomPanel = new JPanel();
        bottomPanel.setBackground(Color.GREEN);
        bottomPanel.setPreferredSize(new Dimension(0, 30));
        frm.add(topPanel, BorderLayout.NORTH);
        frm.add(bottomPanel, BorderLayout.SOUTH);
        frm.add(shortPanelWrapper, BorderLayout.WEST);
        frm.add(new JScrollPane(new JTable(40, 7)));
        frm.pack();
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }

    private void openPopup() {
        if (shortPanelWrapper.getMousePosition() != null) {
            Container glassPane = (Container) frm.getGlassPane();
            glassPane.setLayout(null);
            fullPanelWrapper.setLocation(shortPanelWrapper.getLocation());
            fullPanelWrapper.setSize(140, shortPanelWrapper.getHeight());
            glassPane.add(fullPanelWrapper);
            glassPane.setVisible(true);
        }
    }

    private void closePopup() {
        if (fullPanelWrapper.getMousePosition() == null) {
            Container glassPane = (Container) frm.getGlassPane();
            glassPane.removeAll();
            glassPane.setVisible(false);
        }
    }

    private class OpenSideBarListener extends MouseAdapter {
        @Override
        public void mouseEntered(MouseEvent e) {
            openPopup();
        }
    }

    private class CloseSideBarListener extends MouseAdapter {
        @Override
        public void mouseExited(MouseEvent e) {
            closePopup();
        }
    }
}

我的JDK是:1.8_91,操作系统:Windows 7

我的问题是:如何正确绘制所有按钮?

P.S。在实际应用程序中,我有一个自定义UI,用于左侧工具栏中的所有按钮,因此请不要删除我的按钮的UI。

更新

我再次启动了应用程序(没有任何更改)并得到了另一个错误

这是新图片:

Another bug

可能这是我的显卡的错误?

0 个答案:

没有答案