好的,我有以下代码。
public class MyProgressBar extends JPanel implements MyData, Serializable {
/**
*
*/
public static final int MAX = 10000;
public static final int WIDTH = 400;
public static final int HEIGHT = 75;
private JProgressBar MyBar = new JProgressBar( SwingConstants.HORIZONTAL, 0, MAX );
private JFrame MyFrame = new JFrame();
private int MyValue = 0;
private Thread MyThread = new Thread( new ProgressThread() );
public MyProgressBar() {
add(MyBar);
int x = ( MyData.SCREEN.width / 2 ) - ( WIDTH / 2);
int y = ( MyData.SCREEN.height / 2 ) - ( HEIGHT / 2);
this.setBounds( x, y, WIDTH, HEIGHT );
MyFrame.setBounds( x, y, WIDTH, HEIGHT );
MyFrame.setUndecorated(true);
MyFrame.getContentPane().setSize( new Dimension( WIDTH, HEIGHT ) );
MyFrame.setMinimumSize( new Dimension( WIDTH, HEIGHT ) );
MyFrame.setPreferredSize( new Dimension( WIDTH, HEIGHT ) );
MyFrame.setSize( new Dimension( WIDTH, HEIGHT ) );
MyFrame.setVisible(false);
MyFrame.getContentPane().setLayout(null);
MyBar.setStringPainted( true );
MyBar.setBorderPainted( true );
MyBar.setValue( 0 );
MyBar.setBounds( 0, 0, WIDTH, HEIGHT );
MyFrame.add( MyBar );
MyFrame.pack();
MyFrame.repaint();
}
public void MyUpdateBar() {
MyBar.setValue( MyValue );
MyBar.repaint();
MyFrame.repaint();
this.repaint();
//dbug.Message( "MYPROGRESSBAR", "MyUpdateBar", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue );
}
public void MySetValue( int percent ) {
MyValue = (int)( MAX * ( (double)percent / 100.0 ) );
MyUpdateBar();
//dbug.Message( "MYPROGRESSBAR", "MySetValue", "Value is %3.2f %d percent was %d", MyBar.getPercentComplete(), MyValue, percent );
}
public void CreateAndShow () {
MyFrame.setVisible(true);
MyThread.start();
}
public void HideAndClear () {
MyThread.stop();
//frame.setVisible(false);
}
class ProgressThread implements Runnable {
public void run() {
EventQueue.invokeLater(new Runnable() {
public void run() {
while( MyValue < MyBar.getMaximum() ) {
MyBar.setValue( MyValue );
MyBar.repaint();
MyFrame.repaint();
dbug.Message( "MYPROGRESSBAR", "THREAD", "Value is %3.2f %d", MyBar.getPercentComplete(), MyValue );
}
}
});
}
}
}
正如您所看到的,我创建了一个我希望显示进度的类。发生的事情是我实例化该类。加载我的XML文件,然后当我解析数据时,我正在调用更新MyValue,当我让我的dbug消息出来时,我会看到它。然而,酒吧本身甚至在100%完成之前都不显示。我已经阅读了关于线程和跟随别人的例子的内容,如果我把它作为他的例子就可以了。如果我做了一些调整(更改线程中的循环以填充进度条的setvalue以读取值),它甚至不会显示,直到它为100。
我做错了什么?
谢谢!
答案 0 :(得分:14)
您的线程执行SwingUtilities.invokeLater
。你实际上在Swing的Event Dispatch Thread
上运行。不确定你想要达到什么目的。但看起来您阻止EDT
并且while
循环未更新,因为MySetValue
未执行。
考虑使用SwingWorker
进行冗长的操作。 How to Use Progress Bars演示了SwingWorker
与JProgressBar
的使用情况。
确保从setValue
调用Event Dispatch Thread
方法。您可以使用SwingUtilities.invokeLater
。详细了解Threads and Swing。
考虑这个简化的样本:
public static void main(String[] arguments) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
final JProgressBar bar = new JProgressBar(0, 100);
Thread t = new Thread(){
public void run(){
for(int i = 0 ; i < 100 ; i++){
final int percent = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(percent);
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
};
frame.add(bar);
frame.pack();
frame.setVisible(true);
t.start();
}
答案 1 :(得分:5)
问题是您在EDT中使用了一个更新进度的循环。在该循环退出之前,EDT无法调度事件(如重绘,重新验证,invokeLater,鼠标事件,键事件等等),从而无法刷新进度条。
您应该尝试找到让EDT在每次更新进度条之间调度事件的方法。理想情况下,您使用SwingWorker在EDT之外移动“工作”,同时通过EDT中的属性更改侦听器更新进度条。
为了您的信息,在Java中,方法和变量以小写字母开头。你的代码真的很难为别人阅读。
答案 2 :(得分:1)
所以,我试着按照教程进行操作,这就是我所处的位置。
好的,我已经尝试过以下教程,但我一直迷路。我需要的是一个创建和显示进度条(JProgressBar)的类,我可以设置值,因为我迭代从文件加载的数据并放入数据库内存。我遇到的问题是,我发现的每个例子都有某种计数器,它填充进度条并从“主”函数执行。每当我改变该教程成为一个我可以随意调用并显示条形的类时,我都没有显示条形图(即框架出现但是条形图甚至看起来都没有被添加到框架中,直到之后迭代完成)。我尝试过使用SwingUtilities.invokeLater和SwingWorker(下面的课程中的最新尝试)都有同样的问题。更糟糕的是,我可以做一个dbug.myMessage(基本上发送到System.out)并看到一条消息,显示该条正在更改内存中没有显示。我显然遗漏了一些可能很简单的东西,但我想不出它是什么。
哦,另外一件事,如果我按原样离开教程(http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/ProgressBarDemo2Project/src/components/ProgressBarDemo2.java)并将main更改为createAndShow方法,它可以正常工作,但当然它不会做我需要做的事情。< / p>
我确实发布了另一个关于此的问题,但我已经改变了这个课程,我认为最好发一个新问题。
所以,这是我改变的代码似乎不起作用:
public class MyProgressBar extends JPanel implements PropertyChangeListener,
MyData,
Serializable {
/**
*
*/
private static final long serialVersionUID = -1632492668549544408L;
private MyDebug dbug = new MyDebug( MyData.MYDEBUGCHECK.MYPROGRESSBAR.getOn() );
public static final int MAX = 100;
public static final int WIDTH = 400;
public static final int HEIGHT = 75;
private JProgressBar myBar = new JProgressBar( SwingConstants.HORIZONTAL, 0, MAX );
private JFrame myFrame = new JFrame();
public Task task;
class Task extends SwingWorker<Void, Void> {
public int myValue = 0;
@Override
public Void doInBackground() {
//Initialize progress property.
setProgress(0);
while (myValue < 100) {
//Make random progress.
//myValue += random.nextInt(10);
setProgress( Math.min( myValue, 100 ) );
dbug.myMessage( "MYPROGRESSBAR", "doInBackground", "Value is %3.2f %d", myBar.getPercentComplete(), myValue );
myBar.repaint();
}
return null;
}
public void done() {
}
public void mySetValue( int percent ) {
myValue = (int)( MAX * ( (double)percent / 100.0 ) );
dbug.myMessage( "MYPROGRESSBAR", "mySetValue", "Value is %3.2f %d percent was %d", myBar.getPercentComplete(), myValue, percent );
}
}
public MyProgressBar() {
add(myBar);
int x = ( MyData.SCREEN.width / 2 ) - ( WIDTH / 2);
int y = ( MyData.SCREEN.height / 2 ) - ( HEIGHT / 2);
this.setBounds( x, y, WIDTH, HEIGHT );
myFrame.setBounds( x, y, WIDTH, HEIGHT );
myFrame.setUndecorated(true);
myFrame.getContentPane().setSize( new Dimension( WIDTH, HEIGHT ) );
myFrame.setMinimumSize( new Dimension( WIDTH, HEIGHT ) );
myFrame.setPreferredSize( new Dimension( WIDTH, HEIGHT ) );
myFrame.setSize( new Dimension( WIDTH, HEIGHT ) );
myFrame.setVisible(false);
myFrame.getContentPane().setLayout(null);
myFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
myBar.setStringPainted( true );
myBar.setBorderPainted( true );
myBar.setValue( 0 );
myBar.setBounds( 0, 0, WIDTH, HEIGHT );
myBar.addPropertyChangeListener( this );
myFrame.add( myBar );
//Create and set up the content pane.
//JComponent newContentPane = new MyProgressBar();
JComponent newContentPane = myBar;
newContentPane.setOpaque(true); //content panes must be opaque
myFrame.setContentPane(newContentPane);
myFrame.pack();
}
public void createAndShow () {
//Display the window.
myFrame.setVisible(true);
myFrame.repaint();
}
public void hideAndClear () {
//myFrame.setVisible(false);
}
@Override
public void propertyChange(PropertyChangeEvent args) {
dbug.myMessage( "MYPROGRESSBAR", "propertyChange", "Value is %s", args.getPropertyName() );
if ( "progress" == args.getPropertyName() ) {
int progress = (Integer) args.getNewValue();
//myBar.setValue(progress);
}
}
public void start () {
//Instances of javax.swing.SwingWorker are not reusuable, so
//we create new instances as needed.
task = new Task();
task.addPropertyChangeListener(this);
task.execute();
}
}
答案 3 :(得分:1)
通过以下代码实现进度条的动态进度更新:
int progress = Math.round(((float)finished/(float)(total)) * 100);
uploadPrgressBar.setIndeterminate(progress == 0);
uploadPrgressBar.setValue(progress);
uploadPrgressBar.update(uploadPrgressBar.getGraphics());
在循环中调用包含上述代码的方法(代码逻辑),它将在每次迭代后动态更新进度条
答案 4 :(得分:0)
以下代码段会在进行中时更新进度条
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setValue((int)percentage);
//below code to update progress bar while running on thread
progressBar.update(progressBar.getGraphics());}
});