问题描述
尝试将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);
}
}
这是我正在调用的程序。
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);
}
}
解决方法
有很多方法可以解决此问题。如果您需要一些全局键映射,则其中之一使用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);
}
}