【问题标题】:Progress Bar does not update [closed]进度条不更新[关闭]
【发布时间】:2015-07-21 00:58:28
【问题描述】:

我的进度条只更新到 100%。我检查打印,似乎一切都按原样运行,但 UI 没有根据打印检查中的参数更新!

这是我的面板类。主类创建框架添加我创建的 MyPanel:

public class MyPanel extends JPanel {

    File[] DFLIST;
    File DF[];
    File INP;
    File LOG;
    JButton chooseDF = new JButton("Choose defect file");
    JButton chooseLog = new JButton("Choose log file");
    JButton chooseInp = new JButton("Choose inp file");
    JButton analayze = new JButton("Analayze");
    DefectFileReader[] dfReader;
    Document[] docArray;
    boolean DFloaded = false;
    boolean LOGloaded = false;
    boolean INPloaded = false;
    Checkbox recipeName;
    Checkbox inspectionDuration;
    Checkbox area;
    Checkbox numberOfDefects;
    Checkbox numberOfDefectsPerDetector;
    Checkbox sensetivityName;
    Checkbox SlicesDetected;
    private static int rowIndex = 2;
    private static int cellIndex = 4;
    FileOutputStream fos;
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("analyze_result");
    Row row = sheet.createRow(rowIndex);
    Cell cell = row.createCell(cellIndex);
    XSSFCellStyle csForFirstWrite = workbook.createCellStyle();
    XSSFCellStyle csForSecondWrite = workbook.createCellStyle();
    XSSFFont fontForBold = workbook.createFont();
    XSSFFont fontNotForBold = workbook.createFont();
    String totalDuration = "00:00:00";
    private int currentFolder = 0;
    //TwoRoot t;
    JProgressBar pBar = new JProgressBar();
    Frame frame = new Frame("Progress Bar");
    MyprogressBar taskBar;



    /* creating the main panel of the frame - divided to 3 parts. in the north pictures , in the west checkbox , in the east the file chooser */

    public MyPanel(){ 
        this.setLayout(new BorderLayout());
        this.add(pictureInNorth() , BorderLayout.NORTH);
        this.add(checkBoxPanel() , BorderLayout.WEST);
        this.add(chooseFilesPanel() , BorderLayout.EAST);
        //pBar.setForeground(Color.black);
        //pBar.setStringPainted(true);
        //this.add(pBar , BorderLayout.SOUTH);

    }


    /* creating the north panel with the picture */
private JPanel pictureInNorth(){
    JPanel toReturn = new JPanel();
    toReturn.setBackground(Color.black);
    JButton analayzerPic = new JButton(new ImageIcon(new ImageIcon("C:/Users/uvalerx073037/workspace/Analayzer_GUI_Ver2/src/Images/vXqyQkOv.jpeg")
                            .getImage().getScaledInstance(600, 30,
                                    java.awt.Image.SCALE_SMOOTH)));
    analayzerPic.setBackground(Color.black);
    toReturn.add(analayzerPic);
    return toReturn;

}

    /* creating the checkBox in the west */

private JPanel checkBoxPanel(){
    recipeName = new Checkbox("Recipe Name" , false);
    inspectionDuration = new Checkbox("Inspection Duration" , false);
    area = new Checkbox("Area" , false);
    numberOfDefects = new Checkbox("Number Of Defects" , false);
    numberOfDefectsPerDetector = new Checkbox("Number Of Defects Per Detector", false);
    sensetivityName = new Checkbox("Sensetivity Name", false);
    SlicesDetected = new Checkbox("Slices were detected" , false);
    JPanel toReturn = new JPanel();
    toReturn.setLayout(new BoxLayout(toReturn, BoxLayout.Y_AXIS));
    toReturn.add(recipeName);
    toReturn.add(inspectionDuration);
    toReturn.add(numberOfDefects);
    toReturn.add(numberOfDefectsPerDetector);
    toReturn.add(sensetivityName);
    toReturn.add(SlicesDetected);
    toReturn.add(area);

    return toReturn;

}

