Home > Software engineering >  JFrame showing empty when start socket server
JFrame showing empty when start socket server

Time:03-01

When the code uses a socket, the receiving frame loads empty. It does not add fileNameLabel, headerLabel or scrollFile and if I remove the socket then it loads all added Swing components.

How can I deal with it?

This is the full code of receive files:

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();

            }
        });
    }
}

CodePudding user response:

You are calling method receiveFile on the Event Dispatch Thread (EDT). Method receiveFile contains the following line:

Socket socket = serverSocket.accept();

Here is a quote from the javadoc of method accept:

The method blocks until a connection is made.

In other words, when you run your program, its execution will stop at the above line until a socket connection is made. Thus you have literally stopped the EDT. If the EDT is stopped then it can't paint anything and that's why

It does not add fileNameLabel, headerLabel or scrollFile

And that's also why

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

You need to run your socket code on a separate thread.
You can either use a SwingWorker or create a new Thread to run your socket code and update the GUI from that thread by calling method invokeLater of class java.awt.EventQueue. Note that you will probably find a lot of examples that use method invokeLater of class javax.swing.SwingUtilities. That method simply calls the same name method in class java.awt.EventQueue.

  • Related