做课设,想用Java仿一个微信页面出来。

0d54d1061ca9db2b801794ed12790305.png界面结构大概是这样的:一个 JFrame 中有左中右三个 JPanel,然后左边的 JPanel 中又添加了一个放头像的 PicturePanel。PicturePanel做的事情大概就是:如果 new PicturePanel(ImageIcon picture) 的参数为 ImageIcon ,就将 ImageIcon 作为头像 new 一个 JLabel 添加进 PicturePanel 中,如果 PicturePanel(null) 的参数为空,就调用 PicturePanel 的 PaintComponent() 方法绘制默认头像。

现在的问题是:我自己测试 PicturePanel 这个类好像是没问题的,图片和绘制图形都可以正常显示。在 JFrame 最左边的深色 JPanel(MenuPanel)中 new PicturePanel(null) 也可以正常显示绘制的默认头像,但是,一旦我在 JFrame 最左边的深色 JPanel(MenuPanel)中 new PicturePanel(ImageIcon picture) ,不仅图像显示不出来,JFrame中原先添加的三个JPanel也不会显示。效果如图:

0c75b41b0ccc9d8955fc586e1aaee71d.png以下是代码:

PicturePanel.java

package View.Icons;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.Rectangle;

import javax.swing.ImageIcon;

import javax.swing.JLabel;

import javax.swing.JPanel;

/**

* 绘制用户头像

* @date 2016/10/20

* @version 1.0

*/

public class PictureIconPanel extends JPanel {

private static final long serialVersionUID = 1L;

/**

* 用户头像 ImageIcon

*/

private ImageIcon picture = null;

/**

* 默认图片宽度

*/

private int pictureWidth = 37;

/**

* 默认图片高度

*/

private int pictureHeight = 37;

/**

* 构造方法

*

生成一个用户头像面板

* @param picture 用户头像

*/

public PictureIconPanel(ImageIcon picture) {

this.picture = picture;

this.setLayout(null);

this.setBounds(new Rectangle(this.pictureWidth, this.pictureHeight));

if (picture != null) {

// 如果 ImageIcon 不为空,将 ImageIcon 添加进 picturePanel 中

JLabel pictureLabel = new JLabel();

// 按照 pictureWidth 和 pictureHeight 进行等比缩放

picture.setImage(picture.getImage().getScaledInstance(this.pictureWidth, this.pictureHeight, Image.SCALE_DEFAULT));

pictureLabel.setIcon(picture);

pictureLabel.setBounds(new Rectangle(this.pictureWidth, this.pictureHeight));

this.add(pictureLabel);

}

}

/**

* 绘制指定宽高的头像面板

* @param width 面板宽度

* @param height 面板高度

* @param picture 头像

*/

public PictureIconPanel(int width, int height, ImageIcon picture) {

this.pictureWidth = width;

this.pictureHeight = height;

this.picture = picture;

this.setLayout(null);

this.setBounds(new Rectangle(pictureWidth, this.pictureHeight));

if (picture != null) {

// 如果 ImageIcon 不为空,将 ImageIcon 添加进 picturePanel 中

JLabel pictureLabel = new JLabel();

// 按照 pictureWidth 和 pictureHeight 进行等比缩放

picture.setImage(picture.getImage().getScaledInstance(this.pictureWidth, this.pictureHeight, Image.SCALE_DEFAULT));

pictureLabel.setIcon(picture);

pictureLabel.setBounds(new Rectangle(this.pictureWidth, this.pictureHeight));

this.add(pictureLabel);

}

}

/*

* (non-Javadoc)

* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)

* 如果图片参数为空,绘制默认头像

*/

public void paintComponent(Graphics g) {

super.paintComponent(g);

// 如果图片参数为空,绘制默认头像

if (this.picture == null) {

// 开始绘制头像

g.setColor(new Color(65, 65, 65));

g.fillOval((int)(10 / 37.0 * this.pictureWidth), 0, (int)(15 / 37.0 * this.pictureWidth), (int)(17 / 37.0 * this.pictureHeight));

g.fillRect((int)(15 / 37.0 * this.pictureWidth), (int)(15 / 37.0 * this.pictureHeight), (int)(5 / 37.0 * this.pictureWidth), (int)(5 / 37.0 * this.pictureHeight));

g.fillOval((int)(2 / 37.0 * this.pictureWidth), (int)(17 / 37.0 * this.pictureHeight), (int)(33 / 37.0 * this.pictureWidth), (int)(20 / 37.0 * this.pictureHeight));

// System.out.println("4654564654654");

}

}

}

Test.java   测试PicturePanel

