SwingWorker 中 setProgress 的无法解释的行为
Unexplainable behaviour of setProgress in SwingWorker
我对 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();
}
}
你应该使 (i * 100)/2000
公式是
(current_state * 100) / final_state
你使用整数!!
setProgress((int) ((i/2000)*100));
总是0
因为(int)i / 2000
总是0
同样的问题
setProgress((int) (i*(100/2000)));
100 / 2000
总是 0
in integer
尝试
setProgress((int) (((float)i/2000)*100));
或
setProgress((int) (i*((float)100/2000)));
它会起作用
我对 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();
}
}
你应该使 (i * 100)/2000 公式是
(current_state * 100) / final_state
你使用整数!!
setProgress((int) ((i/2000)*100));
总是0
因为(int)i / 2000
总是0
setProgress((int) (i*(100/2000)));
100 / 2000
总是 0
in integer
尝试
setProgress((int) (((float)i/2000)*100));
或
setProgress((int) (i*((float)100/2000)));
它会起作用