我在更新方法中的jlabel时遇到问题。这是我的代码:
JLabel curStatus = new JLabel("");
JButton jbtnSubmit;
public static void main(String[] args) {
test gui = new test();
gui.startGUI();
// gui.setCurStatus("testing!"); << seems to work here,
//but when i call it from another class, it doesn't want to run.
}
// Set up the GUI end for the user
public void startGUI() {
// These are all essential GUI pieces
new JTextArea("");
final JFrame jfrm = new JFrame("my program");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(300, 300);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jbtnSubmit = new JButton("Submit");
jfrm.add(jbtnSubmit);
jfrm.add(curStatus);
jfrm.setVisible(true);
}
public void setCurStatus(String inCurStatus) {
curStatus.setText(inCurStatus);
curStatus.setVisible(true);
}
正在发生的事情是标签curStatus没有出现。例如,这是一个电话:
gui1.setCurStatus("Now running diagnostics... Please wait!");
答案 0 :(得分:2)
您的问题似乎是错误的引用之一。
以下是创建GUI的方法:
public static void main(String[] args) {
test gui = new test();
gui.startGUI();
// gui.setCurStatus("testing!"); << seems to work here,
// but when i call it from another class, it doesn't want to run.
}
您可以在main方法内部创建“test”对象(应该通过符合Java命名约定的方式命名为“Test”)。由于它是在main内部声明的,因此该变量仅在main内部具有范围,并且在其他位置可见。
然后告诉我们您正在调用这样的方法:
gui1.setCurStatus("Now running diagnostics... Please wait!");
gui1变量引用一个测试类对象,但它可能引用一个不同的对象而不是正在显示的测试对象,因为原始显示的测试对象仅由一个本地的变量引用主要方法。
要解决此问题,您必须确保在当前显示的测试对象上调用setCurStatus。如何执行此操作取决于您的其他代码,尽管我们要求您这样做,但您拒绝向我们展示。
编辑:根据您发布的最新代码(由于缺少方法createTasksFile()
而仍然无法为我编译),我的假设是正确的,您正在调用对于未显示的gui对象的setCurStatus(...)
:
public static String[] runDiagnostics() throws IOException {
gui gui1 = new gui(); // (A)
gui1.setCurStatus("Now running diagnostics... Please wait!");
在行(A)上,您创建一个新的gui对象并在其上调用setCurStatus,但它不正在显示的GUI对象,但它是一个完全不同且不相关的对象。它唯一的关系是它是一个与正在显示的对象相同的对象,但就是这样。解决方案是获取对显示的GUI的引用,并在该对象上调用此方法,并仅在该对象上调用。
同样,罗宾的假设是正确的,因为即使你解决了这个问题,你也会陷入Swing并发问题。 JLabel不会更新,因为Swing线程正在尝试打开文件:
public static String[] runDiagnostics() throws IOException {
gui gui1 = new gui();
gui1.setCurStatus("Now running diagnostics... Please wait!");
int i = 0;
int errorsI = 0;
File f = new File("tasks.txt");
String[] errors = { "", "", "", "", "" };
// try to create the file three times
do {
f.createNewFile();
i++;
} while (!f.exists() && i < 3);
所以我们都是对的。解决方法是在后台线程上打开文件,SwingWorker在这里可以正常工作。
编辑2
因此,要修复引用问题,请使用gui参数将gui的引用传递给runDiagnostics方法。然后在此参数上调用setCurStatus方法。例如:
public static String[] runDiagnostics(gui gui1) throws IOException {
//!! gui gui1 = new gui(); // !! no longer needed
gui1.setCurStatus("Now running diagnostics... Please wait!");
调用方法时必须传入GUI:
//!! results = taskBckg.runDiagnostics();
results = taskBckg.runDiagnostics(gui);
另外,请编辑所有代码,使其遵循Java命名约定。所有类名都应以大写字母开头。这使其他人更容易理解您的代码正在做什么。
答案 1 :(得分:1)
我会根据您要显示的消息进行猜测,因为该问题缺少一些基本信息。基于
“正在运行诊断程序......请稍等!”
消息,我将假设您正在运行诊断程序并尝试在同一个线程上更新UI。您发布的代码没有明显的错误,这可以解释为什么您的电话
gui1.setCurStatus("Now running diagnostics... Please wait!");
不会更新标签内容。
您需要做的就是在Swing concurrency tutorial中解释。重点是您更新Event dispatch thread上的UI,并且您永远不会在该线程上执行繁重的计算,因为这将阻止UI,从而导致糟糕的用户体验。应该在工作线程上进行大量计算,例如使用SwingWorker
类,并且只有更新UI(例如报告进度)才能在EDT上进行。
通过此信息和链接,您应该能够找到所有相关信息。此外,您还可以在此网站上找到有关如何使用SwingWorker
执行后台计算和更新用户界面的多个示例,例如my answer on a previous question