package View;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import View.Icons.PictureIconPanel;

public class TEST{

public static void main(String[] args) {

JFrame frame = new JFrame("TEST");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(new PictureIconPanel(new ImageIcon("D:\\Coding\\Java\\workspace\\WeChat\\files\\pictures\\a.jpg")));

frame.pack();

frame.setVisible(true);

// new WeChatFrame();

}

}

效果图:

27f97e87ac450679e3f51476ba0d1b57.png

WeChatFrame.java   就是一个JFrame

package View;

import java.awt.event.MouseEvent;

/**

* 微信框架

*

* @date 2016年10月22日

* @version 1.0

*/

public class WeChatFrame extends MyFrame {

private static final long serialVersionUID = 1L;

/**

* 菜单面板

*/

private MenuPanel menuPanel;

/**

* 对话列表面板

*/

private DialogListPanel dialogListPanel;

/**

* 聊天面板

*/

private ChattingPanel chattingPanel;

public WeChatFrame() {

this.setLayout(null);

this.setMenuPanel();

this.setDialogListPanel();

this.setChattingPanel();

}

private void setMenuPanel() {

this.menuPanel = new MenuPanel();

this.menuPanel.setBounds(0, 0, 50, this.getHeight());

this.getContentPane().add(this.menuPanel);

}

private void setDialogListPanel() {

this.dialogListPanel = new DialogListPanel();

this.dialogListPanel.setBounds(50, 0, 249, this.getHeight());

this.getContentPane().add(this.dialogListPanel);

}

private void setChattingPanel() {

this.chattingPanel = new ChattingPanel();

this.chattingPanel.setBounds(299, 0, this.getWidth() - 299, this.getHeight());

this.getContentPane().add(this.chattingPanel);

}

/**

* 重新设置组件的大小以及位置

*/

private void resetElementLocation() {

// 设置 menuPanel 的大小及位置

this.menuPanel.setBounds(0, 0, 50, this.getHeight());

// 设置 dialogPanel 的大小及位置

this.dialogListPanel.setBounds(50, 0, 249, this.getHeight());

// 设置 chattingPanel 的大小及位置

this.chattingPanel.setBounds(299, 0, this.getWidth() - 299, this.getHeight());

}

/*

* (non-Javadoc)

*

* @see View.MyFrame#mouseClicked(java.awt.event.MouseEvent) 重写 MyFrame 中的

* mouseClicked 方法

*/

public void mouseClicked(MouseEvent event) {

super.mouseClicked(event);

this.resetElementLocation();

}

}

MenuPanel.java  最左边的JPanel

package View;

import java.awt.Color;

import javax.swing.ImageIcon;

import javax.swing.JPanel;

import View.Icons.MessageIconPanel;

import View.Icons.PictureIconPanel;

/**

* 菜单面板

*

* @author Seven <903481591@qq.com>

* @date 2016年10月22日

* @version 1.0

*/

public class MenuPanel extends JPanel {

private static final long serialVersionUID = 1L;

private PictureIconPanel pictureIconPanel;

private MessageIconPanel messageIconPanel;

public MenuPanel() {

this.setBackground(new Color(62, 62, 64));

this.setLayout(null);

this.setPictureIconPanel(new ImageIcon("D:\\Coding\\Java\\workspace\\WeChat\\files\\pictures\\a.jpg"));

}

public void setPictureIconPanel(ImageIcon picture) {

this.pictureIconPanel = new PictureIconPanel(27, 27, picture);

this.pictureIconPanel.setBounds(11, 12, this.pictureIconPanel.getWidth(), this.pictureIconPanel.getHeight());

this.add(this.pictureIconPanel);

}

/**

* 设置消息图标面板

*/

public void setMessageIconPanel() {

}

}

Test.java  测试WeChatFrame

package View;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import View.Icons.PictureIconPanel;

public class TEST{

public static void main(String[] args) {

new WeChatFrame();

}

}

那么问题来了,、

如果 PicturePanel.java 中 第26行为

this.setPictureIconPanel(null);

面板可以正常显示:

0d54d1061ca9db2b801794ed12790305.png但是把这一行改成

this.setPictureIconPanel(new ImageIcon("D:\\Coding\\Java\\workspace\\WeChat\\files\\pictures\\a.jpg"));

WeChatFrame中的所有组件都会丢失。

0c75b41b0ccc9d8955fc586e1aaee71d.png

更神奇的是如果把窗口最小化再最大化,丢失的组件会自动出现。

在异常显示(也就是空白面板)上面截图,截完图之后丢失的组件也会神奇的再现。

求大神帮忙分析下原因,谢谢!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