    /*creating the file chooser in the east */

private Box chooseFilesPanel(){
    MyActionListener lis = new MyActionListener();
    chooseDF.addActionListener(lis);
    chooseInp.addActionListener(lis);
    chooseLog.addActionListener(lis);
    analayze.addActionListener(lis);
    analayze.setForeground(Color.BLUE);
    Box toReturn = Box.createVerticalBox();
    toReturn.add(Box.createGlue());
    toReturn.add(chooseDF);
    toReturn.add(Box.createGlue());
    toReturn.add(chooseLog);
    toReturn.add(Box.createGlue());
    toReturn.add(chooseInp);
    toReturn.add(Box.createGlue());
    toReturn.add(analayze).setSize(50,50);

    return toReturn;

}

/* function to check after the user clicked on the analyze button if all the conditions are OK */

public Boolean isValidToStart(){
    if(DFloaded == false && LOGloaded == false && INPloaded == false){
        JOptionPane.showMessageDialog(null, "NO FILE WAS LOADED!!!", "User Error" , JOptionPane.ERROR_MESSAGE);
        return false;
    }
    if(recipeName.getState() == false && inspectionDuration.getState() == false && area.getState() == false && 
            numberOfDefects.getState() == false && numberOfDefectsPerDetector.getState() == false && sensetivityName.getState() == false){
        JOptionPane.showMessageDialog(null , "NO CHECK BOX WAS MARKED!!!" + "\n" + "WHAT DATA WOULD YOU LIKE TO COLLECT?" , "User Error" , JOptionPane.ERROR_MESSAGE );
        return false;
    }
    if(area.getState() == true && (LOGloaded == false || DFloaded == false || INPloaded == false)){
        JOptionPane.showMessageDialog(null , "IF YOU WANT TO COLLECT AERA YOU NEED TO CHOOSE INP + LOG + DEF" , "User Error" , JOptionPane.ERROR_MESSAGE );
        return false;
    }
    if(SlicesDetected.getState() == true && LOGloaded == false){
        JOptionPane.showMessageDialog(null , "You need to load the LOG in order to get the amount of slices were detected!" , "User Error" , JOptionPane.ERROR_MESSAGE );
        return false;
    }
    else
        return true;

}

/* build the row of the titles , only what the user marked in the check box */ 

private void firstWriteToExcel(DefectFileReader curDF , XSSFSheet sheet , XSSFWorkbook workbook , FileOutputStream fos) throws Exception{

    fontForBold.setBold(true);
    csForFirstWrite.setFont(fontForBold);
    csForFirstWrite.setFillForegroundColor(new XSSFColor(java.awt.Color.lightGray));
    csForFirstWrite.setFillPattern(CellStyle.SOLID_FOREGROUND);
    csForFirstWrite.setBorderBottom(XSSFCellStyle.BORDER_MEDIUM);
    csForFirstWrite.setBorderTop(XSSFCellStyle.BORDER_MEDIUM);
    csForFirstWrite.setBorderRight(XSSFCellStyle.BORDER_MEDIUM);
    csForFirstWrite.setBorderLeft(XSSFCellStyle.BORDER_MEDIUM);


    if(recipeName.getState() == true){
        row = sheet.createRow(rowIndex - 1);
        row.createCell(cellIndex).setCellValue("Recipe Name: " + curDF.getRecipeName());
        sheet.autoSizeColumn(cellIndex);
    }
    row = sheet.createRow(rowIndex++);
    row.createCell(cellIndex).setCellValue("inspection index");
    sheet.autoSizeColumn(cellIndex);
    cellIndex++;
    if(numberOfDefects.getState() == true){
        row.createCell(cellIndex).setCellValue("Total Defects");
        sheet.autoSizeColumn(cellIndex);
        cellIndex++;
    }
    if(numberOfDefectsPerDetector.getState() == true){
        ArrayList<String> toOtherFunc = new ArrayList<String>();
        toOtherFunc = curDF.getDetectorNames();
        for(int i=0; i < toOtherFunc.size() ; i++){
            row.createCell(cellIndex).setCellValue(toOtherFunc.get(i)); 
            sheet.autoSizeColumn(cellIndex);
            cellIndex++;
        }
    }
    if(sensetivityName.getState() == true){
        row.createCell(cellIndex).setCellValue("sensetivity Name");
        sheet.autoSizeColumn(cellIndex);
        cellIndex++;
    }
    if(LOGloaded == true){
        row.createCell(cellIndex).setCellValue("Slices were detected");
        sheet.autoSizeColumn(cellIndex);
        cellIndex++;

    }
    if(inspectionDuration.getState()==true){
        row.createCell(cellIndex).setCellValue("Inspection Duration");
        sheet.autoSizeColumn(cellIndex);
        cellIndex++;
    }


    for (Row row : sheet){
        for (Cell cell_local : row){
            cell_local.setCellStyle(csForFirstWrite);
        }


    }

    System.out.println("row index is: " + rowIndex + "cell index is: " + cellIndex);

}


/* fill the excel in the data were collected */

private void writeToExcel(DefectFileReader curDF , XSSFSheet sheet , XSSFWorkbook workbook , FileOutputStream fos) throws Exception{

        fontNotForBold.setBold(false);
        csForSecondWrite.setFont(fontNotForBold);
        csForSecondWrite.setFillForegroundColor(new XSSFColor(java.awt.Color.white));
        csForSecondWrite.setFillPattern(CellStyle.SOLID_FOREGROUND);
        csForSecondWrite.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        csForSecondWrite.setBorderTop(XSSFCellStyle.BORDER_THIN);
        csForSecondWrite.setBorderRight(XSSFCellStyle.BORDER_THIN);
        csForSecondWrite.setBorderLeft(XSSFCellStyle.BORDER_THIN);
    cellIndex = 4;
    row = sheet.createRow(rowIndex++);
    row.createCell(cellIndex++).setCellValue("inspection_" + (rowIndex - 3));
    if(numberOfDefects.getState() == true)
        row.createCell(cellIndex++).setCellValue(curDF.getTotalDefects());
    if(numberOfDefectsPerDetector.getState() == true){
        ArrayList<String> toOtherFunc = new ArrayList<String>();
        int[] toPrintNumber = new int[toOtherFunc.size()];
        toOtherFunc = curDF.getDetectorNames();
        System.out.println(toOtherFunc);
        toPrintNumber = curDF.getDefectPerDetector(toOtherFunc);
        for(int i=0; i < toOtherFunc.size() ; i++)
            row.createCell(cellIndex++).setCellValue(toPrintNumber[i]); 
    }
    if(sensetivityName.getState() == true)
        row.createCell(cellIndex++).setCellValue(curDF.getSensetivityName());
    if(LOGloaded == true){
        LogFileReader logReader = new LogFileReader(LOG , curDF.getInspectionEndTime());
        ArrayList<String> toLog = curDF.getRunsIndex();
        String toPrint = "";
        for(int i=0 ; i < toLog.size() ; i = i+2)
            toPrint += toLog.get(i) + ": " + logReader.diagnozeLog(toLog.get(i+1)) + " ";
        if(toPrint.equals(""))
            row.createCell(cellIndex).setCellValue("The data of this run is not in this log!");
        else
            row.createCell(cellIndex).setCellValue(toPrint);
        sheet.autoSizeColumn(cellIndex);
        cellIndex++;

    }
    if(inspectionDuration.getState()==true)
        row.createCell(cellIndex++).setCellValue(curDF.inspectionDuration());


    for (Row row : sheet){
        if( row.getRowNum() > 2){
        for (Cell cell_local : row){
            cell_local.setCellStyle(csForSecondWrite);
        }
        }


    }


    System.out.println("row index is: " + rowIndex + " cell index is: " + cellIndex);


}

/* adding the inspection time of the current run to the total time */

public String sumTimes(String time1) {
    PeriodFormatter formatter = new PeriodFormatterBuilder()
            .minimumPrintedDigits(2)
            .printZeroAlways()
            .appendHours()
            .appendLiteral(":")
            .appendMinutes()
            .appendLiteral(":")
            .appendSeconds()
            .toFormatter();

    org.joda.time.Period period1 = formatter.parsePeriod(time1);
    org.joda.time.Period period2 = formatter.parsePeriod(totalDuration);
    return formatter.print(period2.plus(period1).normalizedStandard());
}

public void initializeFrame(){
    frame.setSize(300, 100);
    pBar.setForeground(Color.black);
    pBar.setStringPainted(true);
    frame.add(pBar);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

class MyprogressBar extends SwingWorker<Void, Integer> {

    JProgressBar pBar;
    int max;
    int currentFolder;

    public MyprogressBar(JProgressBar curBar , int max , int currentFolder){
        this.pBar = curBar;
        this.max = max;
        this.currentFolder = currentFolder;
    }
    public void done(){

    }


    @Override
    protected Void doInBackground() throws Exception {
            System.out.println("i'm in background");
            double i = currentFolder;
            double t = DFLIST.length;
            double toSetInDouble = (i/t);
            int toSet = (int) (toSetInDouble * 100);
            pBar.setValue(toSet); 
            System.out.println(toSet);
            repaint();
            Thread.sleep(10); 
            publish(toSet);

        return null;
    }

}

    /* adding listener to all of the buttons and check boxes */

public class MyActionListener implements ActionListener  
{
    public void actionPerformed(ActionEvent click) 
    {
        if(click.getSource() == chooseDF){
            File directory;
            FilenameFilter f = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.length()<=2;
                }
            };
            FilenameFilter def = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith(".def");
                }
            };
            JFileChooser chooser = new JFileChooser(System.getProperties().getProperty("user.dir"));
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if(chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
                DFloaded = true;
                directory = chooser.getSelectedFile();
                File[] fileList = directory.listFiles(f);
                Arrays.sort(fileList , new NaturalOrderComparator());
                DFLIST = new File[fileList.length];
                for(int i = 0 ; i<fileList.length ; i++){
                    File[] tmp = fileList[i].listFiles(def);
                    for(int j=0 ; j<tmp.length ; j++)
                        DFLIST[i] = tmp[j];
                }
            }

        }

        if(click.getSource() == chooseInp){
            JFileChooser fc2 = new JFileChooser();
            if (fc2.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
                INPloaded = true;
                INP = fc2.getSelectedFile();
            }
        }

        if(click.getSource() == chooseLog){
            JFileChooser fc3 = new JFileChooser();
            if(fc3.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
                LOGloaded = true;
                LOG = fc3.getSelectedFile();


            }
        }

        if(click.getSource() == analayze){
            Boolean valid = isValidToStart();
            if(valid == true){
                try{
                fos = new FileOutputStream("c:/temp/analayze.xlsx");
            if(DFloaded == true){
                try {
                    initializeFrame();
                    DF = new File[DFLIST.length];
                    dfReader = new DefectFileReader[DFLIST.length];
                    docArray = new Document[DFLIST.length];
                    for( ; currentFolder < DFLIST.length ; currentFolder++){
                        new MyprogressBar(pBar, 100, currentFolder + 1).execute();
                        frame.repaint();
                        System.out.println("i'm sending the file down here to parse from file to document");
                        System.out.println(DFLIST[currentFolder].getAbsoluteFile());
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        DocumentBuilder db = dbf.newDocumentBuilder();
                        docArray[currentFolder] = (Document) db.parse(DFLIST[currentFolder]);
                        docArray[currentFolder].getDocumentElement().normalize();
                        dfReader[currentFolder] = new DefectFileReader(DFLIST[currentFolder] , docArray[currentFolder]);
                        dfReader[currentFolder].getRunsIndex();
                        totalDuration = sumTimes(dfReader[currentFolder].inspectionDuration());
                        if(currentFolder==0){
                            firstWriteToExcel(dfReader[0], sheet, workbook, fos);
                            writeToExcel(dfReader[0], sheet, workbook, fos);
                        }
                        if(currentFolder!=0)
                            writeToExcel(dfReader[currentFolder] , sheet ,  workbook , fos );
                        repaint();
                    if(INPloaded == true){

                    }
                    DFLIST[currentFolder] = null;
                    dfReader[currentFolder].clearDfReader();
                    docArray[currentFolder] = null;
                    System.gc();
                   }
                }
                   catch(Exception e ) {
                      System.out.println(e);
                      System.exit(0);
                   }
            }

            row = sheet.createRow(rowIndex);
            totalDuration = sumTimes("00:00:00");
            if(inspectionDuration.getState() == true){
            row.createCell(cellIndex - 1).setCellValue(totalDuration);
            row.getCell(cellIndex - 1).setCellStyle(csForFirstWrite);
            }
            ((Workbook) workbook).write(fos);
            workbook.close();
            JOptionPane.showMessageDialog(null, "Your data has been analyze!\n you can find the result in c:\\temp");
            System.exit(0);

        }catch(Exception e){
            e.printStackTrace();
        }

    }
}


}
}



}

