简体   繁体   English

Java应用程序中的进度条和线程错误

[英]Progress bar and Thread error in java application

I have an application for converting video to audio, it converts file correctly but it has two errors, first error is that: when once it completes converting file and i browse new file so it gives an error in thread like this : 我有一个用于将视频转换为音频的应用程序,它可以正确地转换文件,但是有两个错误,第一个错误是:一旦完成转换文件,并且我浏览了新文件,因此在这样的线程中出现错误:

Exception in thread "AWT-EventQueue-0"java.lang.IllegalThreadStateException at java.lang.Thread.start(Unknown Source) 线程“ AWT-EventQueue-0”中的异常java.lang.Thread.start上的java.lang.IllegalThreadStateException(未知源)

an other error is that: progress bar is not working correctly this is code: 另一个错误是:进度栏无法正常工作,这是代码:

import it.sauronsoftware.jave.*;
import javax.swing.*; 
import javax.swing.filechooser.*;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;


public class MultiThreadign {

static String x=null;
static File Audio;
public static void main(String[] aa) 
{

    final JFrame mainframe=new JFrame("Video To Mp3 Converter");
    mainframe.setResizable(true);

    final JPanel panel=new JPanel();
    panel.setLayout(null);
    panel.setBackground(Color.white);
    mainframe.add(panel);



     /* ********************** MAIN BODY  ************************* */



    JLabel browsefiles=new JLabel("Files"); 
    browsefiles.setBounds(300, 50, 100, 25);
    panel.add(browsefiles);

    JLabel progressl=new JLabel("Status");
    progressl.setBounds(600, 50, 100, 25);
    panel.add(progressl);

     // first task buttons start

    final JTextField field1=new JTextField (300);
    field1.setBounds(160, 80, 300, 25);
    panel.add(field1);

    final JProgressBar progress = new JProgressBar();
     progress.setBounds(475, 80, 280, 25);
     progress.setStringPainted(true);
     progress.setMinimum(0);
     progress.setMaximum(99);
     panel.add(progress);

    JButton browse=new JButton("Browse File");
    browse.setBounds(10, 80, 130, 25);
    panel.add(browse);

    browse.addActionListener(new ActionListener()                               
    {                   
        public void actionPerformed(ActionEvent arg0) 

        {   final JFileChooser chooser=new JFileChooser();
            FileNameExtensionFilter filter = new               FileNameExtensionFilter("*.mp4, *.avi,*.3gp, *2gp", new String[] {"mp4","avi","3gp"});
            chooser.setFileFilter(filter);

             if (chooser.showOpenDialog(mainframe) == JFileChooser.APPROVE_OPTION) 
             {
                 field1.setText(chooser.getSelectedFile().getName());
                 x=chooser.getSelectedFile().getAbsolutePath();
               }
        }   
    });                                                                     // browse files action ends here

    final Thread t1=new Thread (new Runnable()
    {
        public void run()
        {       mainframe.getContentPane().repaint();
                mainframe.getContentPane().validate();

            try
            {    

                File Video=new File(x);
                String z="Audio.mp3";
                 Audio=new File (z);

                AudioAttributes audio=new AudioAttributes();
                audio.setCodec("libmp3lame");           //mp3 format   "libmp3lame"

                int abc=128000;
                audio.setBitRate(abc);              
                audio.setChannels (new Integer(2));
                audio.setSamplingRate(new Integer(44100));

                EncodingAttributes attr=new EncodingAttributes();
                attr.setFormat("mp3");

                attr.setAudioAttributes(audio);
                Encoder encode=new Encoder();
                long totalLength = Audio.length();

                try 
                {   
                    encode.encode(Video, Audio, attr);

                    FileReader fr=new FileReader(Audio);
                       @SuppressWarnings("resource")
                        BufferedReader br=new BufferedReader(fr);

                       long readLength = 0;
                       String s="";
                       while ((s = br.readLine()) != null) {
                     readLength += s.length();     
                     progress.setValue((int) totalLength);

                     }  
                }

                catch (Exception e)
                {
                    System.out.print(e);
                }                   
                   JOptionPane.showMessageDialog(null, "first Completed");
                   Audio=null;
               }

            catch (Exception e)
            {
            System.out.print(e);    
            }

            //mainframe.repaint();
        }
    });
        // first task button ends



    final JButton start=new JButton("Start Converting");
    start.setBounds(180, 260, 250, 25);
    panel.add(start);


     start.addActionListener(new ActionListener()
     {
         public void actionPerformed(ActionEvent arg0) 
        {   

             if (x !=null)
                {
                    t1.start();
                    JOptionPane.showMessageDialog(null, "process one started.");
                    x=null; 
                }
        }}); 

    /* ********************* MAIN BODY ENDS HERE ************* */

    /* **************************** MENU BAR ACTIONS HERE ******************* */



    mainframe.setSize(800, 400);
    mainframe.setLocationRelativeTo(null);
    mainframe.setVisible(true); 
}
}

Firstly, your code is trying to use Swing components from threads other than the EDT. 首先,您的代码尝试使用EDT以外的线程中的Swing组件。 This will cause undefined behavior. 这将导致未定义的行为。 That's why you are getting that Exception. 这就是为什么您得到该异常的原因。

You should always create, modify, and access all of your Swing components on the AWT Event Dispatch Thread (EDT) . 您应该始终在AWT事件调度线程(EDT)上创建,修改和访问所有Swing组件。 Read about Concurrency in Swing . 阅读有关Swing中的并发

Here is a short example of calling code on the EDT: 这是在EDT上调用代码的简短示例:

//Submits this Runnable to the queue to be run by on the EDT.
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        JFrame frame = new JFrame("My Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //add stuff to frame

        frame.pack();
        frame.setVisible(true);
    }
});

Secondly, it would be better to use a SwingWorker for a JProgressBar . 其次,最好为JProgressBar使用SwingWorker Read How to Use Progress Bars . 阅读如何使用进度条 You could use a Thread if you really wanted to, but you would still have manage a way to update Swing components only on the EDT. 如果确实愿意,可以使用Thread ,但是您仍然可以设法仅在EDT上更新Swing组件。 That's what SwingWorker is made for: to make it easy to perform long running operations in manner that doesn't block the EDT, with the option of periodically updating Swing components, such as a JProgressBar , properly on the EDT. 这就是SwingWorker目的:通过使在EDT上适当地定期更新Swing组件(例如JProgressBar的选项,可以轻松地以不阻塞EDT的方式执行长时间运行的操作。

Thirdly, you should avoid setting absolute sizes and positions for components and use Layout Managers instead. 第三,应避免为组件设置绝对尺寸和位置,而应使用布局管理器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM