英文:
Adding KeyAdapter to JComponent
问题
尝试将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");
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));
scrollPane.setVisible(true);
validate();
} else {
JOptionPane.showInputDialog("oops somethings wrong");
}
}
});
file.add(importbutton);
}
}
英文:
Trying to add a keyListener to this component, however I am getting no response. I want it to be respond whenever the component is displayed in the scroll Panel. I've been able to get it to work when adding it to JPanels. Is there something I should be doing differently for my component?
This the the Component I seek to implement Keylistener on.
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);
}
}
This is the program I am calling it on.
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
得分: 0
有很多方法可以解决这个问题。其中之一是使用 KeyEventDispatcher
如果你需要一些全局按键映射。
另一种方法是将 KeyListener
添加到你的父级 JFrame
,以捕获按键事件并将其委托给当前组件。看看这个!
附言: 我并不是说这是一个最佳解决方案,但我已经验证过 - 它有效。你可以使用它,或者它可以成为你自己解决方案的起点。
public class Base extends JFrame implements ActionListener, KeyListener {
// ...(省略其他代码)...
@Override
public void keyPressed(KeyEvent event) {
if (pictureIndex != -1)
pictures.get(pictureIndex).keyPressed(event);
}
// ...(省略其他代码)...
}
public class PhotoComponent extends JComponent {
// ...(省略其他代码)...
public void keyPressed(KeyEvent event) {
System.out.println("keyPressed: " + event.getKeyCode());
}
// ...(省略其他代码)...
}
注意:由于您要求只返回翻译后的代码部分,我已经将代码中的英文注释也保留在了原文状态。如果您需要注释也进行翻译,请提供相应的要求。
英文:
Ther're many ways how to solve this problem. One of them use KeyEventDispatcher
if you need some global key mappings.
Another way is to add KeyListener
to you parent JFrame
to catch key pressed event and delegate it to the current component. Check this out!
P.S. I am not saying that this is an optimal solution, but I have checked it - it works. You can use it or it can be a start point for your own solution.
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);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论