简体   繁体   English

如何将焦点设置到图像或label?[Java Swing]

[英]How to set the focus to an image or a label ?[Java Swing]

Let's say I have several images, each of them in a label, is there a way to set the focus on one of the images or JLabels by clicking at it and do some image processing on the clicked image (blur, black and white...).假设我有几张图片,每张图片都在 label 中,有没有一种方法可以通过单击其中一张图片或 JLabel 来设置焦点,并对点击的图片进行一些图像处理(模糊、黑白...... .).

Any help is appreciated任何帮助表示赞赏

You could...你可以...

Use JButton s instead, it's kind of what they are designed for...改用JButton s,这是它们的设计目的......

在此处输入图像描述

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

    }
}

See How to Use Buttons, Check Boxes, and Radio Buttons查看如何使用按钮、复选框和单选按钮

Don't want the button "fill" effects?不想要按钮“填充”效果?

That becomes a little more complicated, but not impossible...这变得有点复杂,但并非不可能......

在此处输入图像描述

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

    }
}

Why use buttons?为什么要使用按钮?

  1. They are kind built for the purpose;它们是为此目的而建造的; they show focus;他们表现出专注; they provide feedback when "actioned", which leads into他们在“采取行动”时提供反馈,这会导致
  2. Free support for keyboard input;免费支持键盘输入; you can Tab between the buttons and "action" them with the keyboard - you could even set up keyboard shortcuts without much effort.您可以在按钮之间使用Tab键并使用键盘“操作”它们 - 您甚至可以毫不费力地设置键盘快捷键。

but...但...

You could...你可以...

Use a JList , which would allow you to use the arrow keys for navigation使用JList ,这将允许您使用箭头键进行导航

在此处输入图像描述

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

    }
}

See How to Use Lists查看如何使用列表

Or you could...或者你可以...

Just use the JLabels like you actually want to.只需像您真正想要的那样使用 JLabel。 I'm just going to borrow MadProgrammer's code and replace the buttons with JLabels.我只是想借用MadProgrammer 的代码并用 JLabels 替换按钮。 I've also added a class member JLabel variable to hold the JLabel object that happened to be clicked upon by the Mouse Pointer.我还添加了一个 class 成员 JLabel 变量来保存恰好被鼠标指针单击的 JLabel object。 In the demo image below, see how the title bar indicates the image which has current focus.在下面的演示图像中,查看标题栏如何指示具有当前焦点的图像。 A red border around the image is also a pretty good indicator if you happen to want to do such a thing.如果您碰巧想要做这样的事情,图像周围的红色边框也是一个很好的指示。

在此处输入图像描述

Here is a runnable code:这是一个可运行的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM