Java 如何创建一个';s值可以从调用类更新

Java 如何创建一个';s值可以从调用类更新,java,swing,swingworker,jprogressbar,event-dispatch-thread,Java,Swing,Swingworker,Jprogressbar,Event Dispatch Thread,我试过跟随教程,但我总是在某个地方迷路 我需要的是一个类,它创建并显示一个进度条(JProgressBar),我可以在迭代从文件加载的数据并将其放入数据库内存时设置进度条的值。我的问题是,我发现的每个示例都有某种计数器,它填充进度条并从“main”函数执行。每次我将该教程更改为一个类,可以随意调用并显示该条,我都不会看到该条显示(即框架出现,但直到迭代完成后,该条才看起来像是添加到了框架中) 我尝试过使用SwingUtilities.invokeLater和SwingWorker(下面的类的最新

我试过跟随教程,但我总是在某个地方迷路

我需要的是一个类,它创建并显示一个进度条(
JProgressBar
),我可以在迭代从文件加载的数据并将其放入数据库内存时设置进度条的值。我的问题是,我发现的每个示例都有某种计数器,它填充进度条并从“main”函数执行。每次我将该教程更改为一个类,可以随意调用并显示该条,我都不会看到该条显示(即框架出现,但直到迭代完成后,该条才看起来像是添加到了框架中)

我尝试过使用
SwingUtilities.invokeLater
SwingWorker
(下面的类的最新尝试)都有相同的问题。更糟糕的是,我可以做一个
dbug.myMessage
(基本上发送到
System.out
),然后看到一条消息,显示内存中的条正在更改,只是没有显示。我显然错过了一些简单的东西,但我想不出是什么

还有一件事,如果我保持教程的原样,只是将main更改为createAndShow方法,它可以工作,但当然它没有完成我需要它做的事情

我确实发布了关于这个问题的另一个问题,但由于课堂上的内容变化太大,我认为最好发布一个新问题

下面是我修改过的代码,它似乎不起作用:

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

}
公共类MyProgressBar扩展JPanel实现PropertyChangeListener,
我的数据,
可序列化{
/**
* 
*/
私有静态最终长SerialVersionId=-1632492668549544408L;
私有MyDebug dbug=newmydebug(MyData.MYDEBUGCHECK.MYPROGRESSBAR.getOn());
公共静态最终整数最大值=100;
公共静态最终整数宽度=400;
公共静态最终内部高度=75;
private JProgressBar myBar=新的JProgressBar(SwingConstants.HORIZONTAL,0,MAX);
私有JFrame myFrame=newjframe();
公共任务;
类任务扩展SwingWorker{
公共int myValue=0;
@凌驾
公共无效doInBackground(){
//初始化进度属性。
setProgress(0);
而(myValue<100){
//随机取得进展。
//myValue+=random.nextInt(10);
setProgress(Math.min(myValue,100));
myMessage(“MYPROGRESSBAR”、“doInBackground”、“值为%3.2f%d”、myBar.getPercentComplete()、myValue);
myBar.repaint();
}
返回null;
}
公众假期结束(){
}
public void mySetValue(整数百分比){
myValue=(int)(最大*((双)百分比/100.0));
dbug.myMessage(“MYPROGRESSBAR”、“mySetValue”、“值为%3.2f%d百分比为%d”、myBar.getPercentComplete()、myValue、百分比);
}
}
公共MyProgressBar(){
添加(myBar);
intx=(MyData.SCREEN.width/2)-(width/2);
int y=(MyData.SCREEN.height/2)-(height/2);
此.立根(x,y,宽度,高度);
myFrame.setBounds(x,y,宽度,高度);
myFrame.setUndecorated(真);
myFrame.getContentPane().setSize(新尺寸(宽度、高度));
myFrame.setMinimumSize(新尺寸(宽度、高度));
myFrame.setPreferredSize(新尺寸(宽度、高度));
myFrame.setSize(新尺寸(宽度、高度));
myFrame.setVisible(false);
myFrame.getContentPane().setLayout(null);
myFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
myBar.setstringpaint(真);
myBar.com(真);
myBar.setValue(0);
myBar.setBounds(0,0,宽度,高度);
myBar.addPropertyChangeListener(此);
myFrame.add(myBar);
//创建并设置内容窗格。
//JComponent newContentPane=新的MyProgressBar();
JComponent newContentPane=myBar;
newContentPane.setOkable(true);//内容窗格必须是不透明的
myFrame.setContentPane(newContentPane);
myFrame.pack();
}
public void createAndShow(){
//显示窗口。
myFrame.setVisible(true);
myFrame.repaint();
}
公共无效隐藏清除(){
//myFrame.setVisible(false);
}
@凌驾
公共作废propertyChange(PropertyChangeEvent参数){
myMessage(“MYPROGRESSBAR”、“propertyChange”、“值为%s”、args.getPropertyName());
如果(“进度”==args.getPropertyName()){
int progress=(整数)args.getNewValue();
//myBar.setValue(进度);
}
}
公共无效开始(){
//javax.swing.SwingWorker的实例不可重用,因此
//我们根据需要创建新实例。
任务=新任务();
task.addPropertyChangeListener(此);
task.execute();
}
}

不要在
doInBackGround
方法中调用
setProgress
,而应该调用
SwingWorker
中可用的
publish
方法

publish
方法将把这些值传递给在事件调度线程上调用的
process
方法,在此方法中,您应该更新进度条


在本文中,我已经发布了一个这样做的示例

而不是在
doInBackGround
方法中调用
setProgress
,您应该调用
SwingWorker
中可用的
publish
方法

publish
方法将这些值传递给
package com.swa.fin.esaa.sgb.myclasses.myzzarchives;

import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;

public class MyProgressBarTest {

