Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 此代码显示在窗口控制台上的代码,但不显示在我使用的文本区域上_Java_Swing_Awt_Jtextfield_Jtextarea - Fatal编程技术网

Java 此代码显示在窗口控制台上的代码,但不显示在我使用的文本区域上

Java 此代码显示在窗口控制台上的代码,但不显示在我使用的文本区域上,java,swing,awt,jtextfield,jtextarea,Java,Swing,Awt,Jtextfield,Jtextarea,下面是我的代码: package Project1; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.JTextArea; import javax.swing.JTextField; import ja

下面是我的代码:

package Project1;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Font;
import javax.swing.JScrollBar;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class DonorChat extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    String get=null;
    String s1=null;
    DataOutputStream dos;
    DataInputStream dis;
    JButton btnNewButton;
    private JPanel contentPane;
    public JTextField textField;
    public JTextArea textArea ;
    public JButton btnNewButton_1;
    public DonorChat() {
        setTitle("Donor Chat");
//        setIconImage(Toolkit.getDefaultToolkit().getImage("E:\\algorithm\\Project1\\Project1\\Blood.png"));
        setIconImage(Toolkit.getDefaultToolkit().getImage("E:\\algorithm\\Project1\\Project1\\Blood.png"));
        setForeground(Color.RED);
        setFont(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(0, 0, 800, 1000);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        textArea= new JTextArea();
        textArea.setFont(new Font("Tahoma", Font.BOLD, 17));
        textArea.setBounds(31, 222, 707, 522);
        contentPane.add(textArea);


        textField = new JTextField();
        textField.setFont(new Font("Tahoma", Font.BOLD, 17));
        textField.setBounds(31, 793, 510, 105);
        contentPane.add(textField);
        textField.setColumns(10);
        textField.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub

            }

        });

        btnNewButton = new JButton("Send\r\n");
        btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 17));
        btnNewButton.setForeground(Color.RED);
        btnNewButton.setBackground(Color.LIGHT_GRAY);
        btnNewButton.setBounds(602, 820, 125, 47);
        contentPane.add(btnNewButton);

        JScrollBar scrollBar = new JScrollBar();
        scrollBar.setBounds(717, 222, 21, 522);
        contentPane.add(scrollBar);

        btnNewButton_1 = new JButton("CONNECT TO SERVER");
        btnNewButton_1.setBackground(Color.RED);
        btnNewButton_1.setForeground(Color.DARK_GRAY);
        btnNewButton_1.setFont(new Font("Times New Roman", Font.BOLD, 29));
        btnNewButton_1.setBounds(31, 60, 707, 86);
        contentPane.add(btnNewButton_1);
        btnNewButton_1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                try {
                    ServerSocket ss=new ServerSocket(9995);
                    Socket snSocket=ss.accept();
                    dos=new DataOutputStream(snSocket.getOutputStream());
                    dis=new DataInputStream(snSocket.getInputStream());
                    getValue();
                    ss.close();
                } 
                catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

        setVisible(true);
    }
    public void getValue() throws IOException{
        btnNewButton.removeActionListener(null);
        while(true){
            s1=dis.readUTF();
            if (s1.equals("stop")){
                textArea.setText("Client Want to Stop:"+s1);
                break;
            }
            else{
                System.out.println("Client Says:"+s1);
                textArea.setText("Client Says:"+s1);
            }
            System.out.println("Type Something for Client");
            btnNewButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0){
                    try {
                        dos.writeUTF(get);
                    }
                    catch(Exception e){

                    }
                }
            });    
        }
    }
}
我正在为服务器构建一个窗口,该窗口需要一个连接按钮来连接服务器套接字,但在为该服务器设置客户端并向客户端发送消息后,该消息显示在eclipse控制台上,而不是我实际想要的文本区域上

所以请帮我看看我的代码。

