How to highlight (uniform visually select, draw tr

2019-03-01 08:56发布

Many custom Swing components are made of JPanel. Sometimes these components are required to be selectable.

How is it possible to make JPanel look selected? It should be selected like other items do, like menu items, or JTable cells. I.e. entire JPanel should be covered with transparent blue. It would be excellent, if this would made exactly like other items in L&F / theme,

Is it possible?

1条回答
不美不萌又怎样
2楼-- · 2019-03-01 09:43

You could consider taking a look at JXLayer/JLayer, which would allow you to paint an overlay on top the component.

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

}
查看更多
登录 后发表回答