【问题讨论】:

  • 您违反了 Swing 的单线程规则,请参阅Concurrency in Swing 了解更多详情,Worker Threads and SwingWorker 了解可能的解决方案
  • for( ; currentFolder &lt; DFLIST.length ; currentFolder++){ 可能会阻塞 EDT
  • 谢谢!我尝试使用 swingWorker 并发现它非常混乱。这是唯一的方法吗?
  • 这不是唯一的方法,它是一种更受欢迎、更简单、更干净的方法……作为example
  • 问题是我发现很难使用这个框架(swingworker)来更新我的 for 循环中的实际值。有什么建议吗?

标签: java multithreading swing progress-bar


【解决方案1】:

@Udi 如果您可以粘贴结构化代码,那就太好了。但是,无论您粘贴什么代码,这里都是使用 swingworker 的指示性解决方案。您只需要从 swingworker 的 doInBackground() 调用整个 actionPerformed() 代码。希望对您有所帮助。

此外,我发现 swingworker 的 java 文档对于理解它是如何工作的非常有用。示例非常简单,但解释得很好。 https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html

    // use this code inside actionPerformed()
    new SwingWorker(){

        @Override
        protected Object doInBackground() throws Exception {

            // all your code goes here

            for( ; currentFolder < DFLIST.length ; currentFolder++){
                                 double f = currentFolder + 1;
                                double t = DFLIST.length;
                                double currentPercentInDouble = (f / t);
                                int currentPercent = (int) (currentPercentInDouble * 100);

                                // send the current progress to progress bar. This needs to be updated to progress bar in process() method
                                publish(currentPercent)

            }

            // rest of the code
        }


        @Override 
        protected void process(List<V> chunks) {
                // update the progress bar here
        }

    }.execute();

【讨论】:

  • 感谢您的帮助,但我没能解决这个问题。 @Rahul 现在我粘贴整个代码时你能检查一下吗?
  • @Udi 您的代码存在问题,您仍在事件调度程序线程中工作。如果您仔细阅读我的答案,我说过您需要在 doInBackground() 中执行您在 actionPerformed() 方法中所做的所有事情。更新进度条将在 swingworker 的 process() 方法中进行。坦率地说,您的代码非常庞大,具有许多依赖项,并且纠正这将是一项繁琐的任务。我建议你自己做。你可以参考 swing worker 的 javadocs 做更多的阅读。
  • 保持您的代码不变。只需在 actionPerformed() 中创建一个 swing worker 并将所有内容放入 doInBackground() ..send percent to publish() 方法的 swingworker 中。并更新 process() swingworker 中的进度条。
  • 拉胡尔。谢啦!坐多了之后,我成功了。总的来说,我按照你说的做了,这对我帮助很大。尽快发布最终代码(仅相关)。
猜你喜欢
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 2020-10-06
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多