2014-02-05 56 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