如何使进度不确定任务循环循环进度?

时间:2018-01-28 20:54:40

标签: java swing netbeans

我有一个检索数据的程序,其中每个检索都无法确定其完成时间。我的想法是在捕获完成时进行不断重复和标记的进度。

我目前的源代码,来自主类的方法:

public JComponent makeUI(boolean  displayProgressBar) {

if(displayProgressBar){
        jpbCircularProg.setUI(new principal.ProgressCircleUI());
        jpbCircularProg.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
        //Border emptyBorder = BorderFactory.createEmptyBorder();
        //jpbCircularProg.setBorder(emptyBorder);
        jpbCircularProg.setStringPainted(true);
        jpbCircularProg.setFont(jpbCircularProg.getFont().deriveFont(24f));
        jpbCircularProg.setForeground(Color.ORANGE);
        if(jpbCircularProg.isVisible()==false){
            jpbCircularProg.setVisible(true);
        }
        (new Timer(10, e -> {// percepat
            System.out.println("progressbar on :");
            int iv = Math.min(100, jpbCircularProg.getValue() + 1);
            jpbCircularProg.setValue(iv);
            if(jpbCircularProg.getValue()==100){
                jpbCircularProg.setValue(1);
            }
        })).start();
    }else{
        if(jpbCircularProg.isVisible()==true){
            jpbCircularProg.setVisible(false);
        }
        (new Timer(10, e -> {// percepat
            System.out.println("progressbar on :");
            int iv = Math.min(100, jpbCircularProg.getValue() + 1);
            jpbCircularProg.setValue(iv);
            if(jpbCircularProg.getValue()==100){
                jpbCircularProg.setValue(0);
                jpbCircularProg.setStringPainted(true);
                jpbCircularProg.setVisible(false);
            }
        })).start();
     }

    jPanel2.setOpaque(false);
    jPanel2.add(jpbCircularProg);
    return jPanel2;
}

ProgressCircleUI.java:

public class ProgressCircleUI extends BasicProgressBarUI {
  @Override 
  public Dimension getPreferredSize(JComponent c) {
    Dimension d = super.getPreferredSize(c);
    int v = Math.max(d.width, d.height);
    d.setSize(v, v);
    return d;
  }
  @Override public void paint(Graphics g, JComponent c) {
    Insets b = progressBar.getInsets(); // area for border
    int barRectWidth  = progressBar.getWidth()  - b.right - b.left;
    int barRectHeight = progressBar.getHeight() - b.top - b.bottom;
    if (barRectWidth <= 0 || barRectHeight <= 0) {
      return;
    }

    // draw the cells
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setPaint(progressBar.getForeground());
    double degree = 360 * progressBar.getPercentComplete();
    double sz = Math.min(barRectWidth, barRectHeight);
    double cx = b.left + barRectWidth  * .5;
    double cy = b.top  + barRectHeight * .5;
    double or = sz * .5;
    double ir = or * .5; //or - 20;
    Shape inner = new Ellipse2D.Double(cx - ir, cy - ir, ir * 2, ir * 2);
    Shape outer = new Arc2D.Double(
        cx - or, cy - or, sz, sz, 90 - degree, degree, Arc2D.PIE);
    Area area = new Area(outer);
    area.subtract(new Area(inner));
    g2.fill(area);
    g2.dispose();

    // Deal with possible text painting
    if (progressBar.isStringPainted()) {
      paintString(g, b.left, b.top, barRectWidth, barRectHeight, 0, b);
    }
  }
}

源代码diatassaya从网站获取然后我修改了一下。我给出了循环并且结果是成功的,但是当数据检索不止一次时,循环进度周期变得非常快并且总是为下一次数据检索增加得更快。我尝试使用setIntermedinate (true),但似乎ProgressBar不是循环。请帮忙。

1 个答案:

答案 0 :(得分:0)

  

但是当数据检索不止一次时,循环进度周期变得非常快并且下次数据检索总是增加得更快

