使用java swing和socket编程实现简单的多人聊天室
来源:互联网 发布:淘宝评价怎么看五星 编辑:程序博客网 时间:2024/05/17 01:03
完成效果如下
客户端:
服务器端:
客户端功能:
输入服务器对应的端口,IP号,用户名(昵称),可以互相发送消息
服务器端功能:
输入端口号,启动,可以向所有客户端发送消息,IP地址自动获取。
下面是客户端界面:
package Test;import UI.ChatRoomClientFrame;public class ChatRoomClient {public static void main(String[] args) {new ChatRoomClientFrame().setVisible(true);}}客户端实现:
package UI;import java.awt.BorderLayout;import java.awt.Color;import java.awt.FileDialog;import java.awt.Font;import java.awt.Image;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import java.util.Properties;import javax.swing.JButton;import javax.swing.JColorChooser;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.TitledBorder;public class ChatRoomClientFrame extends JFrame{/** * */private static final long serialVersionUID = 7909370607161820239L;private JPanel panel;private JPanel northPanel;private JPanel southPanel;private JTextField port;private JTextField IP;private JTextField userName;private JTextArea userlist;private JTextArea chatRecords;private JScrollPane leftPanel;private JScrollPane rightPanel;private JSplitPane centerPanel;private JTextField message;private JButton link;private JButton discon;private JButton send;private JPanel Jpanel;private JMenuBar bar;private JMenu file;private JMenuItem save;private JMenu format;private JMenuItem font;private JMenuItem foreGround;private JMenuItem backGround;private Font myfont;private boolean isConnect = false;private Socket socket;private DataInputStream dis;private DataOutputStream dos;private ClientThread ct;//private ArrayList<String> users = new ArrayList<String>();private String[] userstr;private int usersLength = 0;public ChatRoomClientFrame(){initServer();link.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(userName.getText().trim().equals("")){JOptionPane.showMessageDialog(null, "用户名不能为空","错误",JOptionPane.ERROR_MESSAGE);}else{try {socket = new Socket(IP.getText(),Integer.parseInt(port.getText()));dos = new DataOutputStream(socket.getOutputStream());dis = new DataInputStream(socket.getInputStream());if(socket!=null){port.setEditable(false);IP.setEditable(false);userName.setEditable(false);link.setEnabled(false);discon.setEnabled(true);ct = new ClientThread();ct.start();if(isConnect==false){dos.writeUTF(userName.getText()+" 进入了聊天室");isConnect=true;}}} catch (NumberFormatException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (UnknownHostException e1) {e1.printStackTrace();} catch (IOException e1) {JOptionPane.showMessageDialog(null, "服务器未开启","错误",JOptionPane.ERROR_MESSAGE);e1.printStackTrace();} }}});discon.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {if(isConnect==true){isConnect=false;dos.writeUTF(userName.getText()+" 离开了聊天室");userlist.setText("");userstr=null;usersLength=0;dos.close();dis.close();socket.close();chatRecords.append("\n");chatRecords.append("你离开了聊天室");chatRecords.setCaretPosition(chatRecords.getDocument().getLength());port.setEditable(true);IP.setEditable(true);userName.setEditable(true);link.setEnabled(true);discon.setEnabled(false);ct.stop();}} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});send.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {send();}});message.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {send();}});font.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {MyFontChooser mf = new MyFontChooser(chatRecords.getFont()); int returnValue = mf.showFontDialog(ChatRoomClientFrame.this); // 如果按下的是确定按钮 if (returnValue == MyFontChooser.APPROVE_OPTION) { // 获取选择的字体 Font font = mf.getSelectFont(); // 将字体设置到JTextArea中 chatRecords.setFont(font); }}});save.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {FileDialog saveFile = new FileDialog(ChatRoomClientFrame.this, "保存文件...", FileDialog.SAVE);saveFile.setVisible(true);String filePath = saveFile.getDirectory() + saveFile.getFile();try {FileOutputStream fos = new FileOutputStream(filePath);fos.write(chatRecords.getText().getBytes());fos.close();} catch (FileNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});backGround.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Color bc = JColorChooser.showDialog(ChatRoomClientFrame.this, "选择颜色", Color.BLACK);chatRecords.setBackground(bc);}});foreGround.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Color fc = JColorChooser.showDialog(ChatRoomClientFrame.this, "选择颜色", Color.BLACK);chatRecords.setForeground(fc);}});initFrame();}private void initServer() {Jpanel = new JPanel();Jpanel.setLayout(new BorderLayout());panel = new JPanel();panel.setLayout(new BorderLayout());northPanel = new JPanel();northPanel.setBorder(new TitledBorder("连接信息"));bar = new JMenuBar();file = new JMenu("记录");save = new JMenuItem("保存");format = new JMenu("格式");font = new JMenuItem("字体");foreGround = new JMenuItem("前景色");backGround = new JMenuItem("背景色");file.add(save);format.add(font);format.add(foreGround);format.add(backGround);bar.add(file);bar.add(format);Jpanel.add(bar,BorderLayout.NORTH);port = new JTextField(8);port.setText("8088");IP = new JTextField(8);IP.setText("192.168.24.8");userName = new JTextField(8);link= new JButton("启动");discon= new JButton("停止");discon.setEnabled(false);northPanel.add(new JLabel("端口号"));northPanel.add(port);northPanel.add(new JLabel("服务器IP"));northPanel.add(IP);northPanel.add(new JLabel("用户名"));northPanel.add(userName);northPanel.add(link);northPanel.add(discon);panel.add(northPanel,BorderLayout.NORTH);userlist = new JTextArea();userlist.setLineWrap(true);userlist.setEditable(false);leftPanel =new JScrollPane(userlist);leftPanel.setBorder(new TitledBorder("在线用户"));panel.add(leftPanel,BorderLayout.EAST);chatRecords = new JTextArea();chatRecords.setLineWrap(true);chatRecords.setEditable(false);rightPanel =new JScrollPane(chatRecords);rightPanel.setBorder(new TitledBorder("聊天信息"));centerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel); centerPanel.setDividerLocation(100); panel.add(centerPanel,BorderLayout.CENTER);southPanel = new JPanel();southPanel.setBorder(new TitledBorder("写消息"));message = new JTextField(50);send = new JButton("发送");southPanel.add(message);southPanel.add(send);panel.add(southPanel, BorderLayout.SOUTH);Jpanel.add(panel,BorderLayout.CENTER);this.add(Jpanel);}private void initFrame(){this.setTitle("聊天室-客户端");this.setSize(640,480);this.setLocationRelativeTo(null);Toolkit kit = Toolkit.getDefaultToolkit();Image img = kit.getImage("img/logo.jpg");this.setIconImage(img);this.setResizable(false);opening();this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);closing();}public class ClientThread extends Thread{@Overridepublic void run() {String message=null;while(true){try {message = dis.readUTF();if(message.contains("@在线用户列表@")){userstr = message.split(" ");if(userstr.length!=usersLength){userlist.setText("");for(int i=0;i<userstr.length-1;i++){ userlist.append(userstr[i]); userlist.append("\n");}usersLength = userstr.length;}}else{chatRecords.append("\n");chatRecords.append(message);chatRecords.setCaretPosition(chatRecords.getDocument().getLength());}} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {if(isConnect==true)JOptionPane.showMessageDialog(null, "服务器断开连接","错误",JOptionPane.ERROR_MESSAGE);link.setEnabled(true);discon.setEnabled(false);isConnect = false;port.setEditable(true);IP.setEditable(true);userName.setEditable(true);userlist.setText("");userstr=null;usersLength=0;try {dis.close();dos.close();socket.close();ct.stop();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}e.printStackTrace();}}}}public void send(){if(isConnect==false){JOptionPane.showMessageDialog(null, "未连接服务器,无法发送消息","错误",JOptionPane.ERROR_MESSAGE);return;}if(message.getText().trim().equals("")){JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);return;}String str = message.getText();sendMessage(str);}public void sendMessage(String str){try {dos.writeUTF(userName.getText()+": "+str);} catch (IOException e) {e.printStackTrace();}message.setText("");}public void opening(){Properties p = new Properties();try {if(new File("src/FontClient.properties").exists()){p.load(new FileReader("src/FontClient.properties"));myfont = new Font(p.getProperty("FontName"),Integer.parseInt(p.getProperty("FontStyle")),Integer.parseInt(p.getProperty("FontSize")));chatRecords.setFont(myfont);chatRecords.setForeground(new Color(Integer.parseInt(p.getProperty("foreColor"))));chatRecords.setBackground(new Color(Integer.parseInt(p.getProperty("backColor"))));}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void closing(){this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {if(isConnect == true){try {dos.writeUTF(userName.getText()+" 离开了聊天室");dis.close();dos.close();socket.close();ct.stop();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}Properties size = new Properties();size.setProperty("FontName", ChatRoomClientFrame.this.chatRecords.getFont().getFamily());size.setProperty("FontStyle", ChatRoomClientFrame.this.chatRecords.getFont().getStyle()+"");size.setProperty("FontSize", ChatRoomClientFrame.this.chatRecords.getFont().getSize()+"");size.setProperty("foreColor", ChatRoomClientFrame.this.chatRecords.getForeground().getRGB()+"");size.setProperty("backColor", ChatRoomClientFrame.this.chatRecords.getBackground().getRGB()+"");try {FileWriter fr = new FileWriter("src/FontClient.properties");size.store(fr, "FontClient Info");fr.close();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});}}服务器端界面:
package Test;import UI.ChatRoomServerFrame;public class ChatRoomServer {public static void main(String[] args) {new ChatRoomServerFrame().setVisible(true);}}服务器端实现:
package UI;import java.awt.BorderLayout;import java.awt.Color;import java.awt.FileDialog;import java.awt.Font;import java.awt.Image;import java.awt.Toolkit;import java.awt.TrayIcon.MessageType;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.net.BindException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.Properties;import java.util.Vector;import javax.swing.JButton;import javax.swing.JColorChooser;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JSplitPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.border.TitledBorder;import javax.swing.event.AncestorEvent;import javax.swing.event.AncestorListener;public class ChatRoomServerFrame extends JFrame{/** * */private static final long serialVersionUID = -6582389471265865971L;private JPanel panel;private JPanel northPanel;private JPanel southPanel;private JTextField IP;private JTextField port;private JTextArea userlist;private JTextArea chatRecords;private JScrollPane leftPanel;private JScrollPane rightPanel;private JSplitPane centerPanel;private JTextField message;private JButton start;private JButton stop;private JButton send;private JPanel Jpanel;private JMenuBar bar;private JMenu file;private JMenuItem save;private JMenu format;private JMenuItem font;private JMenuItem foreGround;private JMenuItem backGround;private Font myfont;private Vector<Socket> lists=new Vector<Socket>(); private ServerSocket serverSocket;private ServerThread st;private DataOutputStream dos;private DataInputStream dis;private ArrayList<String> users = new ArrayList<String>();private int usersLength = 0;private UserList ul;private String usermessage=null;private boolean isStart = false;public ChatRoomServerFrame(){initServer();start.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {if(port.getText().trim().equals("")){JOptionPane.showMessageDialog(null, "端口号不能为空","错误",JOptionPane.ERROR_MESSAGE);return;}if(isStart==false){serverSocket = new ServerSocket(Integer.parseInt(port.getText()));chatRecords.append("\n");chatRecords.append("服务器已开启");st = new ServerThread(serverSocket);st.start();port.setEditable(false);start.setEnabled(false);stop.setEnabled(true);isStart = true;ul = new UserList();ul.start();}} catch (NumberFormatException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});stop.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {chatRecords.append("\n");chatRecords.append("服务器已断开");chatRecords.setCaretPosition(chatRecords.getDocument().getLength());if(dis != null){dis.close();}if(dos != null){dos.close();}users.removeAll(users);userlist.setText("");usersLength=0;serverSocket.close();port.setEditable(true);start.setEnabled(true);stop.setEnabled(false);isStart = false;ul.stop();st.stop();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});send.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(lists.size()==0){JOptionPane.showMessageDialog(null, "当前没有用户在线","错误",JOptionPane.ERROR_MESSAGE);return;}if(message.getText().trim().equals("")){JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);return;}String line="服务器:"+message.getText();sendMessage(line);message.setText("");}});message.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(lists.size()==0){JOptionPane.showMessageDialog(null, "当前没有用户在线","错误",JOptionPane.ERROR_MESSAGE);return;}if(message.getText().trim().equals("")){JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.ERROR_MESSAGE);return;}String line="服务器:"+message.getText();sendMessage(line);message.setText("");}});font.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {MyFontChooser mf = new MyFontChooser(chatRecords.getFont()); int returnValue = mf.showFontDialog(ChatRoomServerFrame.this); // 如果按下的是确定按钮 if (returnValue == MyFontChooser.APPROVE_OPTION) { // 获取选择的字体 Font font = mf.getSelectFont(); // 将字体设置到JTextArea中 chatRecords.setFont(font); }}});save.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {FileDialog saveFile = new FileDialog(ChatRoomServerFrame.this, "保存文件...", FileDialog.SAVE);saveFile.setVisible(true);String filePath = saveFile.getDirectory() + saveFile.getFile();try {FileOutputStream fos = new FileOutputStream(filePath);fos.write(chatRecords.getText().getBytes());fos.close();} catch (FileNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});backGround.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Color bc = JColorChooser.showDialog(ChatRoomServerFrame.this, "选择颜色", Color.BLACK);chatRecords.setBackground(bc);}});foreGround.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Color fc = JColorChooser.showDialog(ChatRoomServerFrame.this, "选择颜色", Color.BLACK);chatRecords.setForeground(fc);}});initFrame();}private void initServer() {Jpanel = new JPanel();Jpanel.setLayout(new BorderLayout());panel = new JPanel();panel.setLayout(new BorderLayout());northPanel = new JPanel();northPanel.setBorder(new TitledBorder("配置信息"));IP = new JTextField(15);String ipAddress = null;try {ipAddress = InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();}IP.setText(ipAddress);IP.setEditable(false);port = new JTextField(15);port.setText("8088");start = new JButton("启动");stop = new JButton("停止");stop.setEnabled(false);northPanel.add(new JLabel("本地地址"));northPanel.add(IP);northPanel.add(new JLabel("端口号"));northPanel.add(port);northPanel.add(start);northPanel.add(stop);bar = new JMenuBar();file = new JMenu("记录");save = new JMenuItem("保存");format = new JMenu("格式");font = new JMenuItem("字体");foreGround = new JMenuItem("前景色");backGround = new JMenuItem("背景色");file.add(save);format.add(font);format.add(foreGround);format.add(backGround);bar.add(file);bar.add(format);Jpanel.add(bar,BorderLayout.NORTH);panel.add(northPanel,BorderLayout.NORTH);userlist = new JTextArea();userlist.setEditable(false);leftPanel =new JScrollPane(userlist);leftPanel.setBorder(new TitledBorder("在线用户"));panel.add(leftPanel,BorderLayout.EAST);chatRecords = new JTextArea();chatRecords.setEditable(false);rightPanel =new JScrollPane(chatRecords);rightPanel.setBorder(new TitledBorder("聊天信息"));centerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel); centerPanel.setDividerLocation(100); panel.add(centerPanel,BorderLayout.CENTER);southPanel = new JPanel();southPanel.setBorder(new TitledBorder("写消息"));message = new JTextField(50);send = new JButton("发送");southPanel.add(message);southPanel.add(send);panel.add(southPanel, BorderLayout.SOUTH);Jpanel.add(panel, BorderLayout.CENTER);this.add(Jpanel);}private void initFrame(){this.setTitle("聊天室-服务器");this.setSize(640,480);this.setLocationRelativeTo(null);Toolkit kit = Toolkit.getDefaultToolkit();Image img = kit.getImage("img/logo.jpg");this.setIconImage(img);this.setResizable(false);opening();this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);closing();}private class MSThread implements Runnable{private Socket socket;private DataInputStream dis ;public MSThread(Socket socket) {try {this.socket = socket;dis = new DataInputStream(socket.getInputStream());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void run() {String message=null;try {while(true){message = dis.readUTF();if(message.contains("进入了聊天室")&&!message.contains(":"))users.add(message.split(" ")[0]);if(message.contains("离开了聊天室")&&!message.contains(":")){users.remove(message.split(" ")[0]);sendMessage(message);dis.close();socket.close();lists.remove(socket);}else{sendMessage(message);}}} catch (IOException e) {lists.remove(socket);e.printStackTrace();}}}public void sendMessage(String str){try {for(int i=0;i<lists.size();i++){dos = new DataOutputStream(lists.get(i).getOutputStream());dos.writeUTF(str);} }catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(str);chatRecords.append("\n");chatRecords.append(str);chatRecords.setCaretPosition(chatRecords.getDocument().getLength());}public void sendUserMessage(String str){try {for(int i=0;i<lists.size();i++){dos = new DataOutputStream(lists.get(i).getOutputStream());dos.writeUTF(str);} }catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}private class ServerThread extends Thread{private ServerSocket serverSocket;public ServerThread(ServerSocket serverSocket){this.serverSocket = serverSocket;}@Overridepublic void run() {while(true){Socket soket=null;try {soket=serverSocket.accept();new Thread(new MSThread(soket)).start();lists.add(soket);} catch (IOException e) {e.printStackTrace();}}}}public void opening(){Properties p = new Properties();try {if(new File("src/FontServer.properties").exists()){p.load(new FileReader("src/FontServer.properties"));myfont = new Font(p.getProperty("FontName"),Integer.parseInt(p.getProperty("FontStyle")),Integer.parseInt(p.getProperty("FontSize")));chatRecords.setFont(myfont);chatRecords.setForeground(new Color(Integer.parseInt(p.getProperty("foreColor"))));chatRecords.setBackground(new Color(Integer.parseInt(p.getProperty("backColor"))));}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void closing(){this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {Properties size = new Properties();size.setProperty("FontName", ChatRoomServerFrame.this.chatRecords.getFont().getFamily());size.setProperty("FontStyle", ChatRoomServerFrame.this.chatRecords.getFont().getStyle()+"");size.setProperty("FontSize", ChatRoomServerFrame.this.chatRecords.getFont().getSize()+"");size.setProperty("foreColor", ChatRoomServerFrame.this.chatRecords.getForeground().getRGB()+"");size.setProperty("backColor", ChatRoomServerFrame.this.chatRecords.getBackground().getRGB()+"");try {FileWriter fr = new FileWriter("src/FontServer.properties");size.store(fr, "FontServer Info");fr.close();if(isStart == true){if(dis != null){dis.close();}if(dos != null){ dos.close();}serverSocket.close();ul.stop();st.stop();}} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}});}public class UserList extends Thread{@Overridepublic void run() {while(true){if(users.size()!=usersLength){userlist.setText("");usermessage="";for(String s : users){ userlist.append(s); userlist.append("\n"); usermessage=usermessage+s+" ";}usersLength = users.size();sendUserMessage(usermessage+"@在线用户列表@");}}}}}字体选择器:
package UI;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.Font;import java.awt.GraphicsEnvironment;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.FocusEvent;import java.awt.event.FocusListener;import javax.swing.BorderFactory;import javax.swing.Box;import javax.swing.ButtonGroup;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JRadioButton;import javax.swing.JScrollPane;import javax.swing.JTextField;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import javax.swing.text.AttributeSet;import javax.swing.text.BadLocationException;import javax.swing.text.Document;import javax.swing.text.PlainDocument;public class MyFontChooser extends JDialog {/** * */private static final long serialVersionUID = 7329415273324558584L;/** * 选择取消按钮的返回值 */ public static final int CANCEL_OPTION = 0; /** * 选择确定按钮的返回值 */ public static final int APPROVE_OPTION = 1; /** * 中文预览的字符串 */ private static final String CHINA_STRING = "神马都是浮云!"; /** * 英文预览的字符串 */ private static final String ENGLISH_STRING = "Hello Kitty!"; /** * 数字预览的字符串 */ private static final String NUMBER_STRING = "0123456789"; // 预设字体,也是将来要返回的字体 private Font font = null; // 字体选择器组件容器 private Box box = null; // 字体文本框 private JTextField fontText = null; // 样式文本框 private JTextField styleText = null; // 文字大小文本框 private JTextField sizeText = null; // 预览文本框 private JTextField previewText = null; // 中文预览 private JRadioButton chinaButton = null; // 英文预览 private JRadioButton englishButton = null; // 数字预览 private JRadioButton numberButton = null; // 字体选择框 private JList fontList = null; // 样式选择器 private JList styleList = null; // 文字大小选择器 private JList sizeList = null; // 确定按钮 private JButton approveButton = null; // 取消按钮 private JButton cancelButton = null; // 所有字体 private String [] fontArray = null; // 所有样式 private String [] styleArray = {"常规", "粗体", "斜体", "粗斜体"}; // 所有预设字体大小 private String [] sizeArray = {"8", "9", "10", "11", "12", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "初号", "小初", "一号", "小一", "二号", "小二", "三号", "小三", "四号", "小四", "五号", "小五", "六号", "小六", "七号", "八号"}; // 上面数组中对应的字体大小 private int [] sizeIntArray = {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 42, 36, 26, 24, 22, 18, 16, 15, 14, 12, 10, 9, 8, 7, 6, 5}; // 返回的数值,默认取消 private int returnValue = CANCEL_OPTION; /** * 体构造一个字体选择器 */ public MyFontChooser(Font font){setTitle("字体选择器"); this.font = font; // 初始化UI组件 init(); // 添加监听器 addListener(); // 按照预设字体显示 setup(); // 基本设置 setModal(true); setResizable(false); // 自适应大小 pack(); } /** * 初始化组件 */ private void init(){ // 获得系统字体 GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment(); fontArray = eq.getAvailableFontFamilyNames(); // 主容器 box = Box.createVerticalBox(); box.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); fontText = new JTextField(); fontText.setEditable(false); fontText.setBackground(Color.WHITE); styleText = new JTextField(); styleText.setEditable(false); styleText.setBackground(Color.WHITE); sizeText = new JTextField("12"); // 给文字大小文本框使用的Document文档,制定了一些输入字符的规则 Document doc = new PlainDocument(){ public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (str == null) { return; } if (getLength() >= 3) { return; } if (!str.matches("[0-9]+") && !str.equals("初号") && !str.equals("小初") && !str.equals("一号") && !str.equals("小一") && !str.equals("二号") && !str.equals("小二") && !str.equals("三号") && !str.equals("小三") && !str.equals("四号") && !str.equals("小四") && !str.equals("五号") && !str.equals("小五") && !str.equals("六号") && !str.equals("小六") && !str.equals("七号") && !str.equals("八号")) { return; } super.insertString(offs, str, a); sizeList.setSelectedValue(sizeText.getText(), true); } }; sizeText.setDocument(doc); previewText = new JTextField(20); previewText.setHorizontalAlignment(JTextField.CENTER); previewText.setEditable(false); previewText.setBackground(Color.WHITE); chinaButton = new JRadioButton("中文预览", true); englishButton = new JRadioButton("英文预览"); numberButton = new JRadioButton("数字预览"); ButtonGroup bg = new ButtonGroup(); bg.add(chinaButton); bg.add(englishButton); bg.add(numberButton); fontList = new JList(fontArray); styleList = new JList(styleArray); sizeList = new JList(sizeArray); approveButton = new JButton("确定"); cancelButton = new JButton("取消"); Box box1 = Box.createHorizontalBox(); JLabel l1 = new JLabel("字体:"); JLabel l2 = new JLabel("字形:"); JLabel l3 = new JLabel("大小:"); l1.setPreferredSize(new Dimension(165, 14)); l1.setMaximumSize(new Dimension(165, 14)); l1.setMinimumSize(new Dimension(165, 14)); l2.setPreferredSize(new Dimension(95, 14)); l2.setMaximumSize(new Dimension(95, 14)); l2.setMinimumSize(new Dimension(95, 14)); l3.setPreferredSize(new Dimension(80, 14)); l3.setMaximumSize(new Dimension(80, 14)); l3.setMinimumSize(new Dimension(80, 14)); box1.add(l1); box1.add(l2); box1.add(l3); Box box2 = Box.createHorizontalBox(); fontText.setPreferredSize(new Dimension(160, 25)); fontText.setMaximumSize(new Dimension(160, 25)); fontText.setMinimumSize(new Dimension(160, 25)); box2.add(fontText); box2.add(Box.createHorizontalStrut(5)); styleText.setPreferredSize(new Dimension(90, 25)); styleText.setMaximumSize(new Dimension(90, 25)); styleText.setMinimumSize(new Dimension(90, 25)); box2.add(styleText); box2.add(Box.createHorizontalStrut(5)); sizeText.setPreferredSize(new Dimension(80, 25)); sizeText.setMaximumSize(new Dimension(80, 25)); sizeText.setMinimumSize(new Dimension(80, 25)); box2.add(sizeText); Box box3 = Box.createHorizontalBox(); JScrollPane sp1 = new JScrollPane(fontList); sp1.setPreferredSize(new Dimension(160, 100)); sp1.setMaximumSize(new Dimension(160, 100)); sp1.setMaximumSize(new Dimension(160, 100)); box3.add(sp1); box3.add(Box.createHorizontalStrut(5)); JScrollPane sp2 = new JScrollPane(styleList); sp2.setPreferredSize(new Dimension(90, 100)); sp2.setMaximumSize(new Dimension(90, 100)); sp2.setMinimumSize(new Dimension(90, 100)); box3.add(sp2); box3.add(Box.createHorizontalStrut(5)); JScrollPane sp3 = new JScrollPane(sizeList); sp3.setPreferredSize(new Dimension(80, 100)); sp3.setMaximumSize(new Dimension(80, 100)); sp3.setMinimumSize(new Dimension(80, 100)); box3.add(sp3); Box box4 = Box.createHorizontalBox(); Box box5 = Box.createVerticalBox(); JPanel box6 = new JPanel(new BorderLayout()); box5.setBorder(BorderFactory.createTitledBorder("字符集")); box6.setBorder(BorderFactory.createTitledBorder("示例")); box5.add(chinaButton); box5.add(englishButton); box5.add(numberButton); box5.setPreferredSize(new Dimension(90, 95)); box5.setMaximumSize(new Dimension(90, 95)); box5.setMinimumSize(new Dimension(90, 95)); box6.add(previewText); box6.setPreferredSize(new Dimension(250, 95)); box6.setMaximumSize(new Dimension(250, 95)); box6.setMinimumSize(new Dimension(250, 95)); box4.add(box5); box4.add(Box.createHorizontalStrut(4)); box4.add(box6); Box box7 = Box.createHorizontalBox(); box7.add(Box.createHorizontalGlue()); box7.add(approveButton); box7.add(Box.createHorizontalStrut(5)); box7.add(cancelButton); box.add(box1); box.add(box2); box.add(box3); box.add(Box.createVerticalStrut(5)); box.add(box4); box.add(Box.createVerticalStrut(5)); box.add(box7); getContentPane().add(box); } /** * 按照预设字体显示 */ private void setup() { String fontName = font.getFamily(); int fontStyle = font.getStyle(); int fontSize = font.getSize(); /* * 如果预设的文字大小在选择列表中,则通过选择该列表中的某项进行设值,否则直接将预设文字大小写入文本框 */ boolean b = false; for (int i = 0; i < sizeArray.length; i++) { if (sizeArray[i].equals(String.valueOf(fontSize))) { b = true; break; } } if(b){ // 选择文字大小列表中的某项 sizeList.setSelectedValue(String.valueOf(fontSize), true); }else{ sizeText.setText(String.valueOf(fontSize)); } // 选择字体列表中的某项 fontList.setSelectedValue(fontName, true); // 选择样式列表中的某项 styleList.setSelectedIndex(fontStyle); // 预览默认显示中文字符 chinaButton.doClick(); // 显示预览 setPreview(); } /** * 添加所需的事件监听器 */ private void addListener() { sizeText.addFocusListener(new FocusListener() { public void focusLost(FocusEvent e) { setPreview(); } public void focusGained(FocusEvent e) { sizeText.selectAll(); } }); // 字体列表发生选择事件的监听器 fontList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { fontText.setText(String.valueOf(fontList.getSelectedValue())); // 设置预览 setPreview(); } } }); styleList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { styleText.setText(String.valueOf(styleList.getSelectedValue())); // 设置预览 setPreview(); } } }); sizeList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { if(!sizeText.isFocusOwner()){ sizeText.setText(String.valueOf(sizeList.getSelectedValue())); } // 设置预览 setPreview(); } } }); // 编码监听器 EncodeAction ea = new EncodeAction(); chinaButton.addActionListener(ea); englishButton.addActionListener(ea); numberButton.addActionListener(ea); // 确定按钮的事件监听 approveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 组合字体 font = groupFont(); // 设置返回值 returnValue = APPROVE_OPTION; // 关闭窗口 disposeDialog(); } }); // 取消按钮事件监听 cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { disposeDialog(); } }); } /** * 显示字体选择器 * @param owner 上层所有者 * @return 该整形返回值表示用户点击了字体选择器的确定按钮或取消按钮,参考本类常量字段APPROVE_OPTION和CANCEL_OPTION */ public final int showFontDialog(JFrame owner) { setLocationRelativeTo(owner); setVisible(true); return returnValue; } /** * 返回选择的字体对象 * @return 字体对象 */ public final Font getSelectFont() { return font; } /** * 关闭窗口 */ private void disposeDialog() { MyFontChooser.this.removeAll(); MyFontChooser.this.dispose(); } /** * 显示错误消息 * @param errorMessage 错误消息 */ private void showErrorDialog(String errorMessage) { JOptionPane.showMessageDialog(this, errorMessage, "错误", JOptionPane.ERROR_MESSAGE); } /** * 设置预览 */ private void setPreview() { Font f = groupFont(); previewText.setFont(f); } /** * 按照选择组合字体 * @return 字体 */ private Font groupFont() { String fontName = fontText.getText(); int fontStyle = styleList.getSelectedIndex(); String sizeStr = sizeText.getText().trim(); // 如果没有输入 if(sizeStr.length() == 0) { showErrorDialog("字体(大小)必须是有效“数值!"); return null; } int fontSize = 0; // 通过循环对比文字大小输入是否在现有列表内 for (int i = 0; i < sizeArray.length; i++) { if(sizeStr.equals(sizeArray[i])){ fontSize = sizeIntArray[i]; break; } } // 没有在列表内 if (fontSize == 0) { try{ fontSize = Integer.parseInt(sizeStr); if(fontSize < 1){ showErrorDialog("字体(大小)必须是有效“数值”!"); return null; } }catch (NumberFormatException nfe) { showErrorDialog("字体(大小)必须是有效“数值”!"); return null; } } return new Font(fontName, fontStyle, fontSize); } /** * 编码选择事件的监听动作 * @author 米强 * */ class EncodeAction implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource().equals(chinaButton)) { previewText.setText(CHINA_STRING); } else if (e.getSource().equals(englishButton)) { previewText.setText(ENGLISH_STRING); } else { previewText.setText(NUMBER_STRING); } } } }
阅读全文
0 0
- 使用java swing和socket编程实现简单的多人聊天室
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- Java使用socket网络编程实现多人聊天室
- Java使用socket网络编程实现多人聊天室
- socket实现简单的多人聊天室
- 使用socket.io编程的简单聊天室
- java简单Socket聊天室程序的实现
- socket编程:简单的多客户端聊天室
- java Socket实现简单聊天室
- java socket编程实现简单聊天室功能 单线程执行
- 使用node.js和socket.io实现多人聊天室
- JAVA通过Swing和socket编程实现简易点对点聊天
- Socket实现简单聊天室
- 使用JAVA swing实现简单的记事本
- Java编程:Socket聊天室
- 体验新玩法,iOS 11 for iPad.
- 局部二值模式(LBP)理论学习与算法实现
- POJ 3974 Palindrome
- SpringMVC是如何让Controler替代Servlet工作的
- python tensorflow学习笔记(三)运算
- 使用java swing和socket编程实现简单的多人聊天室
- spring data jpa将@ManyToOne查询从cross join变成left outer join
- oracle 之 控制oracle RAC 进行并行运算
- 不定根最小树形图 Ice_cream’s world II HDU
- SuperSocket基础二
- 个人赛2 简单思维
- 三千记之知识备忘
- Tomcat7开启SSI功能
- python条件语句