启动套接字服务器时 JFrame 显示为空

JFrame showing empty when start socket server

当代码使用套接字时,接收帧加载为空。 它不添加 fileNameLabelheaderLabelscrollFile,如果我移除套接字,它会加载所有添加的 Swing 组件。

我该如何处理?

这是接收文件的完整代码:

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
// import java.lang.module.ModuleDescriptor.Builder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

// import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

// import javax.swing.border.Border;
// import javax.swing.border.EmptyBorder;
// import java.awt.Color;
import java.awt.Component;

class App {

    public static File[] file = new File[1];

    public static void receiveFile() {

        JFrame receiveFileFrame;
        JPanel receiveFilePanel;
        JLabel fileNameLabel, headerLabel;

        receiveFileFrame = new JFrame();
        receiveFilePanel = new JPanel();
        fileNameLabel = new JLabel();
        headerLabel = new JLabel();

        receiveFileFrame.setBounds(750, 300, 400, 400);
        receiveFileFrame.setLayout(new BoxLayout(receiveFileFrame.getContentPane(), BoxLayout.Y_AXIS));

        JScrollPane scrollFiles = new JScrollPane(receiveFilePanel);
        scrollFiles.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        fileNameLabel.setFont(new Font("Serif", Font.BOLD, 20));
        fileNameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        headerLabel.setText("Received Files");
        headerLabel.setFont(new Font("Serif", Font.BOLD, 20));
        headerLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        receiveFilePanel.add(fileNameLabel);

        receiveFileFrame.add(headerLabel);
        receiveFileFrame.add(scrollFiles);

        receiveFileFrame.setVisible(true);

        receiveFileFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        try {

            ServerSocket serverSocket = new ServerSocket(4444);
            while (true) {
                Socket socket = serverSocket.accept();
                DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
                int fileNameLength = dataInputStream.readInt();
                byte[] fileNameSize = new byte[fileNameLength];
                dataInputStream.readFully(fileNameSize, 0, fileNameSize.length);
                String fileName = new String(fileNameSize);
                fileNameLabel.setText(fileName);
                int fileContentLength = dataInputStream.readInt();
                byte[] fileContentSize = new byte[fileContentLength];
                dataInputStream.readFully(fileContentSize, 0, fileContentLength);
                File fileDownload = new File(fileName);
                FileOutputStream fileOutputStream = new FileOutputStream(fileDownload);
                fileOutputStream.write(fileContentSize);
                fileOutputStream.close();
            }
            
        } catch (Exception e) {
            JOptionPane.showMessageDialog(receiveFileFrame, e, "Message", 0);
        }

    }

    public static void main(String[] args) throws Exception {
        JFrame mainFrame = new JFrame();
        JButton send, receive;
        JPanel mainPanel, buttoPanel;
        JLabel heading;
        // Border border = BorderFactory.createLineBorder(Color.black);

        heading = new JLabel();
        send = new JButton();
        receive = new JButton();
        mainPanel = new JPanel();
        buttoPanel = new JPanel();

        mainFrame.setBounds(700, 250, 400, 200);
        mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS));

        heading.setText("File Transfer");
        heading.setFont(new Font("Serif", Font.BOLD, 20));
        heading.setAlignmentX(Component.CENTER_ALIGNMENT);

        send.setText("Send");
        send.setSize(100, 50);
        send.setFont(new Font("Serif", Font.PLAIN, 15));

        receive.setText("Receive");
        receive.setSize(100, 50);
        receive.setFont(new Font("Serif", Font.PLAIN, 15));

        buttoPanel.add(send);
        buttoPanel.add(receive);

        mainPanel.add(heading);
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        mainPanel.add(Box.createHorizontalStrut(10));
        mainPanel.add(buttoPanel);

        mainFrame.add(mainPanel);

        mainFrame.setVisible(true);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        send.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                JOptionPane.showMessageDialog(mainFrame, "Send feature not added", "Message", 0);

            }
        });

        receive.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                receiveFile();

            }
        });
    }
}

您正在 Event Dispatch Thread(美国东部时间)调用方法 receiveFile。方法 receiveFile 包含以下行:

Socket socket = serverSocket.accept();

这里引用了方法 acceptjavadoc:

The method blocks until a connection is made.

换句话说,当你运行你的程序时,它的执行将停止在上面的行,直到建立套接字连接。因此,您实际上已经停止了 EDT。如果 EDT 停止,则它无法绘制任何东西,这就是为什么

It does not add fileNameLabel, headerLabel or scrollFile

这也是为什么

if I remove the socket then it loads all added Swing components

您需要 运行 您的套接字代码在单独的线程上。
您可以使用 SwingWorker or create a new Thread to run your socket code and update the GUI from that thread by calling method invokeLater 或 class java.awt.EventQueue。请注意,您可能会发现很多示例使用 class javax.swing.SwingUtilities 的方法 invokeLater。该方法只是调用 class java.awt.EventQueue.

中的同名方法