joey rohan
joey rohan

Reputation: 3566

JFrame behaving weirdly

In my program, I am displaying images with a song in background. After song is finished, i need to close frame and JInternalFrame. Here is the code:

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...//////
}

This code is fine, but when I tried out without adding a component listener, that is, getRootPane().SetVisible(false) or jInternalFrame1.getContentPane().setVisible(false) or setVisible(false) none of them was working, but it worked out only after adding a component hidden listener. Why? Any reasons?Then how come JInternalFrame was working (JInternalFrame.setVisible(false))? Is this something to do with rootPane()?

Upvotes: 2

Views: 128

Answers (1)

trashgod
trashgod

Reputation: 205775

As discussed in Initial Threads, "An initial thread schedules the GUI creation task by invoking invokeLater or invokeAndWait." You are trying to both play a sound and operate a GUI on the same initial thread. Instead, start the sound on the initial thread and construct the GUI on the EDT, as shown here, or start a separate thread to play the sound, as shown here.

I don't want to use AWT dispatch thread.

Right, you don't want to use the AWT event dispatch thread to play sound, but you must use it for the GUI.

The question is somewhat unanswered. The playing of sound is light, so must be handled by single EDT.

I can only speculate that using a different component changed the timing enough to affect the result on your platform. Until the program is correctly synchronized, there's always some environment in which it will work and some in which it will fail. The essential rule is this: don't block the EDT. See also this answer, this answer and the Java Sound tag.

Upvotes: 4

Related Questions