JFrame ведет себя странно

В моей программе я показываю изображения с песней в фоновом режиме. После того, как песня закончена, мне нужно закрыть кадр и JInternalFrame. Вот код:

package projectfinal;
import javax.swing.*;
import java.io.File;
import java.io.IOException;

/* MORE IMPORTS */
public class ImagePanel extends javax.swing.JFrame {

    public static class audio extends JApplet {

        private static final int EXTERNAL_BUFFER_SIZE = 128000;

        public void aaudio() {

            String strFilename = "E:/zehreelay.wav";
            File soundFile = new File(strFilename);


            AudioInputStream audioInputStream = null;
            try {
                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
            } catch (Exception e) {

                e.printStackTrace();
                System.exit(1);
            }


            AudioFormat audioFormat = audioInputStream.getFormat();

            SourceDataLine line = null;
            DataLine.Info info = new DataLine.Info(SourceDataLine.class,
                audioFormat);
            try {
                line = (SourceDataLine) AudioSystem.getLine(info);

                line.open(audioFormat);
            } catch (LineUnavailableException e) {
                e.printStackTrace();
                System.exit(1);
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
            line.start();
            int nBytesRead = 0;
            byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
            while (nBytesRead != -1) {
                try {
                    nBytesRead = audioInputStream.read(abData, 0, abData.length);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (nBytesRead >= 0) {
                    int nBytesWritten = line.write(abData, 0, nBytesRead);
                }

            }
            line.drain();

            line.close();

            jInternalFrame1.setVisible(false);
            /**
            * closing internal frame
            */
        }
    }

    /**
    * Creates new form NewJFrame
    */
    public ImagePanel() {

        initComponents();

    }

    @SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jInternalFrame1 = new javax.swing.JInternalFrame();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();

        javax.swing.GroupLayout jInternalFrame1Layout = new javax.swing.GroupLayout(jInternalFrame1.getContentPane());

        //////////more code////////////////////////////////////
        jInternalFrame1.getContentPane().setLayout(jInternalFrame1Layout);
        jInternalFrame1.addComponentListener(new java.awt.event.ComponentAdapter() {

            public void componentHidden(java.awt.event.ComponentEvent evt) {
                hiden(evt);
            }
        });
        /////adding a listner for component///
    }

    public static void main(String args[]) {


        start();

    }

    private void hiden(java.awt.event.ComponentEvent evt) {

        setVisible(false);
    }

    public static void start() {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ImagePanel().setVisible(true);
            }
        });
        audio obj = new audio();
        obj.aaudio();
    }
    private static javax.swing.JInternalFrame jInternalFrame1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
/////more variables...//////
}

Этот код хорош, но когда я попробовал без добавления слушателя компонента, то есть getRootPane().SetVisible(false) или jInternalFrame1.getContentPane().setVisible(false) или setVisible(false), ни один из них не работал, но сработало только после добавления скрытого слушателя компонента. Почему? Какие-то причины? Тогда почему JInternalFrame работал (JInternalFrame.setVisible(false))? Это как-то связано с rootPane()?


person joey rohan    schedule 16.12.2012    source источник
comment
Объекты Swing GUI должны создаваться и управляться только на поток отправки событий.   -  person trashgod    schedule 16.12.2012
comment
@trashgod, тогда почему это работает нормально, если мы просто обычно говорим setVisible (false)? Почему бы и нет в этом случае?   -  person joey rohan    schedule 16.12.2012
comment
Трешгод прав. Почему вы не можете обернуть вызов в SwingUtilities.invokeLater?   -  person StanislavL    schedule 16.12.2012
comment
@StanislavL Я не хочу использовать поток отправки AWT.   -  person joey rohan    schedule 16.12.2012
comment
Я привел два подхода здесь.   -  person trashgod    schedule 16.12.2012


Ответы (1)


Как описано в разделе Начальные темы. , "Исходный поток планирует задачу создания GUI, вызывая invokeLater или invokeAndWait." Вы пытаетесь воспроизводить звук и работать с графическим интерфейсом в одном и том же начальном потоке. Вместо этого запустите звук в начальном потоке и создайте графический интерфейс в EDT, как показано здесь, или запустите отдельный поток. для воспроизведения звука, как показано здесь.

Я не хочу использовать поток отправки AWT.

Правильно, вы не хотите использовать поток диспетчеризации событий AWT для воспроизведения звука, но вы должны использовать его для графического интерфейса.

Вопрос несколько без ответа. Воспроизведение звука легкое, поэтому должно обрабатываться одним EDT.

Я могу только предположить, что использование другого компонента изменило время достаточно, чтобы повлиять на результат на вашей платформе. Пока программа не будет правильно синхронизирована, всегда есть среда, в которой она будет работать, и среда, в которой она не работает. Основное правило таково: не блокируйте EDT. См. также этот ответ, этот answer и тег Java Sound.

person trashgod    schedule 16.12.2012
comment
спасибо. Но вопрос несколько без ответа. Воспроизведение звука - это свет, поэтому его нужно обрабатывать с помощью одного EDT. - person joey rohan; 16.12.2012