我希望在重写的t.isStopped()
方法中访问run()
但我得到以下错误。
不能引用在不同方法中定义的内部类中的非final变量t
如果我将t设置为最终变量
局部变量t可能尚未初始化
<!-- language: java -->
jHibernateCheckBox = new JCheckBox("Sleep / Hibernate after ");
jHibernateTextField = new JTextField("240");
jHibernateCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StoppableThread t = new StoppableThread() {
@Override
public void run() {
t.setIsRunning(true);
long timestamp = new Date().getTime();
int minutes = Integer.parseInt(jHibernateTextField.getText());
long secounds = minutes * 60;
long millisecounds = secounds * 1000;
long elapsedTime = new Date().getTime();
do {
try {
Thread.sleep(1000);
millisecounds -= new Date().getTime() - elapsedTime;
secounds = millisecounds / 1000;
if(secounds < 60) {
jHibernateTextField.setText("" + secounds);
jRemainingLabel.setText(" secounds remaining");
}
else {
jHibernateTextField.setText("" + secounds / 60);
jRemainingLabel.setText(" minutes remaining");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
elapsedTime = new Date().getTime();
}while(!t.isStopped() && timestamp + minutes * 60 * 1000 > new Date().getTime());
jHibernateTextField.setText("" + minutes);
if(t.isStopped()) return;
else {
console.out("Computer wird schlafen gelegt =)");
//Hibernate (siehe LAPTOP)
}
}
};
Thread thread = new Thread(t);
if(jHibernateCheckBox.isSelected()) {
jHibernateTextField.setEnabled(false);
thread.start();
}
else {
jHibernateTextField.setEnabled(true);
t.setIsStopped(true);
}
}
});
是否可以访问内部类中的变量t 或者,如果再次点击复选框,有没有人知道如何停止线程?
我只是希望当我再次点击jHibernateCheckBox时计时器停止工作...也许还有另一种方法?
答案 0 :(得分:2)
与您的问题无关,但在您发布的代码段中违反了Swing线程规则。只能从Event Dispatch Thread访问/修改所有Swing组件。不允许从StoppableThread
修改Swing组件,并且可能在运行时导致奇怪的行为。
快速浏览一下代码后,您似乎可以使用SwingWorker
并触发进度事件。或多或少与JProgressBar
tutorial(他们使用SwingWorker
的部分)
有关详细信息,请参阅Swing concurreny tutorial。
答案 1 :(得分:1)
你可以尝试在实现中使用'this'关键字吗?
答案 2 :(得分:1)
StoppableThread t = new StoppableThread() {
@Override
public void run() {
t.setIsRunning(true);
long timestamp = new Date().getTime();
int minutes = Integer.parseInt(jHibernateTextField.getText());
long secounds = minutes * 60;
long millisecounds = secounds * 1000;
long elapsedTime = new Date().getTime();
do {
try {
Thread.sleep(1000);
millisecounds -= new Date().getTime() - elapsedTime;
secounds = millisecounds / 1000;
if(secounds < 60) {
jHibernateTextField.setText("" + secounds);
jRemainingLabel.setText(" secounds remaining");
}
else {
jHibernateTextField.setText("" + secounds / 60);
jRemainingLabel.setText(" minutes remaining");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
elapsedTime = new Date().getTime();
}while(!t.isStopped() && timestamp + minutes * 60 * 1000 > new Date().getTime());
jHibernateTextField.setText("" + minutes);
if(t.isStopped()) return;
else {
console.out("Computer wird schlafen gelegt =)");
//Hibernate (siehe LAPTOP)
}
}
};
在run方法中,用this
替换t。
答案 3 :(得分:-1)
我尝试了一些新的东西,现在它可以了。我不知道这是否是一个浮躁但是 看看吧。
private StoppableThread t;
public void initComponents() {
...
...
t = new StoppableThread() {
@Override
public void run() {
setIsRunning(true);
long timestamp = new Date().getTime();
int minutes = Integer.parseInt(jHibernateTextField.getText());
long secounds = minutes * 60;
long millisecounds = secounds * 1000;
long elapsedTime = new Date().getTime();
do {
try {
Thread.sleep(1000);
millisecounds -= new Date().getTime() - elapsedTime;
secounds = millisecounds / 1000;
if(secounds < 60) {
jHibernateTextField.setText("" + secounds);
jRemainingLabel.setText(" secounds remaining");
}
else {
jHibernateTextField.setText("" + secounds / 60);
jRemainingLabel.setText(" minutes remaining");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
elapsedTime = new Date().getTime();
}while(!isStopped() && timestamp + minutes * 60 * 1000 > new Date().getTime());
jHibernateTextField.setText("" + minutes);
if(isStopped()) return;
else {
console.out("Computer wird schlafen gelegt =)");
//Hibernate (siehe LAPTOP)
}
}
};
jHibernateCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Thread thread = new Thread(AutoBarbarPanel.this.t);
if(jHibernateCheckBox.isSelected()) {
jHibernateTextField.setEnabled(false);
thread.start();
}
else {
jHibernateTextField.setEnabled(true);
t.setIsStopped(true);
}
}
});
}
感谢所有答案