如何处理长按事件的响应?

fulton_xc 2008-03-10 09:15:10
按Button,可以用mouselistener中mouseDown()获取响应。但长按之,只有一次响应。
需求:按住某Button不放,另一Lable中显示数据持续减少,释放Button时停止。
请写出简单代码,谢谢高手指点。
...全文
295 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
fulton_xc 2008-03-12
  • 打赏
  • 举报
回复
谢谢大家的帮助。
可以用了。
fulton_xc 2008-03-11
  • 打赏
  • 举报
回复
7楼的方法编译是可以的,在awt下估计也行。
但我用SWT,不允许在别的线程调用控件,所以报错:Invalid thread access。
求新方法或计时器解法。谢谢。
dracularking 2008-03-11
  • 打赏
  • 举报
回复
在响应方法中循环的确可能会导致阻塞 新线程可以响应
as follows

import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class Test implements MouseListener{
public boolean isButtonPressed = false;
public boolean isButtonReleased = false;
public boolean isThreadStarted = false;
public JFrame jf;
public JLabel jl;
public JButton jb;

public static void main(String[] args) {
Test test = new Test();
test.go();
}

public void go(){
jf = new JFrame();
jl = new JLabel("jl");
jb = new JButton("jb");
jf.setLayout(new FlowLayout());
jf.add(jl);
jf.add(jb);
jf.setVisible(true);
jf.setSize(300, 100);
jb.addMouseListener(this);
}

class MyThread extends Thread {
public void run(){
System.out.println(isButtonReleased);
while (!isButtonReleased) {
jl.setText(jl.getText() + "a");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub

}

public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub

}

public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub

}

public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("mousePressed");
isButtonPressed = true;
isButtonReleased = false;
if(!isThreadStarted) {
new MyThread().start();
isThreadStarted = true;
}
}

public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("mouseReleased");
isButtonReleased = true;
isThreadStarted = false;
}

}


fulton_xc 2008-03-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 pizzame 的回复:]
循环需要用线程,计时器就不用了。
[/Quote]
也就是说循环需要在线程里进行,但新线程中无法响应别的控件。
所以,再问问计时器如何实现。谢谢。
睿音 2008-03-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fulton_xc 的回复:]
3楼的方法,我尝试了,但效果是进入死循环,不能完成。
[/Quote]
仔细查你的程序,我也这样实现过。没有问题~

循环需要用线程,计时器就不用了。
fulton_xc 2008-03-11
  • 打赏
  • 举报
回复
1楼的太概括了。
2楼的确实可以实现长按响应,但不能在别的控件上显示响应,没满足我的需求。
3楼的方法,我尝试了,但效果是进入死循环,不能完成。

再补充一下需求,在SWT下点击某Button,另一Label显示数据减少,若长按该Button,则显示数据持续减少,释放Button时停止。
谢谢
zapdos 2008-03-11
  • 打赏
  • 举报
回复
虽然没用过SWT
但是想一下就知道肯定是可以在其它线程调用的

随便翻开BAIDU第一页,就找到了解决方法:
Display.getDefault().syncExec()
老紫竹 2008-03-11
  • 打赏
  • 举报
回复
1 侦听 mouseDown 事件,设置一个按下的标志
2 侦听 mouseUp 时间,复位按下的标志
3 一个计时器或者循环,判断标志是否按下,并做对应的操作。

rxiaozheng 2008-03-11
  • 打赏
  • 举报
