我想实现QQ消息这种气泡框,然后我首先写了一个类 A ,包含JFrame,然后在JFrame中写了JPanel, 然后我又写了一个类 B 继承Jpanel,从类A向类B传递Jpanel和输入框中的信息,在B类中,我重写了paintComponent(Graphics g )这个方法,画了一个框,但是在调用类A时,无法显示,应该如何解决这个问题呢?
package chat;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FilenameFilter;
import java.net.Socket;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileView;
import message_show.Messageshow;
import toast.Toast;
import toast.ToastStatus;
public class ChatFrame extends JFrame {
private static final long serialVersionUID = -8945833334986986964L;
/**
* 服务器窗体宽度
*/
public static final Integer FRAME_WIDTH = 750;
/**
* 服务器窗体高度
*/
public static final Integer FRAME_HEIGHT = 800;
//接收框
public JPanel acceptPane;
Socket socket;
ChatFrame chatFrame;
private Color roverBorderColor = Color.gray;
public ChatFrame() {
chatFrame = this;
// this.socket = socket;
this.setTitle("我的电脑");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
//窗体不可扩大
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//获取屏幕
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = screenSize.width;
int height = screenSize.height;
//屏幕居中处理
setLocation((width-FRAME_WIDTH)/2, (height-FRAME_HEIGHT)/2);
//加载窗体的背景图片
ImageIcon imageIcon = new ImageIcon("src/image/beijing.jpg");
//创建一个标签并将图片添加进去
JLabel frameBg = new JLabel(imageIcon);
//设置图片的位置和大小
frameBg.setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);
this.add(frameBg);
// 接收框
acceptPane = new JPanel();
acceptPane.setLayout(null);
acceptPane.setOpaque(false);//设置透明
// acceptPane.setFont(new Font("宋体", 0, 16));
// 设置接收框滚动条
JScrollPane scoPaneOne = new JScrollPane(acceptPane);
scoPaneOne.setSize(750, 498);
// scoPaneOne.setBounds(0, 20, 750, 498);
//设置背景透明
scoPaneOne.setOpaque(false);
scoPaneOne.getViewport().setOpaque(false);
scoPaneOne.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frameBg.add(scoPaneOne);
//添加图片符号点击功能
//发送照片功能
JButton picbut=new JButton();
picbut.setBorder(null);
ImageIcon picIcon = new ImageIcon("src/image/picture.png");
picbut.setIcon(picIcon);
picbut.setBounds(20, 530, picIcon.getIconWidth(), picIcon.getIconHeight());
picbut.setContentAreaFilled(false);
picbut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e){
FileDialog fileDialog = new FileDialog(new JFrame(),"选择照片", FileDialog.LOAD);
fileDialog.setFile("*.jpg;*.png;*.jpeg;*.gif");
fileDialog.setDirectory("Home");
fileDialog.setMultipleMode(true); //实现多选
fileDialog.setVisible(true);
// String pathString = fileDialog.getDirectory() + fileDialog.getFile();
fileDialog.setMultipleMode(true); //实现多选
fileDialog.setVisible(true);
File[] picfile = fileDialog.getFiles();
String pathString = fileDialog.getDirectory();
System.out.println(picfile.length);
System.out.println(pathString);
}
});
frameBg.add(picbut);
//发送视频功能
JButton vdobut=new JButton();
vdobut.setBorder(null);
ImageIcon setIcon = new ImageIcon("src/image/vedio.png");
vdobut.setIcon(setIcon);
vdobut.setBounds(100, 530, setIcon.getIconWidth(), setIcon.getIconHeight());
vdobut.setContentAreaFilled(false);
vdobut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e){
JFileChooser vedioflc = new JFileChooser();
vedioflc.setToolTipText("选择视频");
FileNameExtensionFilter ff = new FileNameExtensionFilter("视频文件(mp4)", "mp4");
vedioflc.setFileFilter(ff);
vedioflc.showOpenDialog(null);
}
});
frameBg.add(vdobut);
//设置功能
JButton setbut=new JButton();
setbut.setBorder(null);
ImageIcon settIcon = new ImageIcon("src/image/setting.png");
setbut.setIcon(settIcon);
setbut.setBounds(180, 530, settIcon.getIconWidth(), settIcon.getIconHeight());
setbut.setContentAreaFilled(false);
setbut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e){
}
});
frameBg.add(setbut);
// 输入框
JTextPane sendPane = new JTextPane();
sendPane.setOpaque(false);
sendPane.setFont(new Font("宋体", 1, 20));
JScrollPane scoPane = new JScrollPane(sendPane);// 设置滚动条
scoPane.setBounds(0, 570, 750, 130);
scoPane.setOpaque(false);
scoPane.getViewport().setOpaque(false);
scoPane.setBorder(null);
frameBg.add(scoPane);
/*
* 发送按钮
*/
JButton send = new JButton("发 送");
send.setBounds(610, 720, 125, 25);
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String message=sendPane.getText();
new Messageshow(acceptPane,scoPaneOne,true,message);
}
});
frameBg.add(send);
setVisible(true);
}
public static void main(String[] args) {
new ChatFrame();
}
}
package message_show;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import entity.UColor;
public class Messageshow extends JPanel{
public static int nowHeight=5;
static final int maxWIDTH = 500;
static final int initHEIGHT = 65;
private static final Graphics Graphics = null;
ImageIcon comimage = new ImageIcon("src/image/computer.png");
JTextPane contentcontain = new JTextPane();
JPanel midpanel;
int height = initHEIGHT;
Messageshow Messageshow;
int realwidth;
boolean self;
Graphics g;
/*
* 将消息包装显示
*/
public Messageshow(JPanel chatpanel, JScrollPane jsp,boolean isself, String content) {
self = isself;
JLabel comheadlabel = new JLabel(comimage);
// this.setOpaque(false);
contentcontain.setFont(new Font("宋体", 1, 20)); //设置框内的字体
contentcontain.setOpaque(false);
contentcontain.setEditable(false);
SimpleAttributeSet set = new SimpleAttributeSet();
Document doc = contentcontain.getStyledDocument();
FontMetrics fm = contentcontain.getFontMetrics(contentcontain.getFont());// 得到JTextPane
int cnt = 0; // 的当前字体尺寸
int paneWidth = contentcontain.getWidth();// 面板的宽度
int fontheight = fm.getHeight();
int allmaxwidth = 0;
//将文本信息传入文本框
try {
for (int i = 0; i < content.length(); ++i) {
if (content.charAt(i) == '\n' || (cnt += fm.charWidth(content.charAt(i))) >= maxWIDTH) {// 当属出字符的宽度大于面板的宽度时换行,也就是达到JTextPane不会出现水平的滚动条
System.out.println(cnt);
allmaxwidth=Math.max(allmaxwidth, cnt);
cnt = 0;
doc.insertString(doc.getLength(), "\n", set);
height += fontheight;
continue;
}
doc.insertString(doc.getLength(), String.valueOf(content.charAt(i)), set);
}
if (height == initHEIGHT) {
realwidth = cnt + 5;
} else {
realwidth = allmaxwidth+5;
}
// 就是将JTextPane中的插入符的位置移动到文本的末端!
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
nowHeight += height + 5;
contentcontain.setDocument(doc);
//判断是谁发出
if (isself) {
comheadlabel.setBounds(655, nowHeight-50, comimage.getIconHeight(), comimage.getIconWidth());
contentcontain.setBounds(650 - realwidth - comimage.getIconHeight(), nowHeight-40, realwidth + 5, height - 25);
} else {
comheadlabel.setBounds(5, 5, comimage.getIconHeight(), comimage.getIconWidth());
contentcontain.setBounds(75, 20, realwidth + 5, height - 25);
}
chatpanel.setPreferredSize(new Dimension(500,nowHeight));
jsp.doLayout();
jsp.getViewport().setViewPosition(new Point(0, jsp.getVerticalScrollBar().getMaximum()));
chatpanel.add(comheadlabel);
chatpanel.add(contentcontain); //将文本消息和头像框添加至面板
chatpanel.updateUI();
chatpanel.revalidate();
chatpanel.repaint();
}
/*
* 制作消息框
*/
@Override
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
System.out.println("到这一步了");
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int xPoints[] = new int[3];
int yPoints[] = new int[3];
if (self) {
g2D.setColor(UColor.CharBubbleColor_blue);
g2D.fillRoundRect(760 - realwidth - comimage.getIconHeight() - 35 - 5, 20 - 5, realwidth + 5 + 5,
height - 25 + 5, 10, 10);
// 绘制圆角消息气泡边框
g2D.setColor(UColor.CharBubbleColor_blue);
g2D.drawRoundRect(760 - realwidth - comimage.getIconHeight() - 35 - 5, 20 - 5, realwidth + 5 + 5,
height - 25 + 5, 10, 10);
xPoints[0] = (760 - realwidth - comimage.getIconHeight() - 35 - 5) + (realwidth + 5 + 5);
yPoints[0] = 20;
xPoints[1] = xPoints[0] + 8;
yPoints[1] = 20;
xPoints[2] = xPoints[0];
yPoints[2] = 20 + 6;
g2D.setColor(UColor.CharBubbleColor_blue);
g2D.fillPolygon(xPoints, yPoints, 3);
g2D.setColor(UColor.CharBubbleColor_blue);
g2D.drawPolyline(xPoints, yPoints, 3);
g2D.setColor(UColor.CharBubbleColor_blue);
g2D.drawLine(xPoints[0], yPoints[0] + 1, xPoints[2], yPoints[2] - 1);
} else {
g2D.setColor(UColor.CharBubbleColor_orange);
g2D.fillRoundRect(75 - 5, 20 - 5, realwidth + 5 + 5, height - 25 + 5, 10, 10);
// 绘制圆角消息气泡边框
g2D.setColor(UColor.CharBubbleColor_orange);
g2D.drawRoundRect(75 - 5, 20 - 5, realwidth + 5 + 5, height - 25 + 5, 10, 10);
xPoints[0] = 75 - 5;
yPoints[0] = 20;
xPoints[1] = xPoints[0] - 8;
yPoints[1] = 20;
xPoints[2] = xPoints[0];
yPoints[2] = 20 + 6;
g2D.setColor(UColor.CharBubbleColor_orange);
g2D.fillPolygon(xPoints, yPoints, 3);
g2D.setColor(UColor.CharBubbleColor_orange);
g2D.drawPolyline(xPoints, yPoints, 3);
g2D.setColor(UColor.CharBubbleColor_orange);
g2D.drawLine(xPoints[0], yPoints[0] + 1, xPoints[2], yPoints[2] - 1);
}
}
/*
* 获取当时时间
*/
static String getTime() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return sdf.format(new Date());
}
}