❶ java 事件监听
貌似没问题啊,执行的也好好的。
你想说的一半距离是指什么?
g.fillRect(x, y, 15, 15);
你在这里设置的长宽都是15
而你的speed=10;
那这样每次只移动边长的2/3有什么好奇怪的?
你的x、y、speed
都是私有变量,如果没有你注释掉的方法接口,你是不能直接修改这三个变量的值的
你可以用setX(),setY(),setSpeed()分别来设置你的方块的x坐标,y坐标,和每次按键的移动步长
你可以用getX(),getY()获取你方块当前的x坐标和y坐标,返回值是int类型
❷ 关于JAVA事件监听
你这个问题是由于焦点(Focus)不正确引起的问题.
在窗口打开之后,如果焦点落在Frame上面,按键被Frame捕获,提示输出,如果焦点落在Button上面,刚按键被Button捕获,当然就没有输出.
更改方法有如下建议:
1.this.setFocusable(true);加在构造函数最后,可以保证Frame可以响应键盘事件,但是按下按扭之后焦点转移,键盘事件不再被Frame响应,因此需要按Tab键重新让Frame得到焦点.(不推荐此方法,不知道按Tab键的用户就惨了...)
2. 将键盘响应KeyListener分别注册给所有的Button.
最后代码如下:
import java.awt.*;
import java.awt.event.*;
public class ButtonTest extends Frame implements KeyListener,ActionListener{
private Button b1;
private Button b2;
public ButtonTest(int i,int j) {
addKeyListener(this);
setLayout(new FlowLayout(1));
b1=new Button("yellow");
b1.addActionListener(this);
b1.addKeyListener(this);
b2=new Button("blue");
b2.addActionListener(this);
b2.addKeyListener(this);
setSize(i, j);
add(b1);add(b2);
pack();
setVisible(true);
this.setFocusable(true);
}
//实现ActionListener接口方法
public void actionPerformed(ActionEvent a) {
if (a.getActionCommand().equals("yellow")) {
b1.setBackground(Color.red);
b2.requestFocus();//点击button1时把事件焦点给b2
} else if (a.getActionCommand().equals("blue")) {
b2.setBackground(Color.BLUE);
}
}
//实现keylistener的3个方法
public void keyTyped(KeyEvent e){
System.out.println("KeyTyped"+" "+e);
}
public void keyPressed(KeyEvent e){
System.out.println("KeyPressed"+" "+e);
}
public void keyReleased(KeyEvent e){
System.out.println("KeyReleased"+" "+e);
}
public static void main(String[] args) {
ButtonTest my=new ButtonTest(300,300);
my.setSize(200,200);
}
}
❸ java中的事件监听有什么作用,怎么用,用在什么地方
主要用于 GUI界面 比如 对JButton进行监听,只要加入监听事件,就可写你想发生的结果。如果以后从事web编程而不从事scoket编程,这几乎没有多大的用处。相对而言,j学习ava的事件监听,很容易上手。
❹ java 事件监听
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.*;
public class Demo1 extends JFrame implements ActionListener {
int i=0;
ArrayList al = new ArrayList(2);
JPanel img=new JPanel();
public static void main(String[] args) {
// TODO 自动生成方法存根
Demo1 demo1 = new Demo1();
}
public Demo1() {
JLabel jl1=new JLabel(new ImageIcon("images/2.jpg"));
JLabel jl2=new JLabel(new ImageIcon("images/3.jpg"));
al.add(jl1);
al.add(jl2);
System.out.println(i);
JLabel jL = (JLabel) al.get(i);
img.add(jL, BorderLayout.CENTER);
this.add(img, BorderLayout.CENTER);
JButton jb1 = new JButton("上一张");
JButton jb2 = new JButton("下一张");
JPanel jp = new JPanel();
this.add(jp, BorderLayout.SOUTH);
jp.add(jb1, BorderLayout.EAST);
jp.add(jb2, BorderLayout.WEST);
jb1.addActionListener(this);
jb1.setActionCommand("上一张");
jb2.addActionListener(this);
jb2.setActionCommand("下一张");
this.setSize(560, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
// TODO 自动生成方法存根
if (arg0.getActionCommand().equals("下一张")) {
i++;
if(i>=al.size()){//翻到最后一张了,重新从第一张开始
i=0;
}
img.removeAll();
img.add((JLabel)al.get(i), BorderLayout.CENTER);
this.validate();//刷新组件
this.repaint();
}
if (arg0.getActionCommand().equals("上一张")) {
i--;
if(i<0){
i=al.size()-1;
}
img.removeAll();
img.add((JLabel)al.get(i), BorderLayout.CENTER);
this.validate();
this.repaint();
}
}
}
❺ java中的事件监听是怎么回事
不是通过线程实现的,它是通过一种注册--通知机制实现的。在java的设计模式中,有一种模式叫:观察者模式,和这个类似。举个例子,本例子是一个简单的监听当数据发生变化时要做的操作。 1,我们先定义一个接口,可以让多个监听者实现 public interface IDataListen {public void update(Object event,Object msg);}2,实现一监听者 public class DataListen implements IDataListen{ @Override public void update(Object event, Object arg) { // TODO Auto-generated method stub System.out.println("数据发生了变化"); }}3,被监听者 public class DataManager{ private List<IDataListen> listenList = new ArrayList<>(); public void notifyListen(Object event,Object msg){ for(IDataListen dataListen : listenList){ dataListen.update(null, null); } } public void addListen(IDataListen dataListen){ listenList.add(dataListen); } public void updateData(Object msg){ this.notifyListen(null, msg); } public static void main(String[] args) { DataManager dataManager = new DataManager(); IDataListen dataListen1 = new DataListen(); ...
❻ java 事件监听
比如你在有两个键
JButton K = new JButton("K");
JButton T = new JButton("T");
且都已添加了监听,那么在接口实现方法中写:
public void actionPerformed(ActionEvent ae)
{
//这样K键和T键就有相同的作用了(如果只是实现相同的作用没必要嵌套啊)
if(ae.getSouce==K || ae.getSouce== T)
{
//按钮处理方法
}
}
❼ java事件监听
你只要改下下面的就可以了:
JButton b,v;//在方法外面声明JButton 对象(加上这一行)
public Test2() {
super("java实例");
b = new JButton("点击");//把着两行的JButton去掉就可以了,你之前是把它声明在方法体内部的,在添加监听器匹配对象是那个b拿不到,其他的都没有什么问题的
v = new JButton("确定");
getContentPane().add(b);
getContentPane().add(v);
setLayout(new FlowLayout());
b.addActionListener(this);
v.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(200, 200, 300, 300);
b.setBounds(0, 0, 30, 40);
v.setBounds(50, 50, 30, 40);
setVisible(true);
}
❽ java 事件监听
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class LayoutTest extends JFrame implements ActionListener {
JButton jb1 = null;
JButton jb2 = null;
JButton jb3 = null;
JButton jb4 = null;
JButton jb5 = null;
public LayoutTest() {
this.setSize(200, 200);
this.setVisible(true);
this.setLayout(new BorderLayout());
jb1 = new JButton("up");
jb1.setActionCommand("up");
jb1.addActionListener(this);
jb2 = new JButton("down");
jb2.setActionCommand("down");
jb2.addActionListener(this);
jb3 = new JButton("left");
jb3.setActionCommand("left");
jb3.addActionListener(this);
jb4 = new JButton("right");
jb4.setActionCommand("right");
jb4.addActionListener(this);
jb5 = new JButton("center");
jb5.setActionCommand("center");
jb5.addActionListener(this);
// this.add(wp);
this.add("North", jb1);
this.add("South", jb2);
this.add("West", jb3);
this.add("East", jb4);
this.add("Center", jb5);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
LayoutTest lt = new LayoutTest();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getActionCommand().equals("up")) {
System.out.println("You have clicked up!");
} else if (e.getActionCommand().equals("down")) {
System.out.println("You have clicked down!");
} else if (e.getActionCommand().equals("left")) {
System.out.println("You have clicked left!");
} else if (e.getActionCommand().equals("right")) {
System.out.println("You have clicked right");
} else if (e.getActionCommand().equals("center")) {
System.out.println("You have clicker center!");
}
}
}
❾ java设计模式-回调、事件监听器、观察者模式
转自( https://my.oschina.net/u/923324/blog/792857 )
背景
关于设计模式,之前笔者写过工厂模式,最近在使用gava ListenableFuture时发现事件监听模型特别有意思,于是就把事件监听、观察者之间比较了一番,发现这是一个非常重要的设计模式,在很多框架里扮演关键的作用。
回调函数
为什么首先会讲回调函数呢?因为这个是理解监听器、观察者模式的关键。
什么是回调函数
所谓的回调,用于回调的函数。 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数。 有这么一句通俗的定义:就是程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法。
举个例子:
这里有两个实体:回调抽象接口、回调者(即程序a)
回调接口(ICallBack )
public interface ICallBack {
public void callBack();
}
回调者(用于调用回调函数的类)
public class Caller {
}
回调测试:
public static void main(String[] args) {
Caller call = new Caller();
call.call(new ICallBack(){
控制台输出:
start...
终于回调成功了!
end...
还有一种写法
或实现这个ICallBack接口类
class CallBackC implements ICallBack{
@Override
public void callBack() {
System.out.println("终于回调成功了!");
}
}
有没有发现这个模型和执行一个线程,Thread很像。 没错,Thread就是回调者,Runnable就是一个回调接口。
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("回调一个新线程!");
}}).start();
Callable也是一个回调接口,原来一直在用。 接下来我们开始讲事件监听器
事件监听模式
什么是事件监听器
监听器将监听自己感兴趣的事件一旦该事件被触发或改变,立即得到通知,做出响应。例如:android程序中的Button事件。
java的事件监听机制可概括为3点:
java的事件监听机制涉及到 事件源,事件监听器,事件对象 三个组件,监听器一般是接口,用来约定调用方式
当事件源对象上发生操作时,它将会调用事件监听器的一个方法,并在调用该方法时传递事件对象过去
事件监听器实现类,通常是由开发人员编写,开发人员通过事件对象拿到事件源,从而对事件源上的操作进行处理
举个例子
这里我为了方便,直接使用jdk,EventListener 监听器,感兴趣的可以去研究下源码,非常简单。
监听器接口
public interface EventListener extends java.util.EventListener {
//事件处理
public void handleEvent(EventObject event);
}
事件对象
public class EventObject extends java.util.EventObject{
private static final long serialVersionUID = 1L;
public EventObject(Object source){
super(source);
}
public void doEvent(){
System.out.println("通知一个事件源 source :"+ this.getSource());
}
}
事件源
事件源是事件对象的入口,包含监听器的注册、撤销、通知
public class EventSource {
//监听器列表,监听器的注册则加入此列表
private Vector<EventListener> ListenerList = new Vector<EventListener>();
//注册监听器
public void addListener(EventListener eventListener){
ListenerList.add(eventListener);
}
//撤销注册
public void removeListener(EventListener eventListener){
ListenerList.remove(eventListener);
}
//接受外部事件
public void notifyListenerEvents(EventObject event){
for(EventListener eventListener:ListenerList){
eventListener.handleEvent(event);
}
}
}
测试执行
public static void main(String[] args) {
EventSource eventSource = new EventSource();
}
控制台显示:
通知一个事件源 source :openWindows
通知一个事件源 source :openWindows
doOpen something...
到这里你应该非常清楚的了解,什么是事件监听器模式了吧。 那么哪里是回调接口,哪里是回调者,对!EventListener是一个回调接口类,handleEvent是一个回调函数接口,通过回调模型,EventSource 事件源便可回调具体监听器动作。
有了了解后,这里还可以做一些变动。 对特定的事件提供特定的关注方法和事件触发
public class EventSource {
...
public void onCloseWindows(EventListener eventListener){
System.out.println("关注关闭窗口事件");
ListenerList.add(eventListener);
}
}
public static void main(String[] args) {
EventSource windows = new EventSource();
/**
* 另一种实现方式
*/
//关注关闭事件,实现回调接口
windows.onCloseWindows(new EventListener(){
}
这种就类似于,我们的窗口程序,Button监听器了。我们还可以为单击、双击事件定制监听器。
观察者模式
什么是观察者模式
观察者模式其实原理和监听器是一样的,使用的关键在搞清楚什么是观察者、什么是被观察者。
观察者(Observer)相当于事件监器。有个微博模型比较好理解,A用户关注B用户,则A是B的观察者,B是一个被观察者,一旦B发表任何言论,A便可以获得。
被观察者(Observable)相当于事件源和事件,执行事件源通知逻辑时,将会回调observer的回调方法update。
举个例子
为了方便,同样我直接使用jdk自带的Observer。
一个观察者
public class WatcherDemo implements Observer {
@Override
public void update(Observable o, Object arg) {
if(arg.toString().equals("openWindows")){
System.out.println("已经打开窗口");
}
}
}
被观察者
Observable 是jdk自带的被观察者,具体可以自行看源码和之前的监听器事件源类似。
主要方法有
addObserver() 添加观察者,与监听器模式类似
notifyObservers() 通知所有观察者
类Watched.java的实现描述:被观察者,相当于事件监听的事件源和事件对象。又理解为订阅的对象 主要职责:注册/撤销观察者(监听器),接收主题对象(事件对象)传递给观察者(监听器),具体由感兴趣的观察者(监听器)执行
/**
}
测试执行
public static void main(String[] args) {
Watched watched = new Watched();
WatcherDemo watcherDemo = new WatcherDemo();
watched.addObserver(watcherDemo);
watched.addObserver(new Observer(){
@Override
public void update(Observable o, Object arg) {
if(arg.toString().equals("closeWindows")){
System.out.println("已经关闭窗口");
}
}
});
//触发打开窗口事件,通知观察者
watched.notifyObservers("openWindows");
//触发关闭窗口事件,通知观察者
watched.notifyObservers("closeWindows");
控制台输出:
已经打开窗口
已经关闭窗口
总结
从整个实现和调用过程来看,观察者和监听器模式基本一样。
有兴趣的你可以基于这个模型,实现一个简单微博加关注和取消的功能。 说到底,就是事件驱动模型,将调用者和被调用者通过一个链表、回调函数来解耦掉,相互独立。
“你别来找我,有了我会找你”。
整个设计模式的初衷也就是要做到低耦合,低依赖。
再延伸下,消息中间件是什么一个模型? 将生产者+服务中心(事件源)和消费者(监听器)通过消息队列解耦掉. 消息这相当于具体的事件对象,只是存储在一个队列里(有消峰填谷的作用),服务中心回调消费者接口通过拉或取的模型响应。 想必基于这个模型,实现一个简单的消息中间件也是可以的。
还比如gava ListenableFuture,采用监听器模式就解决了future.get()一直阻塞等待返回结果的问题。
有兴趣的同学,可以再思考下观察者和责任链之间的关系, 我是这样看的。
同样会存在一个链表,被观察者会通知所有观察者,观察者自行处理,观察者之间互不影响。 而责任链,讲究的是击鼓传花,也就是每一个节点只需记录继任节点,由当前节点决定是否往下传。 常用于工作流,过滤器web filter。