【问题标题】:Adding KeyAdapter to JComponent将 KeyAdapter 添加到 JComponent
【发布时间】:2021-01-09 07:32:31
【问题描述】:

试图向这个组件添加一个 keyListener,但是我没有得到任何响应。我希望它在组件显示在滚动面板中时做出响应。将它添加到 JPanels 时,我已经能够让它工作。我应该为我的组件做些不同的事情吗?

这是我试图在其上实现 Keylistener 的组件。

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

import java.awt.FontMetrics;

import java.awt.event.MouseEvent;
import java.awt.Point;
import java.util.ArrayList;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;



public class PhotoComponent extends JComponent implements MouseInputListener{
    
    private ImageIcon pic;
    
    Boolean checkVac=false;
    Boolean checkSchool=false;
    Boolean checkFam= false;
    Boolean checkWork = false;
    Boolean flipped = false;
    Boolean penButton=false;
    boolean textButton=false;

    
    public PhotoComponent(){
    }

    public PhotoComponent(ImageIcon p){
        pic=p;
        setRequestFocusEnabled(true);
        requestFocus();
        addKeyListener(new KeyAdapter(){
            public void keyTyped(KeyEvent e) {
                System.out.println("hello");
                }
        });
    }

    @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){
        pic.paintIcon(this, g, 0, 0);   
    }
  
}

这是我正在调用的程序。

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.event.MouseInputListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JPanel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.io.*;

public class Base extends JFrame {
    private JPanel  statusContainer;
    private JScrollPane scrollPane;
    private JMenuBar jmb;
    private JMenu file;
    private JMenuItem importbutton;
    private ArrayList<PhotoComponent> picList;
    private int picIndex;

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

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

        pack();
        setVisible(true);
    }

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


        jmb.add(file);

        importbutton = new JMenuItem("Import");

        //currentPic= new PhotoComponent();
        picList= new ArrayList<PhotoComponent>(5);
        picIndex = 0;
        scrollPane = new JScrollPane();
        
        
        add(scrollPane);
        
        importbutton.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));
                            }
                            
                        }
                    scrollPane.setViewportView(picList.get(picIndex));
                    ///mainScroll.addMouseListener(picList.get(pos));
                    scrollPane.setVisible(true);
                    
                    validate();
                    }
                else {
                    JOptionPane.showInputDialog("oops somethings wrong");
                }
                    
                }
                
            });
    

        file.add(importbutton);
    }
}

【问题讨论】:

  • 1) 对于 Swing,我们通常使用 key bindings 而不是较低级别的 KeyListener。 2) 为了尽快获得更好的帮助,edit 添加minimal reproducible exampleShort, Self Contained, Correct Example。一个可编译、可运行的示例应该不超过 40-50 行代码。
  • 另外评论@AndrewThompson:您可能应该在PhotoComponent 的构造函数中添加setFocusable(true);。如果没有帮助,请按照 Andrew 的建议提供minimal reproducible example
  • requestFocus(); - 1) 阅读 API。不应使用此方法。 API 将告诉您要使用的适当方法。 2)在构造函数中添加这个语句不会做任何事情。您只能请求将焦点放在框架上可见的组件上。在构造函数中,组件尚未添加到框架中。 3) 为什么你现在使用 KeyListener?您最后一个代码的问题不是 MouseListener 本身。问题在于 MouseListener 中的代码。您在发布答案之前删除了您的问题。

标签: java swing awt keylistener


【解决方案1】:

有很多方法可以解决这个问题。如果您需要一些全局键映射,其中之一使用KeyEventDispatcher

另一种方法是将KeyListener 添加到您的父级JFrame 以捕获按键事件并将其委托给当前组件。看看这个!

P.S. 我并不是说这是一个最佳解决方案,但我已经检查过了 - 它有效。您可以使用它,也可以作为您自己解决方案的起点。

public class Base extends JFrame implements ActionListener, KeyListener {

    private final JPanel statusContainer = new JPanel();
    private final JScrollPane scrollPane = new JScrollPane();
    private final JMenuBar menubar = new JMenuBar();
    private final JMenu file = new JMenu("File");
    private final JMenuItem importButton = new JMenuItem("Import");

    private List<PhotoComponent> pictures = Collections.emptyList();
    private int pictureIndex = -1;

    public static void main(String... args) {
        SwingUtilities.invokeLater(() -> new Base().setVisible(true));
    }

    public Base() {
        init();
    }

    private void init() {
        setTitle("Placeholder");
        setJMenuBar(menubar);

        add(statusContainer, BorderLayout.SOUTH);
        add(scrollPane);

        file.add(importButton);
        menubar.add(file);
        setResizable(true);

        importButton.addActionListener(this);
        addKeyListener(this);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(500, 500);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == importButton)
            onImportButton();
    }

    private void onImportButton() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("Graphics", "jpg", "jpeg", "png"));
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        fileChooser.setMultiSelectionEnabled(true);

        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            pictures = getPictures(fileChooser);
            pictureIndex = pictures.isEmpty() ? -1 : 0;

            scrollPane.setViewportView(pictureIndex == -1 ? null : pictures.get(pictureIndex));
            scrollPane.setVisible(true);

            validate();
        } else
            JOptionPane.showInputDialog("oops somethings wrong");
    }

    private static List<PhotoComponent> getPictures(JFileChooser fileChooser) {
        List<PhotoComponent> pictures = new ArrayList<>();

        for (File fileOrDir : fileChooser.getSelectedFiles())
            for (File file : getFiles(fileOrDir))
                pictures.add(new PhotoComponent(new ImageIcon(file.getAbsolutePath())));

        return pictures;
    }

    private static List<File> getFiles(File fileOrDir) {
        if (fileOrDir.isDirectory())
            return Arrays.asList(Objects.requireNonNull(fileOrDir.listFiles()));
        return Collections.singletonList(fileOrDir);
    }

    @Override
    public void keyTyped(KeyEvent event) {
    }

    @Override
    public void keyPressed(KeyEvent event) {
        if (pictureIndex != -1)
            pictures.get(pictureIndex).keyPressed(event);
    }

    @Override
    public void keyReleased(KeyEvent event) {
    }
}

public class PhotoComponent extends JComponent {

    private final ImageIcon picture;

    public PhotoComponent(ImageIcon picture) {
        this.picture = picture;
    }

    public void keyPressed(KeyEvent event) {
        System.out.println("keyPressed: " + event.getKeyCode());
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(picture.getIconWidth(), picture.getIconHeight());
    }

    @Override
    protected void paintComponent(Graphics g) {
        picture.paintIcon(this, g, 0, 0);
    }

}

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 2021-12-20
    • 1970-01-01
    • 2022-12-07
    • 2015-02-04
    • 1970-01-01
    • 2020-11-06
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多