java的socket服务端的GUI

java的socket服务端的GUI 2012-05-04 09:03 (分类:JAVA代码)

这几天做了一个基于socket的宠物商店程序,其中服务端的图形化界面问题困扰了很久。今天终于解决,因此也对多线程有了更好的理解。

想很多新手一样,我其实犯了一个错误。

由于soket服务端端口监听用的是 while(true)循环导致,GUI点击开启服务后,主线程被阻塞在while(true)上,是GUI界面失效。

找到了问题所在,那么就用多线程解决。把监听端口放到线程里,这样就不会阻塞主线程画GUI界面。

由于没搞清楚 start()和run(),的区别,结果又出事了。在启动按钮事件里 直接调用了线程的run(),结果点击启动按钮后,GUI界面依然失效。

这就说明主线程依然被阻塞到while(true)里面了,为什么呢?

仔细研究发现run()方法并没有真正的触发线程,run只是调用的 线程中的实现,实际上,程序本身依然是单线程的。所以按钮调用run()依然会阻塞主线程。

将run()改为start()问题就解决了,start()是触发线程,真正的实现了多线程。这样接听端口的while()在副线程里,并不会阻塞主线程。这样GUI不会再

失效了。

这是修改后的代码: 

 

package server;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Server_GUI {
 Server server = new Server();
 JFrame jf = new JFrame("宠物店服务器V1.0");
 private JTabbedPane tabs = new JTabbedPane();
 private JTextField txt = new JTextField();
 private JButton StartServer = new JButton("启动服务器");
 private JButton StopServer = new JButton("关闭服务器");
 private ButtonPanel managerPanel = new ButtonPanel("服务的开启与关闭",
   new String[] {});
 private ButtonPanel informationPanel = new ButtonPanel("服务的版本信息",
   new String[] {});
 private JPanel manager = new JPanel();// 管理面板
 private JPanel information = new JPanel();// 版本面板

 public void init() {
  StartServer.addActionListener(new ActionListener() {

   @Override
   public void actionPerformed(ActionEvent arg0) {
    JOptionPane.showMessageDialog(null, "服务已开启!", "服务启动",
      JOptionPane.DEFAULT_OPTION);
     server.start();
   }
  });
  StopServer.addActionListener(new ActionListener() {

   @Override
   public void actionPerformed(ActionEvent arg0) {
    JOptionPane.showMessageDialog(null, "服务已关闭!", "服务关闭",
      JOptionPane.DEFAULT_OPTION);
    System.exit(0);
   }
  });
  // 管理界面
  JPanel panel_1 = new JPanel();
  panel_1.add(StartServer);
  JPanel panel_2 = new JPanel();
  panel_2.add(StopServer);
  Box managertop = Box.createVerticalBox();
  managertop.add(panel_1);
  managertop.add(panel_2);
  managerPanel.add(managertop);
  manager.add(managerPanel);
  tabs.add("管理界面", manager);
  // 版本信息
  JPanel panel4_1 = new JPanel();
  JPanel panel4_2 = new JPanel();
  JPanel panel4_3 = new JPanel();
  JPanel panel4_4 = new JPanel();
  JPanel panel4_5 = new JPanel();
  JPanel panel4_7 = new JPanel();
  JPanel panel4_9 = new JPanel();
  Box topInformation = Box.createVerticalBox();
  topInformation.add(panel4_1.add(new JLabel("宠物网络服务器端V1.0")));
  topInformation.add(panel4_2.add(new JLabel("主要功能:")));
  topInformation.add(panel4_3.add(new JLabel("宠物信息的增、删、改、查!")));
  topInformation.add(panel4_5.add(new JLabel("宠物信息动态存储,服务器同步!")));
  topInformation.add(panel4_4.add(new JLabel("2010届—网络15班")));
  topInformation.add(panel4_7.add(new JLabel("姓名:仲强-学号:53101512")));
  topInformation.add(panel4_9.add(new JLabel("2012年4月25日 QQ:6475005")));
  informationPanel.add(topInformation);
  information.add(informationPanel);
  tabs.add("版本信息", information);

  // tabs 页签选择监听器
  tabs.addChangeListener(new ChangeListener() {
   public void stateChanged(ChangeEvent e) {
    if (tabs.getSelectedIndex() == 0) {
     txt.setText("管理界面");
    } else {
     txt.setText("版本信息");
    }
   }
  });

  Container contentPane = jf.getContentPane();
  contentPane.add(BorderLayout.SOUTH, txt);
  contentPane.add(tabs);

  jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  jf.pack();
  jf.setVisible(true);
 }

 @SuppressWarnings("serial")
 class ButtonPanel extends JPanel {
  private ButtonGroup group;

  public ButtonPanel(String title, String[] options) {
   setBorder(BorderFactory.createTitledBorder(
     BorderFactory.createEtchedBorder(), title));
   setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
   group = new ButtonGroup();
   for (int i = 0; options != null && i < options.length; i++) {
    JRadioButton b = new JRadioButton(options[i]);
    b.setActionCommand(options[i]);
    add(b);
    group.add(b);
    b.setSelected(i == 0);
   }
  }

  // 定义一个方法,用于返回用户选择的选项
  public String getSelection() {
   return group.getSelection().getActionCommand();
  }
 }

 public static void main(String[] args) {
  File f = new File("users_pet");
  if (!f.exists()) {
   f.mkdirs();
  }
  new Server_GUI().init();
 }

 public class Server extends Thread {

  @Override
  public void run() {
   ServerMain server = new ServerMain();
   server.StartServer();
  }
 }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值