700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java仿QQ客户端(用JTree实现好友列表)

Java仿QQ客户端(用JTree实现好友列表)

时间:2021-12-01 16:00:21

相关推荐

Java仿QQ客户端(用JTree实现好友列表)

仿QQ客户端

当前效果登录界面好友列表界面

当前效果

登录界面

首先,为了达到美观的目的,需要添加一张背景图片,我采用的方法是将图片添加到JLabel上,再将JLabel添加到界面上,但这样会面临一个问题——界面上的其他组件会被遮挡(即使添加顺序在JLabel之后)寻找解决方法的过程中,我了解到JFrame有三层界面,分别是RootPane,LayeredPane,ContentPane。而我们可以将JLabel放置到中间层LayeredPane,并将ContentPane设置为透明(其他组件放置在ContentPane。除此之外,图片的大小一般与JLabel不同,这里将图片的尺寸修改为与JLabel尺寸相同。

//修改图片尺寸Image image = new ImageIcon("登录背景.jpg").getImage().getScaledInstance(450, 330, JFrame.DO_NOTHING_ON_CLOSE);JLabel background = new JLabel(new ImageIcon(image));//将背景标签放置在中间层frame.getLayeredPane().add(background, Integer.valueOf(Integer.MIN_VALUE));//frame为JFrame类的一个对象JPanel panel = (JPanel) frame.getContentPane();//将最上层设置透明panel.setOpaque(false);

另一方面,原有的边框也不太美观,我选择直接将它除去,与此同时,需要添加两个按钮来控制窗体的最小化和关闭(在监听方法内操作)。为了使按钮不影响背景图片的美观,对按钮也要进行一系列的操作。首先需要处理两张去除背景的png图片,使其只有最小化和关闭的符号(用PS将多余的部分除去,导出为png)如图:

这是在照片里打开的样子,将它设置为按钮的图片时周围的格子是不可见的,可见的只有中间的符号。

然后将它们分别设置为按钮的图片。接着我们需要将按钮原本具有的背景隐藏,只保留刚刚设置的图片。最后将它们添加到右上角,而这设置位置的操作涉及到了布局,JFrame有BorderLayout,和FlowLayout等布局设置,但我们需要自定义位置,因此我们将JFrame的布局设置为null。组件可使用setBounds(x,y,width,height)方法设置位置和大小。

JFrame frame = new JFrame();frame.setSize(450, 330);//设置不可改变大小frame.setResizable(false);//去边框frame.setUndecorated(true);frame.setLayout(null);JButton minimize = new JButton(new ImageIcon("最小化.png"));//将按钮设置透明minimize.setContentAreaFilled(false);//将按钮设置为无边框minimize.setBorderPainted(false);minimize.setBounds(390, 0, 30, 30);minimize.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {//最小化窗口frame.setExtendedState(1);}@Overridepublic void mouseEntered(MouseEvent e) {//鼠标移动到上面时使按钮呈现灰色minimize.setContentAreaFilled(true);minimize.setBackground(Color.GRAY);}@Overridepublic void mouseExited(MouseEvent e) {//鼠标移出时更改为原状态minimize.setContentAreaFilled(false);}});frame.add(minimize);JButton close = new JButton(new ImageIcon("关闭.png"));//将按钮设置透明close.setContentAreaFilled(false);//将按钮设置为无边框close.setBorderPainted(false);close.setBounds(420, 0, 30, 30);close.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {//关闭窗口System.exit(0);}@Overridepublic void mouseEntered(MouseEvent e) {//鼠标移动到上面时使按钮呈现红色close.setContentAreaFilled(true);close.setBackground(Color.RED);}@Overridepublic void mouseExited(MouseEvent e) {//鼠标移出时更改为原状态close.setContentAreaFilled(false);}});frame.add(close);

记住密码和自动登录使用JCheckBox实现。

JCheckBox auto_sign_in = new JCheckBox("自动登录");auto_sign_in.setBounds(135, 200, 80, 20);//设置透明,使文本部分多余的部分不会遮挡背景auto_sign_in.setOpaque(false);frame.add(auto_sign_in);JCheckBox remember = new JCheckBox("记住密码");remember.setBounds(240, 200, 80, 20);remember.setOpaque(false);frame.add(remember);

其他组件的设置相对简单,在此不一一介绍了。

好友列表界面

首先,背景图片的设置和窗体布局等在前面介绍过,此处不再赘述,现在需要考虑的是如何实现好友列表。在这里采用选项卡组件和滚动面板加上JTree来实现,最主要的问题便是这些组件的透明设置和JTree的个性化设置(外观和点击节点进行的操作)由于要进行JTree的个性化设置,我们需要对JTree的节点DefaultMutableTreeNode进行一些更改,可创建一个类继承DefaultMutableTreeNode并添加自己所需的方法。同时,通过重写JTree的渲染器来实现更改外观的显示。

具体设置请参考以下代码:

public class PeopleNode extends DefaultMutableTreeNode {private String kind;// 好友分类private String account;// 好友账号private String name; // 好友昵称private String says; // 好友个性签名private int head; // 好友头像(不同的数字对应不同的图片)private boolean OnLineState = false;// 在线状态public PeopleNode(String kind, String account, String name, String says, int head) {super(name + says);//文本框放置昵称和个性签名this.kind = kind;this.account = account;this.name = name;this.says = says;this.head = head;}public String getKind() {return kind;}public String getAccount() {return account;}public String getName() {return name;}public String getSays() {return says;}public ImageIcon getImageIcon() {if (OnLineState) {return switch (head) {case 0 -> new ImageIcon("库里.jpg");case 1 -> new ImageIcon("克莱.png");default -> null;};} else {return switch (head) {case 0 -> getGrayImage(new ImageIcon("库里.jpg"));case 1 -> getGrayImage(new ImageIcon("克莱.png"));default -> null;};}}public boolean getOnLineState() {return OnLineState;}//图片灰度化处理public ImageIcon getGrayImage(ImageIcon icon){int w=icon.getIconWidth();int h=icon.getIconHeight();BufferedImage buff=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);Graphics g=buff.getGraphics();g.drawImage(icon.getImage(),0,0,null);for (int i=0;i<w;i++){for(int j=0;j<h;j++){int red,green,blue;int pixel=buff.getRGB(i,j);red=(pixel>>16)&0xFF;green=(pixel>>8)&0xFF;blue=(pixel>>0)&0xFF;int sum=(red+green+blue)/3;g.setColor(new Color(sum,sum,sum));g.fillRect(i,j,1,1);}}return new ImageIcon(buff);}// 更改在线状态public void SetState(boolean OnLineState) {this.OnLineState = OnLineState;}}

// 默认节点DefaultMutableTreeNode root = new DefaultMutableTreeNode();DefaultMutableTreeNode friend = new DefaultMutableTreeNode("我的好友");DefaultMutableTreeNode stranger = new DefaultMutableTreeNode("陌生人");DefaultMutableTreeNode blacklist = new DefaultMutableTreeNode("黑名单");// 以根节点创建树JTree contacts_tree = new JTree(root);// 设置为点击一次展开contacts_tree.setToggleClickCount(1);// 将节点添加到根节点root.add(friend);root.add(stranger);root.add(blacklist);/*** PeopleNode为继承了DefaultMutableTreeNode的类,people_list为存放PeopleNode的列表,* 在进行登录操作后从服务器获取的信息后动态生成*/for (int i = 0; i < people_list.size(); i++) {PeopleNode node = people_list.get(i);if (node.getKind().equals("我的好友")) {friend.add(node);}else if(node.getKind().equals("陌生人")){stranger.add(node);}else if(node.getKind().equals("黑名单")){blacklist.add(node);}}// 隐藏根节点contacts_tree.setRootVisible(false);// 展开树(在根节点隐藏时,能看见子节点)contacts_tree.expandPath(new TreePath(root));// 设置透明contacts_tree.setOpaque(false);// 隐藏根柄contacts_tree.setShowsRootHandles(false);// 对各个节点进行个性化设置contacts_tree.setCellRenderer(new DefaultTreeCellRenderer() {// 收起和展开图片设置为三角形final ImageIcon icon1 = new ImageIcon("收起.png");final ImageIcon icon2 = new ImageIcon("展开.png");// 重写该方法public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,boolean leaf, int row, boolean hasFocus) {super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);//节点为展开时显示的图片if (!expanded) {setIcon(icon1);} else {setIcon(icon2);}String str = value.toString();if (!str.equals("我的好友") && !str.equals("黑名单") && !str.equals("陌生人")) {DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;PeopleNode people = (PeopleNode) node;// 根据不同的好友对象设置他们的头像setIcon(new ImageIcon(people.getImageIcon().getImage().getScaledInstance(60, 60,JFrame.DO_NOTHING_ON_CLOSE)));// 将好友的昵称字体设置得比类别更小setFont(new Font("宋体", Font.BOLD, 15));} else {setFont(new Font("宋体", Font.BOLD, 20));}// 设置未选中节点时背景色为白色且完全透明,0表示透明,255表示正常setBackgroundNonSelectionColor(new Color(255, 255, 255, 0));// 设置选中节点时背景色为白色,透明度改为100,来区分未选中状态setBackgroundSelectionColor(new Color(255, 255, 255, 100));return this;}});// 使节点能响应相应操作contacts_tree.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {Object node = contacts_tree.getLastSelectedPathComponent();String str = node.toString();if (!str.equals("我的好友") && !str.equals("黑名单") && !str.equals("陌生人") && e.getClickCount() == 2) {//点击两次好友,弹出对话框}}});// 设置选项卡透明(需放置在创建之前)UIManager.put("TabbedPane.contentOpaque", false);// 创建选项卡JTabbedPane tab = new JTabbedPane();// 将创建并进行个性化设置的树添加到滚动面板JScrollPane jsp = new JScrollPane(contacts_tree);// 将滚动面板设置透明jsp.getViewport().setOpaque(false);jsp.setOpaque(false);jsp.setName("联系人");// 显示滚动条jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);// 最后将滚动面板添加到选项卡中tab.add(jsp);

以上只涉及到对界面的设置,具体的通信功能还未完善,进行登录操作和创建好友列表界面都需要与服务器进行交互,这部分功能未在以上的代码给出。

以上基本是我在写这部分界面代码时遇到的问题以及解决办法,遇到这些问题时,我找了好久才找到了这些解决方案,因此希望这篇博客可以帮助到有需要的朋友。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。