回复
如果用timer:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class InteractionDemo {

private Display display = null;
private Shell shell = null;

private Label label = null;
private Button button = null;

private java.util.Timer t;

public InteractionDemo() {

display = Display.getDefault();

shell = new Shell( display );
shell.setText("Demo");
shell.setLayout( new FillLayout() );

label = new Label(shell,SWT.BORDER);
label.setText("Label Demo");
button = new Button(shell,SWT.NONE);
button.setText("click me");

button.addMouseListener( new MouseListener() {

public void mouseDoubleClick(MouseEvent arg0) {

}

public void mouseDown(MouseEvent arg0) {
t = new java.util.Timer(true);
t.schedule(new java.util.TimerTask() {
public void run() {
display.asyncExec( new Runnable() {
public void run() {
label.setText( label.getText()+" a" );
}
} );
}
}, 100,500);
}

public void mouseUp(MouseEvent arg0) {
t.cancel();
}

} );
shell.setSize(500, 80);
shell.open();
while( !shell.isDisposed() ){
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}

/**
* @param args
*/
public static void main(String[] args) {
new InteractionDemo();
}

}
rxiaozheng 2008-03-11
  • 打赏
  • 举报
回复
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class InteractionDemo {

private Display display = null;
private Shell shell = null;

private Label label = null;
private Button button = null;

public InteractionDemo() {

display = Display.getDefault();

shell = new Shell( display );
shell.setText("Demo");
shell.setLayout( new FillLayout() );

label = new Label(shell,SWT.BORDER);
label.setText("Label Demo");
button = new Button(shell,SWT.NONE);
button.setText("click me");

final ActionThread actionThread = new ActionThread();
actionThread.start();
button.addMouseListener( new MouseListener() {

public void mouseDoubleClick(MouseEvent arg0) {

}

public void mouseDown(MouseEvent arg0) {
actionThread.setClicked( true );
}

public void mouseUp(MouseEvent arg0) {
actionThread.setClicked( false );
}

} );
shell.pack();
shell.open();
while( !shell.isDisposed() ){
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}

class ActionThread extends Thread {

private boolean isClicked = false;

public void setClicked( boolean isClicked ) {
this.isClicked = isClicked;
}

public void run() {
while( true ) {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
if( !display.isDisposed() )
display.asyncExec( new Runnable() {
public void run() {
if( isClicked )
label.setText( label.getText()+" a" );
}
} );
else
break;
}
}

}

/**
* @param args
*/
public static void main(String[] args) {
new InteractionDemo();
}

}
fulton_xc 2008-03-11
  • 打赏
  • 举报
回复
很可惜,9楼的方法用于swt一样出错。
Exception in thread "Timer-7" org.eclipse.swt.SWTException: Invalid thread access
有待新方法,谢谢。
zapdos 2008-03-11
  • 打赏
  • 举报
回复

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class test extends JFrame{
static java.util.Timer t;
public test(){
Container c = this.getContentPane();
JLabel jl = new JLabel("sss");
jl.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
t = new java.util.Timer(true);
t.schedule(new TimerTask() {
int i=0;
public void run() {
System.out.println(i++);
}
}, 300,50);
}
public void mouseReleased(MouseEvent e){
t.cancel();
}
});
c.add(jl);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,300);
this.setVisible(true);
}
public static void main(String args[]){
new test();

}
}

这个,就用计时器做的
不过,timertask也是实现了runnable接口的
我实在是想不出有什么理由能够不启动另一条线程
zapdos 2008-03-10
  • 打赏
  • 举报
回复

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

class a extends Thread{
private int i=0;
private boolean b=false;
public a(){
start();
}
public void run(){
while(true){
try{
synchronized(this){
if(!b)
wait();
}
}catch(Exception e2){}
System.out.println(i++);
}
}
public void kill(){
b = false;
}
public void wake(){
b = true;
interrupt();
}
}
public class test extends JFrame{
static a t = new a();
public test(){
Container c = this.getContentPane();
JLabel jl = new JLabel("sss");
jl.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
t.wake();
}
public void mouseReleased(MouseEvent e){
t.kill();
}
});
c.add(jl);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,300);
this.setVisible(true);
}
public static void main(String args[]){
new test();
}
}
zapdos 2008-03-10
  • 打赏
  • 举报
回复
用标记或者计时器,一般都可以解决吧

58,454

社区成员

发帖
与我相关
我的任务
社区描述
Java Eclipse
社区管理员
  • Eclipse
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