Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPanel上的JLabel不';当setText来自另一个方法时,不能更新_Java_Swing_Jlabel_Settext - Fatal编程技术网

Java JPanel上的JLabel不';当setText来自另一个方法时,不能更新

Java JPanel上的JLabel不';当setText来自另一个方法时,不能更新,java,swing,jlabel,settext,Java,Swing,Jlabel,Settext,谢谢你的帮助。我是一个新手,尝试一些简单的事情。 我希望有一个窗口(面板),其中的文本(JLabel)每隔几秒钟更改一次。除了正在更新的JLabel(文本确实发生了变化),整个应用程序都工作得很好,但它没有显示在窗口(面板)上。窗口从头到尾保持相同的文本,即使我有检查点告诉我JLabel的文本正在更新和更改。我到处寻找同一个问题,找到了一些评论,但没有一个有用。有人说他是ActionListener,但当我摆脱它时,这没什么区别。有人说线程中的循环不允许JLabel刷新,所以我尝试将JLabel

谢谢你的帮助。我是一个新手,尝试一些简单的事情。 我希望有一个窗口(面板),其中的文本(JLabel)每隔几秒钟更改一次。除了正在更新的JLabel(文本确实发生了变化),整个应用程序都工作得很好,但它没有显示在窗口(面板)上。窗口从头到尾保持相同的文本,即使我有检查点告诉我JLabel的文本正在更新和更改。我到处寻找同一个问题,找到了一些评论,但没有一个有用。有人说他是ActionListener,但当我摆脱它时,这没什么区别。有人说线程中的循环不允许JLabel刷新,所以我尝试将JLabel和它的更新放在一个单独的线程上,但这也不起作用。我唯一没有尝试过的就是使用swingWorker(不太知道如何)。线程尝试使用了具有可运行方法的线程类。同样,通过这种方式,除了JLabel没有重新粉刷自己之外,其他一切都很完美

这是没有线程的代码。都在一节课上

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.*;





public class SWUI extends JFrame implements ActionListener {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel panel;
    JLabel label;
    private Font font;


