2016-08-15 2 views
1

Я сделал быструю и грязную реализацию SwingWorker для тестирования методов publish() и setProgress(). Когда я устанавливаю параметр для метода setProgress(), как указано в полном исходном коде ниже, все работает так, как ожидалось. Однако если установить параметр setProgress так: setProgress((int) ((i/2000) * 100)); ИЛИ как этот setProgress((int) (i * (100/2000)));Необъяснимое поведение setProgress в SwingWorker

прогрессбар не обновляется, так как 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(); 
} 

}

+0

как-то редактор «съел» muliply знак – motaa

ответ

3

вы работаете с целыми числами!

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))); 

и он будет работать

+0

святой молибденовые! Как я мог этого не увидеть ... думаю, у меня в голове пустота :) – motaa

0

вы должны сделать (я * 100)/2000 формула

(current_state * 100)/final_state

+0

как-то редактор съел мой «*» знаки. Это где-нибудь написано в документах, что это должно быть именно так? Математически говоря (i * 100)/2000 - это то же самое, что и i * (100/2000) – motaa

+0

, так как вы используете int как окончательный тип и не делаете поплавок, литой 100/2000 всегда равен нулю, следовательно прогресс остается 0. – whyn0t

Смежные вопросы