使用Update(Graphic)时,Jlabel文本乘法和重叠



我已经编写了此代码来更新我的进度栏进度消息。基本上,当我有长度的过程以()循环运行时,我将其扔到循环中,并使用prog = i and max =一个数组最大

进行更新
for(int i = 1; i <= array.length-1; i++){
//Process
setPrg(this.lbl, ths.prg, i, array.length-1, "Doing so process");
}

-

public void setPrg(JLabel lbl, JProgressBar prg, int prog, int max, String msg) {
    prg.setMaximum(max);
    if (prog <= max) {
        prg.setValue(prog);
    }
    prg.update(prg.getGraphics());
    if (prog >= max) {
        setMessage(lbl, "");
    } else {
        setMessage(lbl, msg);
    }
}
    public void setMessage(JLabel lbl, String msg) {
        lbl.setText(msg);
        lbl.update(lbl.getGraphics());
    }

我使用()循环多次连续进行此操作,每个循环都有描述该过程的唯一消息。

问题是,由于某种原因,标签文本与自身重叠。例如,如果我有一个运行此代码的循环:

setPrg(this.lbl, ths.prg, i, array.length-1, "This is process 1");

和运行此代码的一个:

setPrg(this.lbl, ths.prg, i, array.length-1, "The second process this is");

然后,一旦第二个过程开始,两条消息的文本就会重叠,而不是"这是过程1"消失。

另一方面,如果我不包含此行:

lbl.update(lbl.getGraphics());

在循环期间根本不会出现文本,只有在循环后出现的最后一个标签的文本。

帮助非常感谢!

这是完整程序:

package test;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
public class Main extends javax.swing.JFrame {
    public Main() {
        initComponents();
    }
 public void setPrg(JLabel lbl, JProgressBar prg, int prog, int max, String msg) {
        prg.setMaximum(max);
        if (prog <= max) {
            prg.setValue(prog);
        }
        prg.update(prg.getGraphics());
        if (prog >= max) {
            setMessage(lbl, "");
        } else {
            setMessage(lbl, msg);
        }
    }
    public void setMessage(JLabel lbl, String msg) {
        lbl.setText(msg);
        lbl.update(lbl.getGraphics());
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        jButton1 = new javax.swing.JButton();
        jProgressBar1 = new javax.swing.JProgressBar();
        jLabel1 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jButton1.setText("Button");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jLabel1.setText("jLabel1");
        jTextField1.setText("jTextField1");
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(246, 246, 246)
                        .addComponent(jLabel1))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(226, 226, 226)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButton1)))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 540, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(108, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addGap(22, 22, 22)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(40, 40, 40))
        );
        pack();
    }// </editor-fold>                        
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        for (int i = 1; i <= 10000; i++) {
            this.setPrg(jLabel1, jProgressBar1, i, 10000, "Message 1");
        }
                for (int i = 1; i <= 10000; i++) {
            this.setPrg(jLabel1, jProgressBar1, i, 10000, "Second Message");
        }
    }                                        
    public static void main(String args[]) {
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    public javax.swing.JButton jButton1;
    public javax.swing.JLabel jLabel1;
    public javax.swing.JProgressBar jProgressBar1;
    public javax.swing.JTextField jTextField1;
    // End of variables declaration                   
}

使用秋千时,您会在多螺纹环境中自动。一个是主线程,秋千使用EDT进行UI重新粉刷。

使用 swingutilities.invokelater()在EventDisPatchThread上执行 jprogressbar.setValue() jlabel.setValue()这样可以确保它们将被相应更新。

如何使用 swingutilities

的示例片段
    final JProgressBar prg = new JProgressBar();
    final JLabel lbl = new JLabel();
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            prg.setValue(70);
            lbl.setText("Text");
        }
    });

您会看到,您不再需要打电话给 lbl.update(lbl.getGraphics());

