2014-02-05 116 views
0

我用java製作了語音通話應用程序。該框架由兩個按鈕組成,一個用於呼叫,另一個用於切斷呼叫。我的問題是每當我按下通話按鈕線程開始運行並且數據(語音)連續傳輸,但其他操作(如剪切按鈕或幀關閉按鈕)根本不響應。就像框架掛起一樣。有人能幫我解決這個問題嗎?JFrame根本沒有響應

編輯:這是我的客戶端代碼。沒有爲服務器製作任何框架。它只是在另一臺機器上運行。

import java.awt.BorderLayout; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.*; 
import javax.sound.sampled.*; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 

public class Program extends JFrame implements ActionListener 
    { 
JButton jbtOpen, c; 
JFrame f1=new JFrame(); 
JPanel PPanel1; 
JLabel limg=new JLabel(); 
public final static String SERVER = JOptionPane.showInputDialog("Please enter server IP"); 
public Program() 
{ 
    PPanel1 = new JPanel(null); 
    PPanel1.setPreferredSize(new Dimension(1366,786)); 
    Container con=getContentPane(); 
    ImageIcon image1 = new ImageIcon("voicecall.jpg"); 
    ImageIcon image2 = new ImageIcon("voicecall1.jpg"); 
    ImageIcon image3 = new ImageIcon("call.jpg"); 
    jbtOpen=new JButton("Call"); 
    c=new JButton("Cut"); 
    limg.setIcon(image1); 
    jbtOpen.setIcon(image2); 
    c.setIcon(image3); 
    limg.setBounds(0,0,1500,700); 
    jbtOpen.setBounds(50,50,100,100); 
    c.setBounds(200,50,100,100); 
    PPanel1.add(limg); 
    PPanel1.add(jbtOpen); 
    PPanel1.add(c); 
    setSize(400, 400); 
    setVisible(true); 
    setTitle("Voice Calling"); 
    con.add(PPanel1,BorderLayout.WEST); 
    jbtOpen.addActionListener(this); 
    c.addActionListener(this); 
      f1.addWindowListener(new W1()); 
} 


public void actionPerformed(ActionEvent e) 
    { 
     if(e.getSource() == jbtOpen) 
       { 
        try { 
        open(); 
       } catch (Exception e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

        if(e.getSource() == c){ 
         System.exit(0); 
        } 
       } 

    } 
public void open() throws Exception 
{ 
AudioFormat af = new AudioFormat(8000.0f,8,1,true,false); 
DataLine.Info info = new DataLine.Info(TargetDataLine.class, af); 
TargetDataLine microphone = (TargetDataLine)AudioSystem.getLine(info); 
microphone.open(af); 
Socket conn = new Socket(SERVER,3000); 
microphone.start(); 
DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); 
int bytesRead = 0; 
byte[] soundData = new byte[1]; 
Thread inThread = new Thread(new SoundReceiver(conn)); 
inThread.start(); 
while(bytesRead != -1) 
{ 
    bytesRead = microphone.read(soundData, 0, soundData.length); 
    if(bytesRead >= 0) 
    { 
     dos.write(soundData, 0, bytesRead); 
    } 
} 
System.out.println("IT IS DONE."); 
} 

public static void main(String args[]) 
{ 
     Program b=new Program(); 
} 
    private class W1 extends WindowAdapter 
{ 
    public void windowClosing(WindowEvent we) 
    { 
    System.exit(0); 
    } 
} 

} 
+3

我的猜測是,你沒有*實際*推出了一個新的線程,但是正在捆綁UI線程。我們無法檢查,但沒有看到代碼。 –

+0

我們需要看一些代碼。你如何停止你使用通話按鈕開始的線程?如果你只是使用標準的Thread或Runnable,你需要調用interrupt(),然後提供一些方法來識別線程中的中斷並從run()方法返回。它可能會更復雜,如果你使用I/O並且它是阻塞的,那麼在你傳輸數據的循環中,你需要中斷它。基本上,如果沒有一個最小的例子來運行和演示問題,我們就無法診斷問題。 – mttdbrd

+0

我用編碼編輯了這個問題。 – sam

回答

0

這段代碼有很多問題。該actionPerformed方法永遠不會達到System.exit()的,因爲你有這樣的代碼塊:

if(e.getSource() == c){ 
    System.exit(0); 
} 

if(e.getSource() == jbtOpen)代碼塊。你至少需要別的東西。

System.exit()不是清理正在運行的線程的好方法。至少應該用一箇中斷()或其他東西來更好地關閉它。

+0

嗯,我明白你說的bt框架只是在我按下通話按鈕後掛起。按鈕就像固定。像框架已經死了。 – sam

+0

你從一個阻塞的IO調用中一次讀取一個字節時有一個嚴格的循環。只要管道中存在數據,UI將永遠不會刷新。 open()方法中的所有垃圾應該放在SwingWorker線程中,如@ user1676075昨天所建議的。 – mttdbrd