有两个问题:

  • 您的
    while(true)
    循环正在阻止AWT事件分派线程
  • 您正在循环的每个迭代中添加一个侦听器
  • 暂停事件队列 。当您的“连接到服务器”按钮的ActionListener被调用时,它将在AWT事件调度线程中被调用。在该方法返回之前,不会处理任何其他事件

    因此,当ActionListener调用
    getValue()
    ,并且getValue()从套接字读取,直到遇到
    “stop”
    ,所有事件处理都将暂停。没有东西会被重新粉刷。将不会对鼠标或键盘输入做出响应,因为不会处理MouseeEvents和KeyEvents

    您必须执行I/O操作,如从不同线程上的套接字读取。但是,Swing方法必须在AWT事件调度线程中执行

    一种解决方案是使用类,它的
    publish
    process
    方法允许您将多个数据元素从后台线程发送到AWT甚至调度线程

    要发送到套接字,可以使用线程安全的BlockingQueue存储要发送的行,然后在不同的线程(不是AWT事件分派线程)中使用循环从该BlockingQueue获取文本并将其发送到套接字

    只添加一次侦听器 方法
    addActionListener
    实际上是向按钮添加一个侦听器。按下按钮时,将调用您添加的所有侦听器

    因此,如果您每次执行循环时都调用
    addActionListener
    ,那么您将为从套接字读取的每段数据添加一个侦听器

    通常在创建按钮之后,只应向按钮添加一次ActionListener

    代码 因此,如果我们将I/O移动到其他线程,并使用BlockingQueue跟踪要发送的行,它看起来是这样的:

    private final BlockingQueue<String> linesToSend =
        new LinkedBlockingDeque<>();
    
    public DonorChat() {
    
        // ...
    
        textField.addActionListener(new ActionListener() {
            linesToSend.add(textField.getText());
        });
    
        btnNewButton.addActionListener(new ActionListener() {
            linesToSend.add(textField.getText());
        });
    
        // ...
    }
    
    private void getValue(Socket snSocket) {
    
        textArea.setText("");
    
        SwingWorker<Void, String> socketReader =
            new SwingWorker<Void, String>() {
                @Override
                protected Void doInBackground()
                throws IOException {
    
                    // Runs in another thread.
                    // No AWT/Swing calls allowed here!
    
                    dis = new DataInputStream(snSocket.getInputStream());
    
                    while (true) {
                        String s1 = dis.readUTF();
                        if (s1.equals("stop")) {
                            publish("Client wants to stop.");
                            break;
                        }
    
                        publish("Client says: " + s1);
                    }
    
                    snSocket.close();
    
                    return null;
                }
    
                @Override
                protected void process(List<String> linesRead) {
    
                    // Runs in event dispatch thread thread.
                    // AWT/Swing calls only;  no I/O allowed here!
    
                    for (String line : linesRead) {
                        textArea.append(line + "\n");
                    }
                }
            };
    
        socketReader.execute();
    
        // Lines to send were added in AWT event dispatch thread
        // by ActionListeners.
        // We want to send them to the socket in a different thread.
    
        Runnable linesSender = new Runnable() {
            @Override
            public void run() {
                try {
                    dos = new DataOutputStream(snSocket.getOutputStream());
                    while (true) {
                        dos.writeUTF(linesToSend.take());
                    }
                } catch (IOException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    
        new Thread(linesSender).start();
    }
    
    private final blocking队列行发送=
    新的LinkedBlockingDeque();
    公共捐款人{
    // ...
    addActionListener(新ActionListener(){
    linesToSend.add(textField.getText());
    });
    addActionListener(新ActionListener(){
    linesToSend.add(textField.getText());
    });
    // ...
    }
    私有void getValue(套接字snSocket){
    textArea.setText(“”);
    SwingWorker socketReader=
    新SwingWorker(){
    @凌驾
    受保护的Void doInBackground()
    抛出IOException{
    //在另一个线程中运行。
    //这里不允许AWT/Swing呼叫!
    dis=新的DataInputStream(snSocket.getInputStream());
    while(true){
    字符串s1=dis.readUTF();
    如果(s1等于(“停止”)){
    发布(“客户想要停止”);
    打破
    }
    发布(“客户说:”+s1);
    }
    snSocket.close();
    返回null;
    }
    @凌驾
    受保护的无效进程(列表行读取){
    //在事件分派线程中运行。
    //仅限AWT/Swing调用;此处不允许I/O!
    用于(字符串行:linesRead){
    textArea.append(第+行“\n”);
    }
    }
    };
    socketReader.execute();
    //要发送的行已添加到AWT事件调度线程中
    //由ActionListeners提供。
    //我们想用不同的线程将它们发送到套接字。
    Runnable linesSender=new Runnable(){
    @凌驾
    公开募捐{
    试一试{
    dos=新的DataOutputStream(snSocket.getOutputStream());
    while(true){
    writeUTF(linesToSend.take());
    }
    }捕获(IOException | InterruptedException e){
    e、 printStackTrace();
    }
    }
    };
    新螺纹(linesSender).start();
    }
    
    其他一些重要注意事项:

    • 切勿写入空的
      catch
      块。异常告诉您哪里出了问题,哪里出了问题,这是非常有价值的信息。如果您不确定在
      catch
      块中放入什么,请编写
      e.printStackTrace()以便您可以查看异常的完整详细信息
    • 空布局将使您的计算机看起来正常,但在其他计算机上会出现问题,因为安装的字体不同,字体呈现的大小也不同。(“17分”是指ª⁷⁄₇₂ 英寸,在120 DPI显示器上渲染的像素比在96 DPI显示器上渲染的像素多。)此外,空布局意味着您无法调整窗口大小以使JTextArea和JTextField变大或变小

    您的
    while(true)
    是从事件侦听器调用的,因此AWT无法处理任何其他事件:它无法绘制任何内容,也无法响应用户输入。看见另外,
    addActionListener
    字面上*将一个侦听器添加到组件的侦听器列表*-这意味着在循环的第二次迭代之后,有两个侦听器,下次有三个侦听器,然后是四个,五个,依此类推。不要在循环中调用
    addActionListener
    。嘿……所以请建议我在这里使用的想法。