线程内部的方法不会被调用

时间:2014-04-05 19:31:55

标签: java swing actionlistener serversocket event-dispatch-thread

serverinitator类中的serverinititaor()。initialize(5555)方法未在以下代码中调用。

此方法将在端口5555上为客户端启动一个新帧,用于发送消息或聊天目的等功能。

public static void main(String[] args) {

    new Thread(new Runnable() {

        public void run() {
            frame = new JFrame("client list");
        panel = new JPanel();
        JButton button = new JButton("Refresh Client list");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                if(success){
                JButton jb = new JButton("A new Client on port 5555");
                jb.addActionListener(new ActionListener() {


                    public void actionPerformed(ActionEvent e) {

                        new ServerInitiator().initialize(5555);
                    }
                });
                panel.add(jb);
                frame.revalidate();
                }

    }).start();

}

ServerInitiator.java

synchronized public void initialize(int port){

    try {            
        final ServerSocket sc = new ServerSocket(port);
        System.out.println(SwingUtilities.isEventDispatchThread());            
        drawGUI();


        new Thread(new Runnable(){
            public void run()
            {
                try {
                    Socket client = sc.accept();
                System.out.println("New client Connected to the server");

                new ClientHandler(client,desktop);
                } catch (IOException ex) {

                }
            }
        }).start();

    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

请回复。

感谢。

2 个答案:

答案 0 :(得分:1)

我尝试应用使其可编译所必需的最小更改。结果就是这堂课。出于一些神秘的原因,我打电话给这个班ItDoesGetCalled

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ItDoesGetCalled
{
    public static void main(String[] args) {

        new Thread(new Runnable() {

            public void run() {
                final JFrame frame = new JFrame("client list");
                final JPanel panel = new JPanel();
                JButton button = new JButton("Refresh Client list");
                button.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e)
                    {
                        boolean success = true;
                        if(success){
                            JButton jb = new JButton("A new Client on port 5555");
                            jb.addActionListener(new ActionListener() {


                                public void actionPerformed(ActionEvent e) {

                                    new ServerInitiator().initialize(5555);
                                }
                            });
                            panel.add(jb);
                            frame.pack();
                        }
                    }        
                });
                panel.add(button);
                frame.getContentPane().add(panel);
                frame.pack();
                frame.setVisible(true);
            }
        }).start();
    }
}

class ServerInitiator
{
    synchronized public void initialize(int port)
    {
        System.out.println("Here we go...");
    }    
}

但是,强烈建议您清理一下。所有线程的目的是什么?目前,这样的事情就足够了:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ClientServerUI
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }


    private static void createAndShowGUI()
    {
        JFrame f = new JFrame("Client list");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel clientListPanel = new ClientListPanel();
        f.getContentPane().add(clientListPanel);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class ClientListPanel extends JPanel
{
    ClientListPanel()
    {
        setLayout(new GridLayout(0,1));
        JButton refreshButton = new JButton("Refresh client list");
        refreshButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                boolean success = true;
                if(success)
                {
                    createNewClientButton();
                }
            }        
        });
        add(refreshButton);
    }

    private void createNewClientButton()
    {
        JButton newClientButton = new JButton("A new Client on port 5555");
        newClientButton.addActionListener(new ActionListener() 
        {
            @Override
            public void actionPerformed(ActionEvent e) {

                new ServerInitiator().initialize(5555);
            }
        });
        add(newClientButton);
        SwingUtilities.getWindowAncestor(this).pack();
    }
}

class ServerInitiator
{
    synchronized public void initialize(int port)
    {
        System.out.println("Here we go...");
    }    
}

答案 1 :(得分:1)

您不应在Event Dispatch Thread(EDT)之外分配您的用户界面。另一方面,保持联网远离EDT。请注意,Swing有一个单线程绘画模型。 UI组件分配及其交互必须在EDT上完成。有关详细信息,请查看Concurrency in Swing

为了获得最佳性能,EDT上的所有任务都应该简短。网络应该在工作线程上处理。有几个选项:SwingWorkerExecutorService或您自己的辅助线程。 SwingWorker有一个内置机制来推送EDT上的更新。如果是ExecutorService,您可以将SwingUtilities.invokeLater用于此目的,与您自己的工作线程相同。