3
回答
Java Swing图形组件无端影响父容器以及与父容器同一级别的其他组件显示状态(使其不显示),求帮忙找出问题在哪儿,谢谢!

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

界面结构大概是这样的:一个 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也不会显示。效果如图:

以下是代码:
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;
 
  /**
   * 构造方法
   * <p>生成一个用户头像面板
   * @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();
  }
}



效果图:


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);



面板可以正常显示:


但是把这一行改成

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



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

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

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


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


举报
第七感
发帖于2年前 3回/253阅
共有3个答案 最后回答: 2年前

PictureIconPanel.publicvoidpaintComponent(Graphics g) {} 有问题.

如果是绘制图片的话,就不要在 JLabel pictureLabel =newJLabel();布局到这个Panel上,应该直接才用绘制的方式绘制这个图片.


ImagePanel 
===========>
package com.catalogic.swing;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;

/**
 * 
 * @author Catalogic
 * 
 */
public class ImagePanel extends JComponent {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private BufferedImage image = null;
	private int key;

	public ImagePanel(int key) {
		this.key = key;
		loadImage();
	}

	public void loadImage() {
		image = SwingToolkit.createBufferedImage(key);
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
		g2.dispose();
	

	}

	@Override
	public Dimension getPreferredSize() {
		if (image != null) {
			Dimension preferredSize = new Dimension(image.getWidth(), image.getHeight());
			return preferredSize;
		} else {
			return super.getPreferredSize();
		}

	}
}


SwingToolkit.createBufferedImage(key);
============>

/**
	 * 
	 * @param key
	 * @return
	 */
	public static BufferedImage createBufferedImage(int key) {
		BufferedImage image = null;
		String path = MR.getString(key);
		if (!StringUtils.isEmpty(path)) {
			if (!path.startsWith(Constants.IMG_FOLDER)) {
				path = Constants.IMG_FOLDER + path;
			}
		}
		URL imgURL = BMR01_SnapInfo.class.getClass().getResource(path);
		if (imgURL != null) {
			try {
				image = GraphicsUtilities.loadCompatibleImage(imgURL);

			} catch (IOException e) {
				System.out.println(" issue with path " + path);
				e.printStackTrace();
			}
		} else {
			System.out.println(" issue with path " + path);
		}

		return image;
	}

	/**
	 * 
	 * @param path
	 * @return
	 */
	public static ImageIcon createImageIcon(int key) {

		String path = MR.getString(key);
		if (!StringUtils.isEmpty(path)) {
			if (!path.startsWith(Constants.IMG_FOLDER)) {
				path = Constants.IMG_FOLDER + path;
			}
		}

		URL imgURL = com.catalogic.gui.BMR01_SnapInfo.class.getClass().getResource(path);
		if (imgURL != null) {
			ImageIcon imageIcon = new ImageIcon(imgURL, path);
			return imageIcon;

		} else {
			System.out.println(" issue with path " + path);
		}
		return null;

	}


GraphicsUtilities.java
=================>
package com.catalogic.swing;

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Graphics;
import java.awt.Transparency;
import java.net.URL;
import java.io.IOException;
import java.io.InputStream;

public class GraphicsUtilities {
    public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
        BufferedImage image = ImageIO.read(resource);
        return toCompatibleImage(image);
    }

    public static BufferedImage loadCompatibleImage(InputStream stream) throws IOException {
        BufferedImage image = ImageIO.read(stream);
        return toCompatibleImage(image);
    }

    public static BufferedImage createCompatibleImage(int width, int height) {
        return getGraphicsConfiguration().createCompatibleImage(width, height);
    }

    public static BufferedImage toCompatibleImage(BufferedImage image) {
        if (isHeadless()) {
            return image;
        }

        if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
            return image;
        }

        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
                    image.getWidth(), image.getHeight(), image.getTransparency());
        Graphics g = compatibleImage.getGraphics();
        g.drawImage(image, 0, 0, null);
        g.dispose();

        return compatibleImage;
    }

    public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) {
        return getGraphicsConfiguration().createCompatibleImage(width, height,
                                                   image.getTransparency());
    }

    private static GraphicsConfiguration getGraphicsConfiguration() {
        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        return environment.getDefaultScreenDevice().getDefaultConfiguration();
    }

    private static boolean isHeadless() {
        return GraphicsEnvironment.isHeadless();
    }

    public static BufferedImage createTranslucentCompatibleImage(int width, int height) {
        return getGraphicsConfiguration().createCompatibleImage(width, height,
                Transparency.TRANSLUCENT);
    }

    public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
        if (w == 0 || h == 0) {
            return new int[0];
        }

        if (pixels == null) {
            pixels = new int[w * h];
        } else if (pixels.length < w * h) {
            throw new IllegalArgumentException("Pixels array must have a length >= w * h");
        }

        int imageType = img.getType();
        if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {
            Raster raster = img.getRaster();
            return (int[]) raster.getDataElements(x, y, w, h, pixels);
        }

        // Unmanages the image
        return img.getRGB(x, y, w, h, pixels, 0, w);
    }
}



 
顶部