我有一个,JFrame
并且里面JFrame
有两个JPanel
。当我按下一个键时,他们两个都必须收听此键事件并采取行动。我要处理所有键盘事件,并将它们传递给两个JPanel
s。你知道怎么做吗?
编辑:由于他们必须做不同的事情,所以我需要两个不同的侦听器,对不起您不明确。
Edit2:我编写了一个简单的代码来向您展示问题。当我按下向上键时,两个JPanel
显示的s都必须更改其字符串。在此代码中,只有其中一个实际反应!
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
*
* @author antonioruffolo
*/
public class TwoPanelsTest extends JFrame {
public TwoPanelsTest() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setSize(800, 600);
PanelTest panelTest1= new PanelTest();
PanelTest panelTest2= new PanelTest();
GridBagLayout layout= new GridBagLayout();
this.setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.ipadx = 220;
c.ipady = 390;
c.insets.right= 0;
c.insets.left=30;
layout.setConstraints(panelTest1, c);
this.add(panelTest1);
layout.setConstraints(panelTest2, c);
c.ipadx = 220;
c.ipady = 390;
c.insets.right=250;
c.insets.left=50;
this.add(panelTest2);
setVisible(true);
setLocationRelativeTo(null);
setTitle("Test");
setFocusable(false);
}
private class PanelTest extends JPanel{
private String string="I'm not called by the event";
private InputMap inputmap;
private ActionMap actionmap;
public PanelTest(){
setFocusable(false);
setDoubleBuffered(true);
this.setBackground(Color.WHITE);
inputmap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputmap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
actionmap = getActionMap();
actionmap.put("up", new ActionController(this));
}
public void setString(String string){
this.string=string;
}
@Override
public void paintComponent( Graphics g){
super.paintComponent(g);
Font infoFont= new Font("OCR A Std", Font.BOLD, 10);
g.setFont(infoFont);
g.drawString(string, 10, 50);
}
}//PanelTest
private class ActionController extends AbstractAction{
private PanelTest panel;
public ActionController (PanelTest panel){
this.panel=panel;
}
@Override
public void actionPerformed(ActionEvent ae) {
panel.setString("Action performed");
panel.repaint();
}
}
public static void main(String[] args) {
TwoPanelsTest t = new TwoPanelsTest();
}
}
代替KeyListener
,使用
按键绑定
,Action
并对每个面板都有不同的实现。通过使用WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
输入映射,两个面板都可以响应。
附录:由于搜索是在找到有效的键绑定之后结束的,因此下面的示例 将 事件 转发
到a的元素List<MyPanel>
,每个元素可以通过available进行不同的响应Action
。
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/** @see http://stackoverflow.com/q/10011564/230513 */
public class TwoPanelsTest extends JFrame {
private MyPanel one = new MyPanel("One");
private MyPanel two = new MyPanel("Two");
private List<MyPanel> list = Arrays.asList(one, two);
public TwoPanelsTest() {
super("TwoPanelsTest");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(0, 1, 10, 10));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
panel.add(one);
panel.add(two);
panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
panel.getActionMap().put("up", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
for (MyPanel panel : list) {
panel.getAction().actionPerformed(e);
}
}
});
this.add(panel);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private static class MyPanel extends JPanel {
private String string = " will be updated though its action.";
private Action action = new UpdateAction(this);
private String name;
private JLabel label;
public MyPanel(String name) {
this.name = name;
this.label = new JLabel(name + string, JLabel.CENTER);
this.setLayout(new GridLayout());
this.setFocusable(true);
this.add(label);
}
public Action getAction() {
return action;
}
private void update() {
label.setText(name + ": " + System.nanoTime());
}
private static class UpdateAction extends AbstractAction {
private MyPanel panel;
public UpdateAction(MyPanel panel) {
this.panel = panel;
}
@Override
public void actionPerformed(ActionEvent ae) {
panel.update();
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
TwoPanelsTest t = new TwoPanelsTest();
}
});
}
}
问题内容: 我有两个分别称为“左”和“右”。“左”按钮将矩形对象向左移动,“右”按钮将其向右移动。我在班上有一个充当单击任一按钮时的侦听器。但是,我希望单击每个动作时都会发生不同的动作。如何区分点击的? 问题答案: 将actionCommand设置到每个按钮。 //将动作命令设置到两个按钮上。 更新:
我通过infinispan缓存添加了CacheEntryExpired侦听器的n实现。addListener()方法。 侦听器事件在条目过期时激发。问题是,每次事件触发两次。 我验证(使用调试器和cache.getListeners())缓存不包含我的同一个侦听器的两个实例。getListeners的结果是: 所以只有一个听众。侦听器实现接口: 一个实现看起来像: 但是从接口中删除@CacheEn
问题内容: 我需要使用同一端口收听2个不同的多播组。会从和那里听。两个多播组都使用相同的文件,但我无法控制它。 运行程序时,我在每个程序中都接收到两个多播流,即和上广播的数据包。我怀疑问题是由于通用端口引起的。这是我用来订阅多播的代码: 如何在每个程序中过滤特定的多播组? 问题答案: 如果你改变 至 您可能会获得更大的成功。 (如果您更改程序以使用,则可以使其适应未来。)
我有一个监听两个不同端口的TCP服务器。我创建了两个不同的套接字,一个在端口8888上,一个在端口6634上。我监听这些端口,然后我在FD_SET中添加两个套接字,并将它们传递给Select()函数...当套接字准备好读取时,我检查FD_ISSET,看看哪个端口上有消息要读取。 不管怎样,当我连接到8888端口时,构思是成功的,我可以向服务器发送和接收。。。当我在客户端ctrl c时,选择函数再次
是否可能有一个全局鼠标运动监听器,根据点击的JPanel的内容而具有不同的效果(仅使用一个鼠标运动监听器)? 例如:我有一个JFrame,其中添加了两个JPanel,并在JFrame中添加了一个鼠标运动监听器。当我点击一个JPanel时,我希望屏幕能够调整大小,但当我点击另一个JPanel时,我希望JFrame能够被拖动。我认为这可以通过使用JLabel来完成,使用JLabel的文本进行检查,与J
问题内容: 我尝试将两个jpanel并排放置,但是在这一刻,我无法执行我想要的代码, `我尝试再放一个jpanel: 此代码无效,也不会出错。 问题答案: 如果我正确理解了您的问题,则希望并排放置2个JPanel。查看布局GridLayout。 您需要setLayout(new GridLayout(1,2)); 上面写着1 Row,2 Col