我有一个检索数据的程序,其中每个检索都无法确定其完成时间。我的想法是在捕获完成时进行不断重复和标记的进度。
我目前的源代码,来自主类的方法:
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不是循环。请帮忙。
答案 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();
}
}
}
}
}
}
}