    public class MyProgressBar extends JPanel implements PropertyChangeListener, 
                                                         Serializable {

        private static final long serialVersionUID = -1632492668549544408L;

        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, Integer> {

            public int myValue = 0;

            @Override
            public Void doInBackground() {
                //Initialize progress property.
                setProgress(0);
                myBar.setValue( myValue );
                myBar.repaint();
                return null;
            }

            public void done() {
            }

            public void mySetValue( int percent ) {
                myValue = (int)( MAX * ( (double)percent / 100.0 ) );
                setProgress( Math.min( myValue, 100 ) );
                myBar.repaint();
            }

        }

        public MyProgressBar() {
            add(myBar);

            myFrame.setUndecorated(false);
            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) {
            if ( "progress" == args.getPropertyName() ) {
                int progress = (Integer) args.getNewValue();
                myBar.setValue(progress);
            }
        }

        public void mySetValue( int percent ) {
            if ( task != null ) {
                task.mySetValue( percent );
            }
            myBar.repaint();
        }

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




    public class Tester {

        public Tester() {
        }
        public void testit () {
            MyProgressBar bar = new MyProgressBar();
            bar.createAndShow();
            bar.start();
            bar.mySetValue(  0 );
            try { Thread.sleep( 100 );  } catch (InterruptedException e) { e.printStackTrace(); } 
            bar.mySetValue(  10 );
            try { Thread.sleep( 100 );  } catch (InterruptedException e) { e.printStackTrace(); } 
            bar.mySetValue(  20 );
            try { Thread.sleep( 100 );  } catch (InterruptedException e) { e.printStackTrace(); }
            for ( int count = 20; count <= 100; count++ ) {
                bar.mySetValue(  count );
                try { Thread.sleep( 100 );  } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }


    public static void main ( String[] args ) {
        MyProgressBarTest my = new MyProgressBarTest();
        MyProgressBarTest.Tester test = my.new Tester();

        test.testit();

    }


}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class WorkerExample
{

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                WorkerGui gui = new WorkerGui();
                JFrame frame = gui.createFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}



class WorkerGui
{
    public static final String ADD_NEW_ROW_PROPERTY = "ADD_NEW_ROW";
    private static final Dimension SUB_PANEL_SIZE = new Dimension(350, 50);
    private JButton button;
    private JComponent labelComponent;
    private JScrollPane scroller;
    int labelCount = 0;

    private List<String> loadXml() {
        try {
            // pretend to load a large XML file...
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException ex) {
            Logger.getLogger(WorkerGui.class.getName()).log(Level.SEVERE, null, ex);
        }

        List<String> dataList = new ArrayList<String>();

        for (int i = 1; i <= 20; i++) {
            dataList.add("Important data " + i);
        }

        return dataList;
    }

    ProgressMonitor monitor = null;


    class XmlWorker extends SwingWorker<Void, Void> {

        @Override protected Void doInBackground() throws Exception {
            monitor.setProgress(2);
            List<String> rows = loadXml();

            final int denom = rows.size();

            int i = 1;
            Random random = new Random();
            for (String string : rows) {
                if (monitor.isCanceled()) {
                    break;
                }
                Thread.sleep(random.nextInt(2000));
                firePropertyChange(ADD_NEW_ROW_PROPERTY, null, string);
                setProgress((int)(100 * (i / (double)denom)));
                i++;
            }
            return null;
        }

        @Override protected void done() {
            // restore the button
            button.setEnabled(true);
            button.requestFocus();
        }
    }


    final PropertyChangeListener listener = new PropertyChangeListener() {
        @Override public void propertyChange(PropertyChangeEvent evt) {
            if ("progress".equals(evt.getPropertyName())) {
                monitor.setProgress((Integer)evt.getNewValue());
            } else if (ADD_NEW_ROW_PROPERTY.equals(evt.getPropertyName())) {
                addRow((String)evt.getNewValue());
            }
        }
    };

    private void doWork() {
        monitor = new ProgressMonitor(labelComponent.getTopLevelAncestor(), "Loading XML", "", 0, 100);
        monitor.setProgress(0);
        monitor.setMillisToPopup(0);
        monitor.setMillisToDecideToPopup(0);
        XmlWorker worker = new XmlWorker();
        worker.addPropertyChangeListener(listener);
        worker.execute();
    }

    private JComponent setupGui() {
        labelComponent = Box.createVerticalBox();
        scroller = new JScrollPane(labelComponent,
                                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        JPanel buttonPanel = new JPanel();
        button = new JButton("Do it!");
        buttonPanel.add(button);
        button.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                button.setEnabled(false);
                clear();
                doWork();
            }
        });

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.add(scroller, BorderLayout.CENTER);
        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
        return mainPanel;
    }

    public JFrame createFrame() {
        JFrame frame = new JFrame("Hello!");
        frame.setSize(400, 400);
        JComponent component = setupGui();
        frame.add(component);
        return frame;
    }

    public void clear() {
        labelComponent.removeAll();
        labelCount = 0;
        scroller.validate();
        scroller.getTopLevelAncestor().repaint();
    }

    /**
     * Creates a JLabel out of the data and adds it to the main panel.
     * Must be called on Event Dispatch Thread!!
     * @param data  the data to add, could be any class.
     */
    public void addRow(String data) {
        if (labelCount > 0) {
            labelComponent.add(Box.createVerticalStrut(10));
        }
        labelCount++;

        final JLabel label = new JLabel(data);
        JPanel panel = new JPanel();
        panel.add(label);

        panel.setPreferredSize(SUB_PANEL_SIZE);
        panel.setMaximumSize(SUB_PANEL_SIZE);
        panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));

        labelComponent.add(panel);
        scroller.validate();
        panel.scrollRectToVisible(panel.getBounds());
    }
}