Java jLabel不更改文本,jProgressbar不更新
我有一个Java jLabel不更改文本,jProgressbar不更新,java,swing,event-dispatch-thread,Java,Swing,Event Dispatch Thread,我有一个JFrame。在JFrame中有一个JDesktopPane,JComboBox,几个JLabel和一个JProgressBar。我面临两个挑战: 我想通过单击JInternalFrame上的JButton更新/更改JLabel之一中的文本(该按钮执行一些计算) 单击另一个JInternalFrame上的JButton(该按钮执行一项小任务),我想使用JProgressBar(progressbar位于JFrame)来显示完成工作的进度 我使用SwingUtilities.invokel
JFrame
。在JFrame
中有一个JDesktopPane
,JComboBox
,几个JLabel
和一个JProgressBar
。我面临两个挑战:
JInternalFrame
上的JButton
更新/更改JLabel
之一中的文本(该按钮执行一些计算)JInternalFrame
上的JButton
(该按钮执行一项小任务),我想使用JProgressBar
(progressbar位于JFrame
)来显示完成工作的进度SwingUtilities.invokelater()
执行按钮完成的任务。
我使用NetBeans作为我的IDE。如果没有代码,很难知道发生了什么,但事件调度线程(EDT)可能正在被阻止(或终止?),例如,被
调用器调用的代码。EDT用于更新GUI,不应用于(缓慢的)非GUI相关计算。有关更多详细信息,请参见教程“事件分派线程”及其后续部分
示例(无阻塞):
import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.time.LocalTime;
导入javax.swing.*;
公共类标签进展{
公共静态void main(字符串[]args){
LabelProgress main=新的LabelProgress();
SwingUtilities.invokeLater(()->main.showInternal1());
SwingUtilities.invokeLater(()->main.showInternal2());
}
私有JFrame;
私人标签;
私人JDesktopPane桌面;
私人酒吧;
私有int进程=0;
私有LabelProgress(){
标签=新的JLabel(“标签:”);
桌面=新的JDesktopPane();
bar=新的JProgressBar(0,100);
bar.设置字符串已上漆(正确);
frame=新的JFrame();
frame.setLayout(新的BorderLayout());
框架。添加(标签、边框布局。在第一行之前);
添加(桌面、边框布局、中心);
frame.add(在最后一行之后的条、边框布局);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
框架。设置尺寸(600400);
frame.validate();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
私有void showInternal1(){
JButton change=新JButton(“变更”);
change.addActionListener(this::doChange);
JInternalFrame internal=新的JInternalFrame(“变更标签”);
内部.setLayout(新的FlowLayout());
内部。添加(更改);
内部.立根(20,20,200,150);
内部设置可见(true);
桌面。添加(内部);
}
私有void showInternal2(){
JButton任务=新JButton(“任务”);
task.addActionListener(this::doTask);
JInternalFrame internal=新的JInternalFrame(“小任务”);
内部.setLayout(新的FlowLayout());
添加(任务);
内部.立根(150100200150);
内部设置可见(true);
桌面。添加(内部);
}
私人无效变更(ActionEvent ev){
//使用SwingWorker:
//为了演示,我使用了一个匿名类,也许自己的类更好
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的LocalTime doInBackground()引发异常{
//未在EDT上执行-仅获取当前时间
LocalTime someCalculation=LocalTime.now();
返回计算;
}
@凌驾
受保护的void done(){
//于美国东部时间执行
试一试{
LocalTime ResultoSomeCalculation=get();
label.setText(“label:+resultOfSomeCalculation.toString());
}捕获(例外情况除外){
例如printStackTrace();
}
}
};
worker.execute();
}
私有无效点任务(ActionEvent ev){
//不需要使用SwingWorker
线程线程=新线程(this::slowTask);
thread.start();
}
私有void slowTask(){
//不是很慢,只是为了演示一下
进展+=10;
如果(进度>100)进度=100;
//现在切换到EDT
SwingUtilities.invokeLater(()->bar.setValue(progress));
}
}
您能分享一下您已经尝试过的内容吗(代码)?欢迎来到Stack Overflow,请阅读,并学习,然后发布一个有效或有效的。如果您的问题与您希望在单击按钮时更改JLabel
中的文本有关,则创建一个包含JLabel
和JButton
及其操作执行的调用myLabel.setText(“任意文本”)代码>。也请在需要的时候写一些大写的单词,很难用小写来阅读所有内容。谢谢大家的快速回复。程序的所有其他部分都运行良好,只是jLabel和jProgressBar给了我问题。我观察到的是应该由jLabel显示的“新文本”没有显示,但当我在jLabel上打印时,它会显示新文本。当我想从jInternalFrame访问jFrame中的任何变量时,我会创建jFrame的新实例。jframe的类名是home,所以我做了“home home1=new home();然后(jLabel7在这里是公共的)home1.jLabel7.setText(“new text”),但它不起作用。我甚至在jframe中编写了一个名为“AMOUNT”的方法来获取新文本,然后将其设置为jLabel的值。仍然没有更新jLabel。我甚至放了theAMOUNT()swingworker的DONE方法中的方法仍然没有更新jLabel。
import java.awt.*;
import java.awt.event.ActionEvent;
import java.time.LocalTime;
import javax.swing.*;
public class LabelProgress {
public static void main(String[] args) {
LabelProgress main = new LabelProgress();
SwingUtilities.invokeLater(() -> main.showInternal1());
SwingUtilities.invokeLater(() -> main.showInternal2());
}
private JFrame frame;
private JLabel label;
private JDesktopPane desktop;
private JProgressBar bar;
private int progress = 0;
private LabelProgress() {
label = new JLabel("Label: ");
desktop = new JDesktopPane();
bar = new JProgressBar(0, 100);
bar.setStringPainted(true);
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(label, BorderLayout.BEFORE_FIRST_LINE);
frame.add(desktop, BorderLayout.CENTER);
frame.add(bar, BorderLayout.AFTER_LAST_LINE);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(600, 400);
frame.validate();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void showInternal1() {
JButton change = new JButton("Change");
change.addActionListener(this::doChange);
JInternalFrame internal = new JInternalFrame("Change Label");
internal.setLayout(new FlowLayout());
internal.add(change);
internal.setBounds(20, 20, 200, 150);
internal.setVisible(true);
desktop.add(internal);
}
private void showInternal2() {
JButton task = new JButton("Task");
task.addActionListener(this::doTask);
JInternalFrame internal = new JInternalFrame("Small Task");
internal.setLayout(new FlowLayout());
internal.add(task);
internal.setBounds(150, 100, 200, 150);
internal.setVisible(true);
desktop.add(internal);
}
private void doChange(ActionEvent ev) {
// using a SwingWorker:
// for demonstration I used an anonymous class, maybe a own class is better
SwingWorker<LocalTime , Void> worker = new SwingWorker<LocalTime , Void>() {
@Override
protected LocalTime doInBackground() throws Exception {
// not executed on the EDT - just get the current time
LocalTime someCalculation = LocalTime.now();
return someCalculation;
}
@Override
protected void done() {
// executed on EDT
try {
LocalTime resultOfSomeCalculation = get();
label.setText("Label: " + resultOfSomeCalculation.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
worker.execute();
}
private void doTask(ActionEvent ev) {
// no need to use SwingWorker
Thread thread = new Thread(this::slowTask);
thread.start();
}
private void slowTask() {
// not really that slow, just for demonstration
progress += 10;
if (progress > 100) progress = 100;
// and now switching to the EDT
SwingUtilities.invokeLater(() -> bar.setValue(progress));
}
}