进度条可以在 main 之外的类中使用吗?
现在,我的 main 只调用一个有 10 行的 gui。根据其中有多少行有文本,调用 9 个类中的 1 个(两行必须有文本)。被调用的类执行我希望将进度条绑定到的计算。这是一个被调用的类之一的示例(每个类都是相似的,但不同之处足以保证一个新类。)我认为问题是违反了 EDT 规则,但我在其中看到的所有示例都涉及一个 main争论。代码运行时会出现该框架,但进度条直到所有计算完成后才会更新。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class twoLoan extends JFrame {
static JFrame progressFrame;
static JProgressBar progressBar;
static Container pane;
double amountSaved = 0;
int i = 0;
public void runCalcs(Double MP, Double StepAmt,
Double L1, Double L2, Double C1, Double C2,
Double IM1, Double IM2, Double M1Start, Double M2Start) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
int iterations = (int) (MP - (M1Start * M2Start));
//Create all components
progressFrame = new JFrame("Calculation Progress");
progressFrame.setSize(300, 100);
pane = progressFrame.getContentPane();
pane.setLayout(null);
progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressBar = new JProgressBar(0, iterations);
//Add components to pane
pane.add(progressBar);
//Position controls (X, Y, width, height)
progressBar.setBounds(10, 10, 280, 20);
//Make frame visible
progressFrame.setResizable(false); //No resize
progressFrame.setVisible(true);
double M1 = M1Start;
double M2 = M2Start;
// Set MinLoop as maximum to start
// Loan 1
double N1 = (Math.log10(1 - IM1 * L1 / M1) * -1) / Math.log10(1 + IM1);
double M1Sum = M1 * N1;
// Loan 2
double N2 = (Math.log10(1 - IM2 * L2 / M2) * -1) / Math.log10(1 + IM2);
double M2Sum = M2 * N2;
double minLoop = M1Sum + M2Sum;
double MTotal = 0;
// Define variables for mins
double MP1 = 0;
double MP2 = 0;
double NP1 = 0;
double NP2 = 0;
double MP1Sum = 0;
double MP2Sum = 0;
while (M1 <= MP - M2Start && M2 >= M2Start) {
N1 = (Math.log10(1 - IM1 * L1 / M1) * -1) / Math.log10(1 + IM1);
M1Sum = N1 * M1;
N2 = (Math.log10(1 - IM2 * L2 / M2) * -1) / Math.log10(1 + IM2);
M2Sum = N2 * M2;
MTotal = M1Sum + M2Sum;
if (MTotal < minLoop) {
minLoop = MTotal;
MP1 = M1;
MP2 = M2;
NP1 = N1;
NP2 = N2;
MP1Sum = M1Sum;
MP2Sum = M2Sum;
} // end if
M1 = M1 + StepAmt;
M2 = MP - M1;
// Reset monthly sums
M1Sum = 0;
M2Sum = 0;
i++;
progressBar.setValue(i);
progressBar.repaint();
if (i >= iterations) {
progressFrame.dispose();
}
} // end while
// if there's a value for current payments, calculate amount saved
if (C1 > 0) {
double CN1 = (Math.log10(1 - IM1 * L1 / C1) * -1) / Math.log10(1 + IM1);
double CT1 = CN1 * C1;
double CN2 = (Math.log10(1 - IM2 * L2 / C2) * -1) / Math.log10(1 + IM2);
double CT2 = CN2 * C2;
double CTotal = CT1 + CT2;
amountSaved = CTotal - minLoop;
}
} // end method runCalcs
//Workbook wb = new HSSFWorkbook();
public double savedReturn() {
return amountSaved;
}
} // end class twoLoans
Right now, my main just calls a gui with 10 rows. Based on how many of those rows have text, 1 of 9 classes is called (two rows must have text). The called class performs calculations that I'd like to have the progress bar tied to. Here is an example of one of the called classes (each class is similar, but different enough to warrant a new class.) I believe the problem is a violation of EDT rules, but all the examples I've seen on them involve a main argument. The frame appears when the code is run, but the progress bar doesn't update until all calculations are completed.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class twoLoan extends JFrame {
static JFrame progressFrame;
static JProgressBar progressBar;
static Container pane;
double amountSaved = 0;
int i = 0;
public void runCalcs(Double MP, Double StepAmt,
Double L1, Double L2, Double C1, Double C2,
Double IM1, Double IM2, Double M1Start, Double M2Start) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
int iterations = (int) (MP - (M1Start * M2Start));
//Create all components
progressFrame = new JFrame("Calculation Progress");
progressFrame.setSize(300, 100);
pane = progressFrame.getContentPane();
pane.setLayout(null);
progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressBar = new JProgressBar(0, iterations);
//Add components to pane
pane.add(progressBar);
//Position controls (X, Y, width, height)
progressBar.setBounds(10, 10, 280, 20);
//Make frame visible
progressFrame.setResizable(false); //No resize
progressFrame.setVisible(true);
double M1 = M1Start;
double M2 = M2Start;
// Set MinLoop as maximum to start
// Loan 1
double N1 = (Math.log10(1 - IM1 * L1 / M1) * -1) / Math.log10(1 + IM1);
double M1Sum = M1 * N1;
// Loan 2
double N2 = (Math.log10(1 - IM2 * L2 / M2) * -1) / Math.log10(1 + IM2);
double M2Sum = M2 * N2;
double minLoop = M1Sum + M2Sum;
double MTotal = 0;
// Define variables for mins
double MP1 = 0;
double MP2 = 0;
double NP1 = 0;
double NP2 = 0;
double MP1Sum = 0;
double MP2Sum = 0;
while (M1 <= MP - M2Start && M2 >= M2Start) {
N1 = (Math.log10(1 - IM1 * L1 / M1) * -1) / Math.log10(1 + IM1);
M1Sum = N1 * M1;
N2 = (Math.log10(1 - IM2 * L2 / M2) * -1) / Math.log10(1 + IM2);
M2Sum = N2 * M2;
MTotal = M1Sum + M2Sum;
if (MTotal < minLoop) {
minLoop = MTotal;
MP1 = M1;
MP2 = M2;
NP1 = N1;
NP2 = N2;
MP1Sum = M1Sum;
MP2Sum = M2Sum;
} // end if
M1 = M1 + StepAmt;
M2 = MP - M1;
// Reset monthly sums
M1Sum = 0;
M2Sum = 0;
i++;
progressBar.setValue(i);
progressBar.repaint();
if (i >= iterations) {
progressFrame.dispose();
}
} // end while
// if there's a value for current payments, calculate amount saved
if (C1 > 0) {
double CN1 = (Math.log10(1 - IM1 * L1 / C1) * -1) / Math.log10(1 + IM1);
double CT1 = CN1 * C1;
double CN2 = (Math.log10(1 - IM2 * L2 / C2) * -1) / Math.log10(1 + IM2);
double CT2 = CN2 * C2;
double CTotal = CT1 + CT2;
amountSaved = CTotal - minLoop;
}
} // end method runCalcs
//Workbook wb = new HSSFWorkbook();
public double savedReturn() {
return amountSaved;
}
} // end class twoLoans
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
SwingWorker
非常适合此目的。下面的示例在后台执行简单的迭代,同时在窗口中报告进度和中间结果。您可以在合适的SwingWorker
构造函数。SwingWorker
is ideal for this. The example below performs a simple iteration in the background, while reporting progress and intermediate results in a window. You can pass whatever parameters you need in a suitableSwingWorker
constructor.我认为您的预感是对的,您需要遵守 Swing 线程规则。
那么该怎么办呢?
首先,我不确定你的应用程序是如何设计的。你说你有一个带有一堆行的主框架,并且每个行都可能调用 9 个类中的一个,并且它们看起来都像上面的那样。看起来这些类将生成它们自己的
JFrame
。我猜这个新框架仅用于进度条。我会假设这就是设计,并会提出相应的建议。我建议您在
Runnable
实例中执行一些操作,然后将这些Runnable
实例放入SwingUtilities.invokeLater
中,让它们在美东时间。同时,我会花时间重新组织您的代码,以便于阅读。I think you premonition is right, you need to adhere to Swing threading rules.
So what to do?
First, I am not sure how your app is designed exactly. You say that you have a main frame with a bunch of rows, and potentially each could potentially call one of 9 classes, and they all look like the one above. It seems that these classes will generate their own
JFrame
. I guess that this new frame is solely used for the progress bar. I will assume that this is the design and will suggest accordingly.I suggest that you perform a couple actions in instances of
Runnable
, and you drop thoseRunnable
instances intoSwingUtilities.invokeLater
to have them run on the EDT. At the same time, I would take the time to reorganize your code for ease if reading.感谢您的帮助。我开始尝试使用第一个响应,但我无法让该栏同时运行,并且它在程序完成时运行。我确信它会起作用,但我无法弄清楚。使用trashgod的响应和其他一些示例,我能够使用
SwingWorker
让它工作。不幸的是,我并不完全理解它是如何工作的,但我现在就先了解它。首先在另一个类中调用运行计算的 gui 和方法:
然后运行如下:
Thanks for the help. I started with trying to use the first response, but I couldn't get the bar to run concurrently, and it ran when the program finished. I'm sure it would work, but I wasn't able to figure it out. Using trashgod's response and some other examples, I was able to get it to work using
SwingWorker
. Unfortunately, I don't totally understand how it works, but I'll take it for now.The gui and method to run the calculations are called in another class first:
Then it runs as follows: