我有一个带有actionListener的JButton,当我多次点击它时,它会像我点击一样多次完成它的工作,下面是我的代码:
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);
我想要的是无论我在工作期间点击多少次,它都不会再次执行。当工作完成后,如果我再次点击,工作将再次运行。我不知道该怎么做,请告诉我你是否知道,谢谢!
答案 0 :(得分:5)
长时间运行的代码不应该在事件调度线程(EDT)上执行。您需要启动一个单独的线程来处理HTTP请求。
最简单的方法是使用SwingWorker
。您可以在启动worker之前禁用该按钮,然后该worker调用了done()
方法,您可以启用该按钮。
阅读Concurrency in Swing上Swing教程中的部分,了解有关EDT的更多信息以及Swing worker的工作示例。
编辑:
人们似乎对事件处理感到困惑。在处理下一个事件之前调用事件的侦听器。所以在按钮上“双击”的情况下。第一次单击时禁用该按钮,并启动长时间运行的任务。然后在禁用按钮上接收第二次单击,因此不会调用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();
}
}
SwingWorker与上述逻辑类似,但是:
done()
方法,以便启用该按钮。答案 1 :(得分:0)
我确实应该使用if
并在执行代码之前检查按钮是否已启用。
JButton source = (JButton) e.getSource();
if(source.isEnabled()) {
.
.
.
execute your code
我希望我帮助你。 :)
答案 2 :(得分:-1)
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L,NE]
答案 3 :(得分:-1)
添加了一个completedTime变量来保存时间戳,就像操作完成时一样,每个事件都有生成时间,比较并返回,如果它小于完成时间
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();
}
};