java - 如何高亮(统一视觉选择,绘制透明覆盖)JPanel?

标签 java swing jpanel

许多自定义 Swing 组件由 JPanel 组成。有时需要这些组件是可选的。

如何使 JPanel 看起来被选中?它应该像其他项目一样被选中,如菜单项或 JTable 单元格。 IE。整个 JPanel 应该被透明的蓝色覆盖。如果这与 L&F/主题中的其他项目完全一样,那就太好了,

这可能吗?

最佳答案

您可以考虑查看 JXLayer/JLayer,它允许您在组件顶部绘制覆盖层。

Highlight

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.QualityHints;
import org.jdesktop.jxlayer.plaf.AbstractBufferedLayerUI;

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

                SelectablePane pane = new SelectablePane();
                SelectableUI ui = new SelectableUI();
                JXLayer<JPanel> layer = new JXLayer<>(pane, ui);
                layer.addMouseListener(new MouseAdapter() {

                    @Override
                    public void mouseClicked(MouseEvent e) {
                        ui.setSelected(!ui.isSelected());
                    }

                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(layer);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SelectablePane extends JPanel {

        public SelectablePane() {

            setLayout(new GridBagLayout());
            add(new JLabel("Hello world"));

        }

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

    public static class SelectableUI extends AbstractBufferedLayerUI<JPanel> {

        public static Map<RenderingHints.Key, Object> mapRenderHints = new QualityHints();

        private boolean selected = false;

        public SelectableUI() {

            mapRenderHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); // okay
            mapRenderHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // bad
            mapRenderHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); // okay
            mapRenderHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            mapRenderHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            mapRenderHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            mapRenderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        }

        public void setSelected(boolean value) {

            if (selected != value) {
                selected = value;
                firePropertyChange("selected", !selected, selected);
                repaint();
            }

        }

        public boolean isSelected() {
            return selected;
        }

        @Override
        protected void paintLayer(Graphics2D g2, JXLayer<? extends JPanel> l) {
            super.paintLayer(g2, l);
            if (isSelected()) {
                Graphics2D g2d = (Graphics2D) g2.create();
                g2d.setColor(UIManager.getColor("List.selectionBackground"));
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.fillRect(0, 0, l.getWidth(), l.getHeight());
                g2d.dispose();
            }
        }

        @Override
        protected Map<RenderingHints.Key, Object> getRenderingHints(JXLayer<? extends JPanel> l) {
            return mapRenderHints;
        }

        public void repaint() {
            setDirty(true);
        }

        public void invalidate() {
            setDirty(true);
        }

        public void revalidate() {
            setDirty(true);
        }
    }

}

关于java - 如何高亮(统一视觉选择,绘制透明覆盖)JPanel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27516581/

相关文章:

java - 选择数组中的随机字符串来打印消息

java - Java 文件读/写新手

java - 是否可以在 sonarqube 的多模式项目中跳过 Java 插件

java - 将 JSpinner 的日期值转换为整数

java - 在 Java 中画一条线 - 线不可见

Java 2d 游戏-游戏中非常奇怪的 "bug"

java - 加入 SAAJ 和 JAXB

java - 为什么我的 java 应用程序模糊?

java - Java 中有 JFrame 的有效替代品吗?

java - 如何自定义 JPanel 或 JLabel 的形状?