您的问题是在秋千事件线程上运行长期运行的代码的经典问题,并且可以进行无效的秋千图形调用。解决方案是在背景线程中执行长期运行的代码,例如Swingworker的Doinbackground方法,并注意在秋千事件线程上进行所有摇摆电话。

所有这些都很好地解释了易于找到的教程,包括

  • 课程:秋千的并发:如何使用摇摆工
  • jprogressbar教程

例如,编译并运行此:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
@SuppressWarnings("serial")
public class Main4b extends JPanel {
    private static final int MAX = 10000;
    private static final int PREF_W = 400;
    private static final int PREF_H = 200;
    private ButtonAction buttonAction = new ButtonAction();
    private JButton button = new JButton(buttonAction);
    private JTextField jTextField1 = new JTextField("jTextField1", 10);
    private JLabel jLabel1 = new JLabel("jLabel1");
    private JProgressBar jProgressBar1 = new JProgressBar(0, MAX);
    public Main4b() {
        jProgressBar1.setStringPainted(true);
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(new JPanel() {{add(button);}});
        add(new JPanel() {{add(jTextField1);}});
        add(new JPanel() {{add(jLabel1);}});
        add(jProgressBar1);
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    }
    @Override
    public Dimension getPreferredSize() {
        Dimension superSz = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return superSz;
        }
        int prefW = Math.max(superSz.width, PREF_W);
        int prefH = Math.max(superSz.height, PREF_H);
        return new Dimension(prefW, prefH);
    }
    private class ButtonAction extends AbstractAction {
        public ButtonAction() {
            super("Button");
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            setEnabled(false); // make the button non-pressable
            // create background thread worker
            MyWorker myWorker = new MyWorker();
            // add propertychange listener to it
            myWorker.addPropertyChangeListener(new WorkerListener());
            // run the worker thread
            myWorker.execute();
        }
    }
    // background thread
    private static class MyWorker extends SwingWorker<Void, Integer> {
        private static final String MY_PROGRESS = "my progress";
        private int myProgress = 0;
        @Override
        protected Void doInBackground() throws Exception {
            // all this code is run in a background thread
            // do this twice
            for (int j = 0; j < 2; j++) {
                // iterate from 0 to 10,000
                for (int i = 0; i < MAX; i++) {
                    Thread.sleep(1); // small delay so we can see what we're doing
                    setMyProgress(i + j * MAX); // send output to listeners
                }
            }
            return null;
        }
        public int getMyProgress() {
            return myProgress;
        }
        // myProgress is a "bound" field, one that will notify listeners
        // if it is changed
        public void setMyProgress(int myProgress) {
            int oldValue = this.myProgress;
            int newValue = myProgress;
            this.myProgress = myProgress;
            // notify all listeners
            firePropertyChange(MY_PROGRESS, oldValue, newValue);
        }
    }
    private class WorkerListener implements PropertyChangeListener {
        private String message = "Message %d: %05d";
        public WorkerListener() {
            jLabel1.setText(String.format(message, 1, 0));
        }
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            // all this code is run on the Swing event thread
            // listen for changes to my progress bound field
            if (MyWorker.MY_PROGRESS.equals(evt.getPropertyName())) {
                int value = (int) evt.getNewValue(); // get value
                int newMsgIndex = 1 + value / MAX; // message number 
                jProgressBar1.setValue(value % MAX); // set value on progress bar
                jLabel1.setText(String.format(message, newMsgIndex, value % MAX));
            } else if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
                // worker is done
                jLabel1.setText(""); // reset JLabel
                buttonAction.setEnabled(true);  // re-enable JButton's Action
                MyWorker myWorker = (MyWorker) evt.getSource();
                try {
                    // always call this to catch and handle any exceptions that 
                    // may have been thrown from within the worker
                    myWorker.get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    private static void createAndShowGui() {
        Main4b mainPanel = new Main4b();
        JFrame frame = new JFrame("Main");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

最新更新