代码之家  ›  专栏  ›  技术社区  ›  Kirito

如何将焦点设置为图像或标签?[Java Swing]

  •  0
  • Kirito  · 技术社区  · 2 年前

    假设我有几个图像,每个图像都在一个标签中,有没有一种方法可以通过单击其中一个图像或标签来设置焦点,并对单击的图像进行一些图像处理(模糊、黑白…)。

    谢谢你的帮助

    0 回复  |  直到 2 年前
        1
  •  2
  •   MadProgrammer    2 年前

    你可以。。。

    使用 JButton 相反,这是他们设计的目的。。。

    enter image description here

    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        JFrame frame = new JFrame();
                        frame.add(new TestPane());
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() throws IOException {
                setLayout(new GridLayout(-1, 3));
                for (int index = 1; index < 13; index++) {
                    BufferedImage image = ImageIO.read(getClass().getResource("/images/Cute" + index + ".png"));
                    Image scaled = image.getScaledInstance(50, -1, Image.SCALE_SMOOTH);
                    JButton btn = new JButton(new ImageIcon(scaled));
                    btn.putClientProperty("image", image);
                    add(btn);
                    btn.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            JButton btn = (JButton) e.getSource();
                            BufferedImage img = (BufferedImage) btn.getClientProperty("image");
                            // Do stuff
                        }
                    });
                }
            }
    
        }
    }
    

    看见 How to Use Buttons, Check Boxes, and Radio Buttons

    不想要按钮“填充”效果吗?

    这变得有点复杂,但并非不可能。。。

    enter image description here

    import java.awt.Component;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.border.AbstractBorder;
    import javax.swing.border.EmptyBorder;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        JFrame frame = new JFrame();
                        frame.add(new TestPane());
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() throws IOException {
                setLayout(new GridLayout(-1, 3));
                for (int index = 1; index < 13; index++) {
                    BufferedImage image = ImageIO.read(getClass().getResource("/images/Cute" + index + ".png"));
                    Image scaled = image.getScaledInstance(50, -1, Image.SCALE_SMOOTH);
                    JButton btn = new JButton();
                    btn.addFocusListener(new FocusListener() {
                        @Override
                        public void focusGained(FocusEvent e) {
                            // Focus.color is for MacOS, Button.focus should work under
                            // most other look and feels
                            btn.setBorder(new RoundBorder());
                        }
    
                        @Override
                        public void focusLost(FocusEvent e) {
                            btn.setBorder(new EmptyBorder(1, 1, 1, 1));
                        }
                    });
                    btn.setBorder(new EmptyBorder(1, 1, 1, 1));
                    btn.setIcon(new ImageIcon(scaled));
                    btn.putClientProperty("image", image);
                    add(btn);
                    btn.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            JButton btn = (JButton) e.getSource();
                            BufferedImage img = (BufferedImage) btn.getClientProperty("image");
                            // Do stuff
                        }
                    });
                }
            }
    
            public class RoundBorder extends AbstractBorder {
                @Override
                public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                    g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                    g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
                    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    g2d.setColor(UIManager.getColor("Focus.color"));
                    g2d.drawRoundRect(x, y, width - 1, height - 1, 20, 20);
                }
            }
    
        }
    }
    

    为什么要用按钮?

    1. 它们是为这个目的而建造的;他们表现出专注;他们在“采取行动”时提供反馈,从而导致
    2. 免费支持键盘输入;你可以 标签 在按钮之间,用键盘“操作”它们——你甚至可以不费吹灰之力地设置键盘快捷键。

    但是

    你可以。。。

    使用 JList ,这将允许您使用箭头键进行导航

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.EventQueue;
    import java.awt.Image;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.DefaultListCellRenderer;
    import javax.swing.DefaultListModel;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        JFrame frame = new JFrame();
                        frame.add(new TestPane());
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() throws IOException {
                setLayout(new BorderLayout());
                DefaultListModel<BufferedImage> model = new DefaultListModel<>();
                for (int index = 1; index < 13; index++) {
                    BufferedImage image = ImageIO.read(getClass().getResource("/images/Cute" + index + ".png"));
                    model.addElement(image);
                }
    
                JList list = new JList(model);
                list.setCellRenderer(new BufferedImageListRenderer());
                list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
                list.setVisibleRowCount(4);
    
                list.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        BufferedImage image = (BufferedImage)list.getSelectedValue();
                        // Do stuff
                    }
                });
                list.setSelectedIndex(0);
    
                add(new JScrollPane(list));
            }
    
            protected class BufferedImageListRenderer extends DefaultListCellRenderer {
                @Override
                public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                    if (value instanceof BufferedImage) {
                        setText(null);
                        // This is expensive, I'd normally have it cached somewhere
                        Image scaled = ((BufferedImage)value).getScaledInstance(50, -1, Image.SCALE_SMOOTH);
                        setIcon(new ImageIcon(scaled));
                    }
                    return this;
                }
            }
    
        }
    }
    

    看见 How to Use Lists

        2
  •  1
  •   DevilsHnd - 退した    2 年前

    或者你可以。。。

    只需使用你真正想要的JLabel。我只是想借钱 疯狂的程序员 编码并用JLabel替换按钮。我还添加了一个类成员JLabel变量来保存恰好被鼠标指针点击的JLabel对象。在下面的演示图像中,请参见标题栏如何指示具有当前焦点的图像。如果你碰巧想做这样的事情,图像周围的红色边框也是一个很好的指示器。

    enter image description here

    下面是一个可运行的代码:

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.Image;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class Main {
        JFrame frame;
        JLabel labelWithFocus;
        
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        frame = new JFrame();
                        frame.setAlwaysOnTop(true);
                        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        frame.add(new TestPane());
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }
    
        public JLabel getLabelWithFocus() {
            return labelWithFocus;
        }
    
        
        public class TestPane extends JPanel {
    
            private static final long serialVersionUID = 40666L;
    
            public TestPane() throws IOException {
                GridLayout layout = new GridLayout(-1, 3);
                layout.setHgap(40);
                layout.setVgap(15);
                setLayout(layout);
                setBackground(Color.WHITE);
                for (int index = 1; index < 13; index++) {
                    BufferedImage image = ImageIO.read(getClass().getResource("/images/Cute" + index + ".png"));
                    Image scaled = image.getScaledInstance(50, -1, Image.SCALE_SMOOTH);
                    JLabel lbl = new JLabel(new ImageIcon(scaled));
                    lbl.setName("Cute" + index + ".png");
                    lbl.putClientProperty("image", image);
                    add(lbl);
                    lbl.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            if (labelWithFocus != null ) {
                                labelWithFocus.setBorder(null);
                                // Drop Focus if it currently has focus and is clicked on again.
                                if (lbl.getName().equals(labelWithFocus.getName())) {
                                    frame.setTitle("");
                                    labelWithFocus = null;
                                    return;
                                }
                            }
                            labelWithFocus = (JLabel) e.getSource();
                            BufferedImage img = (BufferedImage) labelWithFocus.getClientProperty("image");
                            lbl.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
                            frame.setTitle(labelWithFocus.getName());
                            
                            // Do anything else you want...
                        }
                        
                        @Override
                        public void mouseEntered(MouseEvent e) {
                            JLabel lbl = (JLabel) e.getSource();
                            lbl.setBorder(BorderFactory.createLineBorder(Color.decode("#2eb8b8"), 1));
                        }
                        
                        @Override
                        public void mouseExited(MouseEvent e) {
                            JLabel lbl = (JLabel) e.getSource();
                             if (lbl == labelWithFocus) {
                                lbl.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
                            }
                            else {
                                lbl.setBorder(null);
                            }
                        }
                    });
                }
            }
        }
    }