    //Set up the interface. SWUI is working perfectly
SWUI() {

        System.out.println("run started");      //just to check that the method gets called.
        panel = new JPanel();
        panel.setLayout(new BorderLayout(1, 1));
        panel.setPreferredSize(new Dimension(1000, 400));
        panel.setBackground(Color.white);
        getContentPane().add(panel);

        label = new JLabel("Ready");                    //These four statements are working
        label.setHorizontalAlignment(JLabel.CENTER);
        font = new Font("Comic Sans MS", Font.PLAIN, 70);
        label.setFont(font);

        panel.add(label, BorderLayout.CENTER);

        System.out.println("run done and draw to start");

        label.setText("label is updatable");        //Checks that the whole method gets done and that the label is indeed able to get updated. It works.

    }


// draw() mostly sets the Frame up, names it, sets closing behavior. It's working.
    public void draw() {

        System.out.println("draw started");         //To check that the method is getting invoked.

        SWUI frame = new SWUI();
        frame.setTitle("Sight Words Rock");

        WindowListener l = new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
           System.exit(0);
         }
      };
        frame.addWindowListener(l);

        frame.pack();
        frame.setVisible(true);

        System.out.println("draw done");        //To check that the whole method went through. It's all working.

    }



    //Should change the label to 4 sentences every 1 second. The text of the label does change, but it doesn't show on the interface (panel).
    private void updateLabel(String word){

        label.setText(word);

        //label.revalidate();       //I tried these three statements one at a time and both together and they made no difference.
        //label.updateUI();
        //label.repaint();

        System.out.println("The label now is: "+ label.getText());   //This confirms that the setText() is indeed changing the text
                                                                    // of the label, but it doesn't show on the interface.
    }


    //Main gets the draw() started to initiate the interface and gets the sentences changed and sent to updateLabel() every second.
    public static void main(String args[]) 

        throws InterruptedException {

        SWUI ui = new SWUI();
        ui.draw();


        String importantInfo[] = {
            "Mares eat oats",
            "Dogs eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 1 second
            Thread.sleep(1000);

            //Print a message
            System.out.println(importantInfo[i]);

            ui.label.setText(importantInfo[i]);
            ui.updateLabel(importantInfo[i]);
        }

    }

    //This will come later once I figure how to fix the label. Someone else suggested that the problem were the listeners not letting the thread
    // do the repainting(), but I tried getting rid of the "implements ActionListener" and the actionPerformed methods and it didn't make a
    // difference. It still didn't work.
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Font;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.awt.event.WindowListener;
导入javax.swing.*;
公共类SWUI扩展JFrame实现ActionListener{
/**
* 
*/
私有静态最终长serialVersionUID=1L;
私人JPanel小组;
JLabel标签;
专用字体;
//设置界面。SWUI工作正常
SWUI(){
System.out.println(“run started”);//只是检查是否调用了该方法。
panel=新的JPanel();
面板设置布局(新边框布局(1,1));
面板。设置首选尺寸(新尺寸(1000400));
面板.立根背景(颜色.白色);
getContentPane().add(面板);
label=new JLabel(“Ready”);//这四条语句正在工作
标签设置水平对齐(JLabel.CENTER);
字体=新字体(“Comic Sans MS”,font.PLAIN,70);
label.setFont(字体);
添加(标签、边框布局、中心);
System.out.println(“运行完成并从绘图开始”);
label.setText(“label是可更新的”);//检查整个方法是否完成,以及标签是否确实能够更新。它可以工作。
}
//draw()主要设置框架,命名框架,设置关闭行为。它工作正常。
公众抽签(){
System.out.println(“draw start”);//检查方法是否被调用。
SWUI框架=新SWUI();
帧。设置标题(“视觉文字摇滚”);
WindowListener l=新的WindowAdapter(){
公共无效窗口关闭(WindowEvent e){
系统出口(0);
}
};
frame.addWindowListener(l);
frame.pack();
frame.setVisible(true);
System.out.println(“draw done”);//检查整个方法是否完成。一切正常。
}
//应将标签更改为每1秒4句。标签文本确实会更改,但不会显示在界面(面板)上。
私有void updateLabel(字符串字){
label.setText(word);
//label.revalidate();//我一次尝试了这三条语句,两条语句都尝试了,但都没有什么不同。
//label.updateUI();
//label.repaint();
System.out.println(“现在的标签是:“+label.getText());//这确认了setText()确实在更改文本
//标签的名称,但它不显示在界面上。
}
//Main获取开始启动接口的draw(),并每秒将语句更改并发送到updateLabel()。
公共静态void main(字符串参数[])
抛出中断异常{
SWUI=新的SWUI();
ui.draw();
字符串重要性信息[]={
“母马吃燕麦”,
“狗吃燕麦”,
“小羊羔吃常春藤”,
“孩子也会吃常春藤”
};
对于(int i=0;
i<重要信息长度;
(i++){
//暂停1秒钟
睡眠(1000);
//打印消息
系统输出打印LN(重要信息[i]);
ui.label.setText(importantInfo[i]);
ui.updateLabel(importantInfo[i]);
}
}
//这将在我找到修复标签的方法后出现。其他人建议问题在于侦听器不允许线程
//执行repainting(),但我尝试摆脱了“implements ActionListener”和actionPerformed方法,但没有成功
//不同,它仍然不起作用。
@凌驾
已执行的公共无效操作(操作事件arg0){
//TODO自动生成的方法存根
}
}

您在
SWUI
中的
draw
方法创建了一个全新的帧,而您的更新将转到初始帧,而初始帧从未真正设置为可见。要修复此问题,绘制方法应该更像这样

public void draw() {

        System.out.println("draw started");         //To check that the method is getting invoked.

        setTitle("Sight Words Rock");

        WindowListener l = new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
           System.exit(0);
         }
      };
        addWindowListener(l);

        pack();
        setVisible(true);
    System.out.println("draw done");        //To check that the whole method went through. It's all working.

}

那么您从哪个线程调用
setText
?请记住,对swing组件的所有更新都必须在EDT上进行,如果需要从另一个线程触发更新,请使用
SwingUtilities.invokeLater
。1)使用逻辑一致的代码行和代码块缩进形式。缩进的目的是使代码的流程更易于遵循!2) 在源代码中只需要一行空白就可以了。
{
之后或
}
之前的空行通常也是多余的。非常感谢pvg提供的详尽而清晰的解释。系统退出(0);在windowClosing==JFrame.s中