【问题标题】:Unexplainable behaviour of setProgress in SwingWorkerSwingWorker 中 setProgress 的无法解释的行为
【发布时间】:2016-08-15 08:01:09
【问题描述】:

我做了一个快速而肮脏的 SwingWorker 实现来测试 publish() 和 setProgress() 方法。当我为 setProgress() 方法设置参数时,如下面的完整源代码中所述,一切都按预期工作。 但是,如果我像这样设置 setProgress 参数: setProgress((int) ((i/2000) * 100)); 或者像这样 setProgress((int) (i * (100/2000)));

进度条不会更新,因为 propertyChange 没有被触发。

我真的不知道为什么会这样,因为在我看来我没有看到任何数学错误......

有什么想法吗?

提前致谢!

最好的问候

package test;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;

public class ConsoleTest extends SwingWorker<Void, String>{ 

private JTextPane console;
private JProgressBar pb;

public ConsoleTest(JProgressBar pb, JTextPane out){

    this.console = out;
    this.pb = pb;
}

private static void createGUI(){

    JFrame container = new JFrame();
    container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTextPane console = new JTextPane();
    JButton start = new JButton("start");
    JButton reset = new JButton("reset");
    JPanel btnpane = new JPanel();
    btnpane.add(start);
    btnpane.add(reset);
    btnpane.add(new JCheckBox( "Click me to proof UI is responsive" ));
    JProgressBar pb = new JProgressBar(0,100);
    btnpane.add(pb);
    container.add(btnpane, BorderLayout.SOUTH);

    JScrollPane sp = new JScrollPane(console);
    sp.setPreferredSize(new Dimension(800,800));
    container.add(sp,BorderLayout.NORTH);

    start.addActionListener(e -> { ConsoleTest test = new ConsoleTest(pb, console);
                                   test.addPropertyChangeListener(evt -> { if ("progress".equals(evt.getPropertyName())) {
                                                                             System.out.println("check");
                                                                             test.getPG().setValue((int)evt.getNewValue());
                                                                           }                                                                                  
                                                                         });
                                   test.execute();
                                 });
    reset.addActionListener(e -> clear(console));
    container.pack();
    container.setVisible(true);


}

private static void clear(JTextPane console) {

    console.setText("");
}



public JProgressBar getPG(){

    return this.pb;
}

@Override
protected Void doInBackground() throws Exception {

    LinkedList<Integer> list = new LinkedList<>();
    for (int i = 0; i< 2000;i++){
        list.add(i);
        if(((i+1) % 5) == 0)
            publish(Integer.toString(i+1));
        setProgress((int) (i*100/2000));
        Thread.sleep(1);            
    }
    return null;
}

@Override
protected void process(List<String> chunks){

        StyledDocument doc = this.console.getStyledDocument();
        try {
            for(String s: chunks)
            doc.insertString(doc.getLength(),"- "+s+" elements added to the list\n", null);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }       
}


@Override
protected void done() {

    try {
        System.out.println("DONE!!!");
    } 
    catch (Exception ignore) {
    }
}

public static void main(String[] args) {

    createGUI();
}

}

【问题讨论】:

  • 不知何故编辑“吃了”多重符号

标签: java jtextpane swingworker jprogressbar


【解决方案1】:

你使用整数!!

setProgress((int) ((i/2000)*100));

总是0,因为(int)i / 2000总是0

同样的问题

setProgress((int) (i*(100/2000)));

100 / 2000 始终是整数 0

试试

setProgress((int) (((float)i/2000)*100));

setProgress((int) (i*((float)100/2000)));

它会起作用的

【讨论】:

    【解决方案2】:

    你应该做 (i * 100)/2000 公式是

    (current_state * 100) / final_state

    【讨论】:

    • 不知何故,编辑吃了我的“*”符号。文档中的任何地方都必须这样写吗?从数学上讲 (i * 100) / 2000 与 i * (100/2000) 相同
    • 因为您使用 int 作为最终类型并且不进行浮点转换 100/2000 始终为零,因此进度保持为 0。
    猜你喜欢
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多