java socket gui登录_java的socket服务端的GUI
這幾天做了一個基于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(); ??} ?} }
總結
以上是生活随笔為你收集整理的java socket gui登录_java的socket服务端的GUI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android studio配置java
- 下一篇: java自定义键值对_KV键值对数据类型