我正在实现一个javax.swing.timer来调用GUI上的同步操作。但是,该操作需要一些时间才能完成,我想为该定时器调用提供一个中止选项。这可能吗?
THX!
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Iterator;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JTextField;
import org.omg.CosNaming.IstringHelper;
public class vtm extends JPanel implements ActionListener{
private JFrame frame;
private String children[];
private ConsoleApp hawk[];
public static String data[][];
public Timer timer;
private int count1, count2;
private int i;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
vtm window = new vtm();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public vtm() {
timer = new Timer(25000, this);
//timer.setInitialDelay(190);
timer.start();
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame("VTM");
frame.setSize(1024, 720);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblNewLabel_1 = new JLabel("");
lblNewLabel_1.setIcon(new ImageIcon("config.png"));
lblNewLabel_1.setBounds(970, 0, 51, 55);
frame.getContentPane().add(lblNewLabel_1);
lblNewLabel_1.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
config x = new config();
x.main(null);
timer.stop();
frame.dispose();
}
});
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon("bg.png"));
lblNewLabel.setBounds(0, 0, 1024, 720);
frame.getContentPane().add(lblNewLabel);
String dir = System.getProperty("user.dir");
File df = new File(dir);
FilenameFilter fi = new FilenameFilter(){
public boolean accept(File df, String name){
return name.startsWith("D-");
}
};
children = df.list(fi);
hawk=new ConsoleApp[children.length];
EventQueue.invokeLater(new Runnable(){
public void run(){
int count1 = 0; count2 = 0;
for(i=0;i<children.length;i++)
{
hawk[i]=new ConsoleApp(children[i]);
Iterator<String> it = hawk[i].p.iterator();
System.out.println("Hi:"+hawk[i].p.size());
while(it.hasNext())
{
hawk[i].call(it.next());
if(count1 == 3)
{
count2++;
count1=0;
}
System.out.println("Look: " + hawk[i].l.getText().length());
hawk[i].l.setBounds((60 + 270*count1) + ((260-(hawk[i].l.getText().length()*7))/2), (70+(count2*60)), 260, 62);
hawk[i].c.setBounds(50 + 270*count1, (70+(count2*60)), 273, 62);
frame.getContentPane().add(hawk[i].c,0);
frame.getContentPane().add(hawk[i].l,0);
count1++;
}
}
}
});
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("lol");
EventQueue.invokeLater(new Runnable(){
public void run(){
int count1 = 0; count2 = 0;
for(i=0;i<children.length;i++)
{
hawk[i]=new ConsoleApp(children[i]);
Iterator<String> it = hawk[i].p.iterator();
System.out.println("Hi:"+hawk[i].p.size());
while(it.hasNext())
{
hawk[i].call(it.next());
if(count1 == 3)
{
count2++;
count1=0;
}
hawk[i].l.setBounds((60 + 270*count1) + ((260-(hawk[i].l.getText().length()*7))/2), (70+(count2*60)), 260, 62);
hawk[i].c.setBounds(50 + 270*count1, (70+(count2*60)), 273, 62);
frame.getContentPane().add(hawk[i].c,0);
frame.getContentPane().add(hawk[i].l,0);
count1++;
}
}
}
});
}
}
答案 0 :(得分:2)
你的actionPerformed会触发一个Runnable,我认为这需要花费很长时间以及你想要中止的内容。在Runnable的run方法中,你有两个循环,for(i=0;i<children.length;i++)
和while(it.hasNext())
。如果为这些循环添加停止条件,则可以通过从外部控制该条件来提前完成Runnable完成。
例如,向vtm添加字段abort
,并将两个循环分别更改为for(i=0;i<children.length && !abort;i++)
和while(it.hasNext() && !abort)
。您现在可以将abort
设置为true,并且Runnable将在下次尝试再次循环时停止。
答案 1 :(得分:2)
使用Swingworker而不是Runnable,这就是实现取消机制的方法:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/cancel.html
答案 2 :(得分:0)
我正在实现一个javax.swing.timer来调用GUI上的同步操作。但是,该操作需要一些时间才能完成,我想为该定时器调用提供一个中止选项。这可能吗?
如果您想为您的用户提供UI以取消您在事件调度线程(EDT)运行时发布的Runnable
,那么不,这是不可能的。
当您的Runnable
代码开始执行时,您的UI将无响应,因为您的Runnable
占用了UI线程(EDT)。因此,在Runnable
完成之前,任何取消按钮或您想到的任何界面都不会对任何点击做出反应。
你可以在它开始运行之前取消它,但是你可以更好地投入时间来调查你是否真的必须在EDT上执行繁重的工作(通常答案是否定的)。最好对工作Thread
执行所有繁重的计算/操作,并在/期间更新UI。 SwingWorker
类就是为此而设计的,可以在网上找到许多使用它的例子(在javadoc,官方Swing教程和本网站上)