Как увидеть связь между двумя работающими с прогрессом
У меня 2 класса.java
Главный:
public class Controller extends javax.swing.JFrame
{
public static void updateProgressBar(int i) {
jProgressBar1.setValue(i);
jProgressBar1.repaint();
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Controller app = new Controller();
app.setVisible(true);
app.setResizable(false);
}
});
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
ChildModel model = new ChildModel();
Thread t1 = new Thread(model);
t1.start();
}
private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}
Мой ChildModel (ChildModel.java) вычисляет некоторый код (который занимает около 10-20 секунд), и я хочу показать прогресс в классе отца (Controller.java).
Вот моя ChildModel:
public class ChildModel implements Runnable
{
public ChildModel(){ /* Something */ }
public void complexMath()
{
//Lots of logic here
Controller.updateProgression(purcent);
}
@Override
public void run() {
complexMath();
}
}
Проблема, очевидно, моя статическая пустота updateProgressBar, который не может изменить нестатическую переменную. Как я могу сделать это?
2 ответа
jProgressBar1
переменная является переменной экземпляра, поэтому вы не можете получить к ней доступ из статического метода. И метод не должен быть статическим: вы хотите обновить прогресс в контроллере, а не во всех экземплярах контроллера.
Передайте ссылку на контроллер в ChildModel и используйте эту ссылку из ChildModel для обновления индикатора выполнения. Также помните, что все взаимодействия Swing должны выполняться в EDT, а не в фоновом потоке. ТАК код должен выглядеть так:
public class Controller extends javax.swing.JFrame
{
public void updateProgressBar(int i) {
jProgressBar1.setValue(i);
// no need for repaint. The progress bar knows it must be repainted
// when its value changes
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Controller app = new Controller();
app.setVisible(true);
app.setResizable(false);
}
});
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
ChildModel model = new ChildModel(this);
Thread t1 = new Thread(model);
t1.start();
}
private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder
}
public class ChildModel implements Runnable
{
private Controller controller;
public ChildModel(Controller controller){
this.controller = controller;
}
public void complexMath()
{
//Lots of logic here
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
controller.updateProgression(percent);
}
});
}
@Override
public void run() {
complexMath();
}
}
У Swing есть свои собственные механизмы параллелизма для обновления компонентов. Здесь вы можете использовать Swing Timer и обновить JProgressBar
, Вместо того, чтобы иметь ChildModel
воплощать в жизнь Runnable
Вы могли бы использовать Timer
в качестве переменной члена класса и передать в вашем экземпляре jProgressBar1
, позволяя вам позвонить setValue
когда требуется.