如何在自定义 JComponent 中正确实现 MouseInputListener

How to properly implement MouseInputListener in custom JComponent

我正在尝试为我构建的自定义组件实现一些 mouseListener 功能。但是,我 运行 遇到了让它工作的一些障碍。这是自定义 JComponent 的代码。

import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputListener;

import org.w3c.dom.events.MouseEvent;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseListener;
import java.lang.reflect.Field;
import java.util.prefs.Preferences;

public class PhotoComponent extends JComponent implements MouseInputListener{
    
    private ImageIcon pic;
    Boolean flipped = false;

    public PhotoComponent(){

    }

    public PhotoComponent(ImageIcon p){
        pic=p;
    }

    @Override
    public Dimension getPreferredSize(){
        if(pic==null){
            return new Dimension(0,0);
        }
        return new Dimension(pic.getIconWidth(), pic.getIconHeight());
    }

    @Override
    protected void paintComponent(Graphics g){
        if (flipped==false){
            pic.paintIcon(this, g, 0, 0);
        }

        if (flipped==true){
            g.setColor(Color.WHITE);
            g.drawRect(0, 0, pic.getIconWidth(), pic.getIconHeight());
            g.fillRect(0,0, pic.getIconWidth(), pic.getIconHeight());
        }
    

    }

    
    @Override
    public void mouseClicked(MouseEvent e){
        if(e.getClickCount()==2){
            flipped=!flipped;
            repaint();
            jl.settext("hi");
        }
    }

    @Override
    public void mousePressed(MouseEvent e){
        //lol
    }

    @Override
    public void mouseReleased(MouseEvent e){
        //lol
    }

    @Override
    public void mouseEntered(MouseEvent e){
        //lol
    }

    @Override
    public void mouseExited(MouseEvent e){
        //lol
    }


}

目标是通过双击鼠标在真实图像和全白图像之间切换。该组件将在下面的代码中使用。


public class Base extends JFrame {
    private JPanel radio, buttons, tags, container, statusContainer;
    private JScrollPane mainScroll;
    private JButton next, prev, delete;
    private JMenuBar jmb;
    private JMenu file, view;
    private JMenuItem impo;
    private JLabel jl;
    private ArrayList<PhotoComponent> picList;
    private int pos;

    public static void main(String[] args) {
        new Base();
    }

    public Base(){
        setTitle("Placeholder");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500,500);
        setResizable(true);
        
        menusAndLabels();

        pack();
        setVisible(true);
    }

    public void menusAndLabels(){
        jmb = new JMenuBar();
        setJMenuBar(jmb);
        file=new JMenu("File");
        statusContainer = new JPanel();
        add(statusContainer, BorderLayout.SOUTH);


        jmb.add(file);

        impo = new JMenuItem("Import");

        //currentPic= new PhotoComponent();
        picList= new ArrayList<PhotoComponent>(5);
        pos = 0;
        mainScroll = new JScrollPane();
        
        
        add(mainScroll);
        
        impo.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent fo){
                JFileChooser chooser= new JFileChooser("");
                FileFilter filter = new FileNameExtensionFilter("Graphics", "jpg","jpeg","png");
                chooser.setFileFilter(filter);
                chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                chooser.setMultiSelectionEnabled(true);
                int response = chooser.showOpenDialog(null);

                if(response == JFileChooser.APPROVE_OPTION){
                   File[] chosen = chooser.getSelectedFiles();
                    for (File f:chosen) {
                        if(f.isDirectory()){
                            File[] temp=f.listFiles();
                            for (File x:temp){;
                                ImageIcon ii =new ImageIcon(x.getAbsolutePath());
                                picList.add(new PhotoComponent(ii));
                            }
                        }
                        else{
                            ImageIcon ii =new ImageIcon(f.getAbsolutePath());
                            picList.add(new PhotoComponent(ii));
                            }
                            
                        }
                    mainScroll.setViewportView(picList.get(pos));
                    ///mainScroll.addMouseListener(picList.get(pos));
                    mainScroll.setVisible(true);
                    
                    validate();
                    }
                else {
                    JOptionPane.showInputDialog("oops somethings wrong");
                }
                    
                }
                
            });
    

        file.add(impo);
    }
}

到目前为止,当我尝试时,我的鼠标侦听器没有任何响应。我做错了什么,我怎样才能更好地实施它?

我尝试将 addMouseListener(this) 添加到组件中,但它一直给我语法错误并告诉我它“需要主体”。我的代码错误一直提示我添加:

@Override
    public synchronized void addMouseListener(MouseListener l) {
        // TODO Auto-generated method stub
        super.addMouseListener(l);
    }

但我不完全确定该怎么做。

So far I get no response from my mouse listener

在组件的什么地方添加MouseListener?

您需要将侦听器添加到 class 以便它可以响应事件。在您的构造函数中,您需要如下代码:

addMouseListener( this );

阅读 Swing 教程中关于 How to Write a MouseListener 的部分以获得工作示例。