你没有停止计时器,事实上,你似乎正在使用第二个Timer隐藏进度条......出于某种原因。

这意味着,每次要使用进度指示器时,都会创建另一个Timer,这会创建一堆竞争Timer,这些都会改变状态并相互干扰。

更好更简单的解决方案是创建单个Timer并根据需要停止/启动它,例如

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.plaf.basic.BasicProgressBarUI;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JProgressBar jpbCircularProg;
        private Timer timer;

        public TestPane() {
            timer = new Timer(10, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int iv = Math.min(100, jpbCircularProg.getValue() + 1);
                    jpbCircularProg.setValue(iv);
                    if (jpbCircularProg.getValue() == 100) {
                        jpbCircularProg.setValue(1);
                    }
                }
            });
            jpbCircularProg = new JProgressBar();
            jpbCircularProg.setUI(new ProgressCircleUI());
            jpbCircularProg.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
            //Border emptyBorder = BorderFactory.createEmptyBorder();
            //jpbCircularProg.setBorder(emptyBorder);
            jpbCircularProg.setStringPainted(true);
            jpbCircularProg.setFont(jpbCircularProg.getFont().deriveFont(24f));
            jpbCircularProg.setForeground(Color.ORANGE);
            if (jpbCircularProg.isVisible() == false) {
                jpbCircularProg.setVisible(true);
            }

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = GridBagConstraints.REMAINDER;
            add(jpbCircularProg, gbc);

            JButton toggle = new JButton("Toggle");
            toggle.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (timer.isRunning()) {
                        timer.stop();
                    } else {
                        timer.restart();
                    }
                }
            });

            add(toggle, gbc);
        }

    }

    public class ProgressCircleUI extends BasicProgressBarUI {

        @Override
        public Dimension getPreferredSize(JComponent c) {
            Dimension d = super.getPreferredSize(c);
            int v = Math.max(d.width, d.height);
            d.setSize(v, v);
            return d;
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            Insets b = progressBar.getInsets(); // area for border
            int barRectWidth = progressBar.getWidth() - b.right - b.left;
            int barRectHeight = progressBar.getHeight() - b.top - b.bottom;
            if (barRectWidth <= 0 || barRectHeight <= 0) {
                return;
            }

            // draw the cells
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(progressBar.getForeground());
            double degree = 360 * progressBar.getPercentComplete();
            double sz = Math.min(barRectWidth, barRectHeight);
            double cx = b.left + barRectWidth * .5;
            double cy = b.top + barRectHeight * .5;
            double or = sz * .5;
            double ir = or * .5; //or - 20;
            Shape inner = new Ellipse2D.Double(cx - ir, cy - ir, ir * 2, ir * 2);
            Shape outer = new Arc2D.Double(
                    cx - or, cy - or, sz, sz, 90 - degree, degree, Arc2D.PIE);
            Area area = new Area(outer);
            area.subtract(new Area(inner));
            g2.fill(area);
            g2.dispose();

            // Deal with possible text painting
            if (progressBar.isStringPainted()) {
                paintString(g, b.left, b.top, barRectWidth, barRectHeight, 0, b);
            }
        }
    }

}

由于您尝试将其显示为“中间”进度条,因此最好将动画功能包装到UI委托本身。

