Java 单击后禁用JButton,单击后启用';他的工作
我有一个JButton,它有一个actionListener,当我多次单击它时,它将完成与我单击次数相同的工作,下面是我的代码:Java 单击后禁用JButton,单击后启用';他的工作,java,swing,Java,Swing,我有一个JButton,它有一个actionListener,当我多次单击它时,它将完成与我单击次数相同的工作,下面是我的代码: mouseListener = new ActionListener() { public void actionPerformed(ActionEvent e) { JButton source = (JButton) e.getSource(); source.setEnable
mouseListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
source.setEnabled(false);
try {
RequestCommon.ctbCookie = jtf.getText();
System.out.println( RequestCommon.ctbCookie );
HttpURLConnection connection = HttpURLConnectionBuilder.getConnection(RequestCommon.login, RequestCommon.getCtb888Headers());
String connectionOuput = HttpURLConnectionBuilder.getConnectionOuput(connection);
System.out.println(connectionOuput);
new Player(new BufferedInputStream(new FileInputStream(new File("sounds/8.mp3")))).play();
} catch (IOException e1) {
e1.printStackTrace();
} catch (JavaLayerException e1) {
e1.printStackTrace();
}
source.setEnabled(true);
}
};
jb1.addActionListener(mouseListener);
我希望无论在作业运行期间单击多少次,它都不会再次执行。作业完成后,如果我再次单击,作业将再次运行。我不知道如何操作,请告诉我是否知道,谢谢 I thing,您应该在执行代码之前使用
if
并检查按钮是否已启用
JButton source = (JButton) e.getSource();
if(source.isEnabled()) {
.
.
.
execute your code
我希望我能帮助你。:) 长时间运行的代码不应在事件调度线程(EDT)上执行。您需要启动一个单独的线程来执行HTTP请求 最简单的方法是使用
SwingWorker
。您可以在启动工作程序之前禁用该按钮,然后该工作程序将调用一个done()
方法,您可以启用该按钮
有关EDT和Swing worker工作示例的更多信息,请阅读上Swing教程的部分
编辑:
人们似乎对事件处理感到困惑。在处理下一个事件之前调用事件的侦听器。所以在“双击”按钮的情况下。该按钮在第一次单击时被禁用,长时间运行的任务将启动。然后在禁用按钮上接收第二次单击,因此不会调用ActionListener
这是我手头的一些旧代码,它是在SwingWorker出现之前编写的。“在新线程中启动”按钮的基本逻辑是:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*
* A couple of notes about long running tasks and GUI updates:
*
* 1) all GUI painting should be done in the event thread
* 2) GUI painting is not done until the event thread processing is done
*
* This means that long running code (database access, file processing ...)
* should not be done in the event thread. A new thread can be created for
* these tasks.
*
* Most Swing methods are not thread safe. If the long running task needs
* to update the GUI for any reason then the SwingUtilities class
* should be used to add code to the event thread.
*
* See the Swing tutorial on "Using Threads" for more information
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*/
public class InvokeLaterTest extends JFrame
implements ActionListener, Runnable
{
JLabel status;
JButton eventThread;
JButton newThread;
JButton stop;
Thread thread;
int i;
boolean stopProcessing;
public InvokeLaterTest()
{
status = new JLabel( "Ready to Process:" );
status.setHorizontalAlignment( JLabel.CENTER );
getContentPane().add(status, BorderLayout.NORTH);
eventThread = new JButton( "Start in Event Thread" );
eventThread.addActionListener( this );
getContentPane().add(eventThread, BorderLayout.WEST);
newThread = new JButton( "Start in New Thread" );
newThread.addActionListener( this );
getContentPane().add(newThread, BorderLayout.EAST);
stop = new JButton( "Stop Processing" );
stop.addActionListener( this );
getContentPane().add(stop, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e)
{
// Code is executing in Event thread so label will not be updated
// and the Stop button will not be enabled.
if (e.getSource() == eventThread)
{
stopProcessing = false;
run();
}
// Code is executing in a new thread so label will be updated
else if (e.getSource() == newThread)
{
stopProcessing = false;
thread = new Thread( this );
thread.start();
}
else
{
stopProcessing = true;
status.setText("Processing Stopped");
setButtons( true );
}
}
public void run()
{
setButtons( false );
for (i = 1; i < 10; i++)
{
if ( stopProcessing ) return;
System.out.println("ProcessingFile: " + i);
// SwingUtilities makes sure code is executed in the event thread.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
status.setText("Processing File: " + i);
status.paintImmediately(status.getBounds());
}
});
// simulate log running task
try { Thread.sleep(1000); }
catch (Exception e) {}
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
status.setText("Finished Processing");
setButtons( true );
}
});
}
private void setButtons(boolean value)
{
eventThread.setEnabled( value );
newThread.setEnabled( value );
}
public static void main(String[] args)
{
JFrame frame = new InvokeLaterTest();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.show();
}
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
/*
*关于长时间运行的任务和GUI更新的几个注意事项:
*
*1)所有GUI绘制应在事件线程中完成
*2)在事件线程处理完成之前,不进行GUI绘制
*
*这意味着长时间运行的代码(数据库访问、文件处理…)
*不应在事件线程中执行。可以为创建新线程
*这些任务。
*
*大多数Swing方法都不是线程安全的。如果长时间运行的任务需要
*要出于任何原因更新GUI,请单击SwingUtilities类
*应用于向事件线程添加代码。
*
*有关更多信息,请参阅Swing教程“使用线程”
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*/
公共类InvokeLaterTest扩展了JFrame
实现ActionListener,可运行
{
JLabel状态;
JButton事件线程;
JButton新线程;
按钮停止;
螺纹;
int i;
布尔停止处理;
公共调用器测试()
{
状态=新JLabel(“准备处理:”);
状态。设置水平对齐(JLabel.CENTER);
getContentPane().add(状态,BorderLayout.NORTH);
eventThread=newjbutton(“在事件线程中启动”);
addActionListener(这个);
getContentPane().add(eventThread,BorderLayout.WEST);
newThread=newjbutton(“在新线程中启动”);
addActionListener(这个);
getContentPane().add(newThread,BorderLayout.EAST);
停止=新的JButton(“停止处理”);
stop.addActionListener(this);
getContentPane().add(停止,BorderLayout.SOUTH);
}
已执行的公共无效操作(操作事件e)
{
//代码正在事件线程中执行,因此不会更新标签
//并且停止按钮将不会启用。
如果(例如getSource()==eventThread)
{
停止处理=错误;
run();
}
//代码正在新线程中执行,因此标签将被更新
else if(例如getSource()==newThread)
{
停止处理=错误;
线程=新线程(此);
thread.start();
}
其他的
{
停止处理=真;
status.setText(“处理已停止”);
设置按钮(真);
}
}
公开募捐
{
缩进(假);
对于(i=1;i<10;i++)
{
如果(停止处理)返回;
System.out.println(“处理文件:+i”);
//SwingUtilities确保代码在事件线程中执行。
SwingUtilities.invokeLater(新的Runnable()
{
公开募捐
{
status.setText(“处理文件:+i”);
status.paintInstance(status.getBounds());
}
});
//模拟日志运行任务
试试{Thread.sleep(1000);}
捕获(例外e){}
}
SwingUtilities.invokeLater(新的Runnable()
{
公开募捐
{
status.setText(“已完成处理”);
设置按钮(真);
}
});
}
专用空心收进按钮(布尔值)
{
eventThread.setEnabled(值);
newThread.setEnabled(值);
}
公共静态void main(字符串[]args)
{
JFrame frame=newinvokelatertest();
frame.setDefaultCloseOperation(关闭时退出);
frame.pack();
frame.setLocationRelativeTo(空);
frame.show();
}
}
SwingWorker与上述逻辑类似,但:
done()
方法,以便您可以启用该按钮添加了completedTime变量以保存时间戳,如同操作完成时一样,每个事件都有生成时间,如果小于完成时间,则进行比较并返回
JButton source = (JButton) e.getSource();
if (source.isEnabled()) {
Executors.newSingleThreadScheduledExecutor().execute(() -> {
source.setEnabled(false);
--your code here--
source.setEnabled(true);
}
);
}
};
long completedTime;
mouseListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
long timeStamp = e.getWhen();
if (timeStamp < completedTime) {
System.out.println("returned");
return;
}
// source.setEnabled(false);
try {
RequestCommon.ctbCookie = jtf.getText();
System.out.println( RequestCommon.ctbCookie );
HttpURLConnection connection = HttpURLConnectionBuilder.getConnection(RequestCommon.login, RequestCommon.getCtb888Headers());
String connectionOuput = HttpURLConnectionBuilder.getConnectionOuput(connection);
System.out.println(connectionOuput);
new Player(new BufferedInputStream(new FileInputStream(new File("sounds/8.mp3")))).play();
} catch (IOException e1) {
e1.printStackTrace();
} catch (JavaLayerException e1) {
e1.printStackTrace();
}
// source.setEnabled(true);
completedTime = System.currentTimeMillis();
}
};