0

我想以大约 300 毫秒的恒定速率更新 JLabel。目前我正在使用以下代码部分来执行此操作:

class setLabel {

    PdfHandler PdfHandling = new PdfHandler(pdfName);//as the name implies, this object is to handle pdf's
    Iterator<String> textIterator=PdfHandling.getPageStringList(pageNr).iterator();//extracting text from a pdf word by word

    ActionListener task = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            centerLabel.setText(textIterator.next());//update the JLabel cenetrLabel with the next string in the textIterator
        }
    };

    public void startTask(){
            new javax.swing.Timer(rate, task).start();
    }

}

问题是使用此代码会导致 JLabel (centerLabel) 的非恒定更新。这意味着两个“新”标签之间的时间不是恒定的(您可以用肉眼看到),并且由于更新之间的时间太短,一些字符串似乎被跳过了。我已经尝试了几种不同的方法,例如使用 invokeLater 或 shedledExecutorService 但似乎都有同样的问题。我的问题是,这是否是正确的方法,如果从一开始就为这项任务使用 JLabel 方法是一个坏主意?如果是这样,以平滑控制的方式(有点像视频)一个接一个地显示字符串的好方法是什么。

非常感谢,任何帮助和建议都非常感谢。

编辑:

我尝试使用以下代码而不是迭代器,尽管我不知道这是否更快:

class stringBuffer {
    private ArrayList<String> buf;
    private final int size;
    private int index;

    stringBuffer(ArrayList<String> list){
            buf = list;
            size = buf.size();
    }

    public String getNext(){
            if(index < size){
                return buf.get(index++);
            } else {
                return null;
            }
    }

}

问题仍然存在,所以我尝试直接访问列表

centerLabel.setText(list.get(index++));

但这仍然没有解决问题。

第二次编辑:

这是一个演示问题的可运行示例:

import java.util.ArrayList;
import java.util.Arrays;

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

import java.awt.event.*;
import java.awt.BorderLayout;

class JLabelTest {
    public static void main(String[] args){
        BuildGui gui = new BuildGui();
    }
}

class BuildGui {
    JFrame topLevelFrame;
    JLabel centerLabel;
    JButton startButton;

    BuildGui(){
        initFrame();
        addElements();
        addActionListeners();
    }

    public void initFrame(){
        topLevelFrame = new JFrame("JFrame");
        topLevelFrame.setBounds(200, 200, 400, 200);
        topLevelFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        topLevelFrame.setVisible(true);
    }

    public void addElements(){
        centerLabel = new JLabel("Center");
        startButton = new JButton("Start");

        centerLabel.setHorizontalAlignment(JLabel.CENTER);
        centerLabel.setVerticalAlignment(JLabel.CENTER);

        topLevelFrame.add(startButton, BorderLayout.SOUTH);
        topLevelFrame.add(centerLabel,BorderLayout.CENTER);
    }

    public void addActionListeners(){

        startButton.addActionListener( new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                new setLabel().startTask();
                startButton.setEnabled(false);
            }
        });

    }


    class setLabel {

        private final String[] stringArray =     {"one","two","one","two","one","two","one","two"};//just something to display
        private final int size = stringArray.length;
        private final ArrayList<String> list = new ArrayList<String>(Arrays.asList(stringArray));
        private int index = 0;

        ActionListener task = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
            centerLabel.setText(list.get(index++));
            if(index >= size) index = 0;
            }
        };

        public void startTask(){
            new javax.swing.Timer(300, task).start();
        }

    }

}

第三次编辑

我听说前面的例子有几个问题。所以我试图修复它们,我希望这个例子更好

import java.util.ArrayList;
import java.util.Arrays;

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

import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.EventQueue;

class JLabelTest2 extends JFrame {
    JLabel centerLabel;
    JButton startButton;

    public static void main(String[] args){
        EventQueue.invokeLater(() -> {
            JLabelTest2 gui = new JLabelTest2();
            gui.setVisible(true);
        });
    }

    JLabelTest2(){
        initUI();
    }

    public void initUI(){
        setBounds(200, 200, 400, 200);

        centerLabel = new JLabel("Center");
        startButton = new JButton("Start");

        centerLabel.setHorizontalAlignment(JLabel.CENTER);
        centerLabel.setVerticalAlignment(JLabel.CENTER);

        getContentPane().add(startButton, BorderLayout.SOUTH);
        getContentPane().add(centerLabel,BorderLayout.CENTER);

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        startButton.addActionListener( new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                new setLabel().startTask();
                startButton.setEnabled(false);
            }
        });

        pack();

    }

    class setLabel {

        private final String[] stringArray = {"one","two","one","two","one","two","one","two"};
        private final int size = stringArray.length;
        private final ArrayList<String> list = new ArrayList<String>(Arrays.asList(stringArray));
        private int index = 0;

        ActionListener task = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                centerLabel.setText(list.get(index++));
                if(index >= size) index = 0;
            }
        };

        public void startTask(){
            new javax.swing.Timer(300, task).start();
        }

    }

}

但不知何故,我的机器上仍然存在问题。我没有运行很多程序,即使我关闭所有正在运行的程序,问题也不会改变。我看不到的代码中是否还有一些问题?

第四次编辑

添加 centerLabel.repaint() 并没有改变行为。我仍然看到标签发生变化,但频率不稳定。环境信息:

操作系统:Ubuntu 14.04 LTS,64 位

处理器:Intel Core™ i5-2430M CPU @ 2.40GHz × 4

内存:5,7 GiB

Java信息:

java版本“1.8.0_102”

Java(TM) SE 运行时环境 (build 1.8.0_102-b14)

Java HotSpot(TM) 64 位服务器 VM(内部版本 25.102-b14,混合模式)

4

0 回答 0