以下示例利用JProgressBar的“中间”状态自我动画进度,管理Timer状态本身

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.beans.PropertyChangeEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.plaf.basic.BasicProgressBarUI;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JProgressBar jpbCircularProg;

        public TestPane() {
            jpbCircularProg = new JProgressBar();
            jpbCircularProg.setUI(new ProgressCircleUI());
            jpbCircularProg.setIndeterminate(true);
            jpbCircularProg.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
            //Border emptyBorder = BorderFactory.createEmptyBorder();
            //jpbCircularProg.setBorder(emptyBorder);
            jpbCircularProg.setStringPainted(true);
            jpbCircularProg.setFont(jpbCircularProg.getFont().deriveFont(24f));
            jpbCircularProg.setForeground(Color.ORANGE);
            if (jpbCircularProg.isVisible() == false) {
                jpbCircularProg.setVisible(true);
            }

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = GridBagConstraints.REMAINDER;
            add(jpbCircularProg, gbc);

            JButton toggle = new JButton("Toggle");
            toggle.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    jpbCircularProg.setIndeterminate(!jpbCircularProg.isIndeterminate());
                }
            });

            add(toggle, gbc);
        }

    }

    public class ProgressCircleUI extends BasicProgressBarUI {

        private Timer timer;
        private Handler handler = new Handler();

        @Override
        public void installUI(JComponent c) {
            initTimer();
            super.installUI(c);
        }

        protected void initTimer() {
            if (timer == null) {
                timer = new Timer(10, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int iv = Math.min(100, progressBar.getValue() + 1);
                        progressBar.setValue(iv);
                        if (progressBar.getValue() == 100) {
                            progressBar.setValue(1);
                        }
                        progressBar.repaint();
                    }
                });
            }
        }

        @Override
        protected void startAnimationTimer() {
            timer.restart();
        }

        @Override
        protected void stopAnimationTimer() {
            timer.stop();
        }

        private void initIndeterminateValues() {
            initTimer();
            // we only bother installing the HierarchyChangeListener if we
            // are indeterminate
            progressBar.addHierarchyListener(handler);

            // start the animation thread if necessary
            if (progressBar.isDisplayable()) {
                startAnimationTimer();
            }
        }

        /**
         * Invoked by PropertyChangeHandler.
         */
        private void cleanUpIndeterminateValues() {
            // stop the animation thread if necessary
            if (progressBar.isDisplayable()) {
                stopAnimationTimer();
            }

            progressBar.setValue(0);

            progressBar.removeHierarchyListener(handler);
        }

        public void propertyChange(PropertyChangeEvent e) {
            String prop = e.getPropertyName();
            if ("indeterminate" == prop) {
                if (progressBar.isIndeterminate()) {
                    initIndeterminateValues();
                } else {
                    //clean up
                    cleanUpIndeterminateValues();
                }
                progressBar.repaint();
            }
        }

        @Override
        public Dimension getPreferredSize(JComponent c) {
            Dimension d = super.getPreferredSize(c);
            int v = Math.max(d.width, d.height);
            d.setSize(v, v);
            return d;
        }

        @Override
        public void paint(Graphics g, JComponent c) {
            Insets b = progressBar.getInsets(); // area for border
            int barRectWidth = progressBar.getWidth() - b.right - b.left;
            int barRectHeight = progressBar.getHeight() - b.top - b.bottom;
            if (barRectWidth <= 0 || barRectHeight <= 0) {
                return;
            }

            // draw the cells
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(progressBar.getForeground());
            double degree = 360 * progressBar.getPercentComplete();
            double sz = Math.min(barRectWidth, barRectHeight);
            double cx = b.left + barRectWidth * .5;
            double cy = b.top + barRectHeight * .5;
            double or = sz * .5;
            double ir = or * .5; //or - 20;
            Shape inner = new Ellipse2D.Double(cx - ir, cy - ir, ir * 2, ir * 2);
            Shape outer = new Arc2D.Double(
                    cx - or, cy - or, sz, sz, 90 - degree, degree, Arc2D.PIE);
            Area area = new Area(outer);
            area.subtract(new Area(inner));
            g2.fill(area);
            g2.dispose();

            // Deal with possible text painting
            if (progressBar.isStringPainted() && !progressBar.isIndeterminate()) {
                paintString(g, b.left, b.top, barRectWidth, barRectHeight, 0, b);
            }
        }

        protected class Handler implements HierarchyListener {

            public void hierarchyChanged(HierarchyEvent he) {
                if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
                    if (progressBar.isIndeterminate()) {
                        if (progressBar.isDisplayable()) {
                            startAnimationTimer();
                        } else {
                            stopAnimationTimer();
                        }
                    }
                }
            }
        }
    }

}