刷新Java GUI元素

6
我刚开始接触Java中的GUI。例如,我只需要更新一个元素(如JLabel)。在Tkinter中,我会使用类似root.update()root.update_idletasks()的函数。我想知道是否有类似的简单函数可以用于使用Swing构建的应用程序。我尝试过gui_element.SetVisible(false)gui_element.SetVisible(true)等类似的方法,但并不成功。我认为使用javax.swing.Timer可能有效,但不知道具体怎么做。 编辑:这里是代码,请告诉我是否发现其他错误。谢谢。
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class sof_sample{

    /**
     * @param args
     */

    private static JFrame frame1 = new JFrame("Fractal Geometry");
    public static JButton quit_button = new JButton("Quit");
    private static JButton run_button = new JButton("Run");
    private static JLabel label1 = new JLabel();
    public static JLabel label_iter = new JLabel(); 
    private static GridLayout layout1 = new GridLayout(2,20);
    private JOptionPane msg1 = new JOptionPane();
    private static int counter;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AuxClass1 inst1 = new AuxClass1();
        quit_button.addActionListener(inst1);
        run_button.addActionListener(inst1);
        label1.setText("Iteration");
        label1.setVerticalTextPosition(JLabel.CENTER);
        label1.setHorizontalAlignment(JLabel.CENTER);
        label_iter.setText("0");
        label_iter.setBorder(BorderFactory.createLineBorder(Color.BLACK));      
        label_iter.setVerticalTextPosition(JLabel.CENTER);
        label_iter.setHorizontalAlignment(JLabel.CENTER);

        //add widgets to the frame
        frame1.add(label1);
        frame1.add(label_iter);
        frame1.add(run_button);
        frame1.add(quit_button);

        frame1.setLayout(layout1);
        frame1.setLocationRelativeTo(null);
        //frame1.pack();
        frame1.setSize(250, 75);
        frame1.setVisible(true);

    }

}

class AuxClass1 implements ActionListener{
    sof_sample inst2 = new sof_sample();

    public void actionPerformed(ActionEvent event1){

        if (event1.getSource()==inst2.quit_button){
            System.exit(0);

        }
        else{
            for (int i=0;i<20000;i++){

                inst2.label_iter.setText(Integer.toString(i));

            }
            //msg1.showMessageDialog(frame1, "Not yet!");

        }


    }



}

2
为了更快地获得更好的帮助,请发布一个SSCCE - Andrew Thompson
2个回答

7
Swing是事件驱动的。所有组件都通过MVC模式工作。您不需要通过隐藏/显示来显式地重绘它以更新其在屏幕上的表示。
您只需执行yourLabel.setText(“your new text”),新文本将出现在标签上。
请记住,大多数GUI更新(setText是一个例外)需要在EDT上执行,因此如果您的更新由网络消息触发,请使用SwingUtilities.invokeLater等。
如果您对GUI进行结构更改,则必须重新验证(revalidate())/repaint()

我尝试了 repaint(),但没有任何变化。如果说有一个计数器的更新,我在循环中使用 label_name.setText(Integer.toString(i)),其中 i<100,但我只看到最后一个值(99)。我做错了什么? - Alex
发布一个 SSCCE,我会看一下。 - aioobe
你正在独占EDT(不断重绘GUI的线程)。在另一个线程中执行循环,以避免阻止EDT完成其工作(更新GUI)。 - aioobe
对不起,请问你能否更明确一些?我不太理解'hog the edt'是什么意思。 - Alex

0
通过使用Javax.swing.Timer,您可以实现您的目标。
    timer = new Timer(100,new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            label.setText(String.valueOf(i));
            if(i==100){
                timer.stop();
            }
            i++;
        }
    });

当您想要更改JLabel上的值时,只需使用timer.start()启动计时器,因此标签上的值将更改直到100。当i值达到100时,timer.stop()将停止计时器。

这是javax.swing.timer教程。请看一下。 http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/Timer.html

从以下链接下载工作示例...

https://docs.google.com/open?id=0B9U-BwYu62ZaQWZMWloxdHp0YWs

我认为它适合你使用...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接