package ui;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* 一个可以动态加载一个图片做背景的Jpanel
*/
public class floatPanel extends JPanel{
Image im;
//容器总宽度
private int width;
//容器总高度
private int height;
//图片宽度
private int imgW;
//图片高度
private int imgH;
//构造函数制定Jpanel的大小
private char[] charArr;
//图片与文字的间距
private int spacing;
//行间距
private int lineSpacing;
//绘图后溢出高度
private int overflow;
public floatPanel(Image im,int width,int height,int imgW,int imgH,String str,int spacing,int lineSpacing) {
this.im = im;
this.width=width;
this.height=height;
this.imgW=imgW;
this.imgH=imgH;
this.charArr=str.toCharArray();
this.spacing=spacing;
this.lineSpacing=lineSpacing;
this.setBounds(0, 0, this.width, this.height);
this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
//画出背景
@Override
protected void paintComponent(Graphics g) {
// 清屏
super.paintComponent(g);
//参数说明:
/*
第一个参数是要绘制的图片资源
第二、三个参数是绘制的起点x,y坐标
第四、五 个参数是绘制矩形的宽、高
最后一个参数是指定存放绘制内容的容器
*/
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(im, 0, 0, this.imgW, this.imgH, this);
//决定是否使用抗锯齿。当着色有倾斜角度的线时,通常会得到一组阶梯式的像素排列,使这条线看上去不平滑,经常被称为 锯齿状图形。
//抗锯齿是一种技术,它设置有倾斜角度的线的像素亮度,以使线看起来更平滑。
//因此,这个微调是用来决定在着色有倾斜角度的线时是否在减少锯齿状图形上花费时间。可能的值有 VALUE_ANTIALIAS_ON, _OFF 或 _DEFAULT。
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//设计字体显示效果 Font mf = new Font(String 字体,int 风格,int 字号);
//字体:TimesRoman, Courier, Arial等
//风格:三个常量 lFont.PLAIN, Font.BOLD, Font.ITALIC
//字号:字的大小(磅数)
//设置组件当前使用的字体:setFont(Font fn)
//获取组件当前使用的字体:getFont()
Font font = new Font("Serif", Font.PLAIN, 12);
g2.setFont(font);
FontMetrics fm = new JLabel().getFontMetrics(font);
//str - 要绘制的 string。
// x - x 坐标。
//y - y 坐标。
//g2.drawString("Text", 40, 120);
/*
Font f = new Font("宋体", Font.BOLD, 24);
FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(f);
//高度
System.out.println( fm.getHeight() );
//单个字符宽度
System.out.println( fm.charWidth( 'A' ));
//整个字符串的宽度
System.out.println( fm.stringWidth( "ABC" ));
*/
//获取右边区域能存储的文字的行数(向上取整后虽然是整数但是格式是"1.0"这样的,所以要用double存储)
double zg=this.imgH+this.spacing;
double dh=fm.getHeight();
double rRows=zg/dh;
System.out.println("总行:"+rRows);
//右边区域x的初始坐标
int rx=this.imgH+this.spacing;
//文字的初始y坐标
int texty=fm.getMaxAscent();
//右边区域行数计数器
double rRowsCount=1;
//获取字符高度
int charH=fm.getHeight();
for(int i=0;i<this.charArr.length;i++){
//当前字符的x坐标
int currentX=rx;
//当前y坐标
int currentY=texty;
//drawString是绘制字符串的所以要将每个字符以字符串的形式来绘制
//当前字符串
String currentText=String.valueOf(this.charArr[i]);
//绘制文字
g2.drawString(currentText,currentX,currentY);
System.out.println("当前字:"+currentText+"当前行:"+rRowsCount);
//更新右边区域的x坐标
//如果还存在下一个字符
if(i+1<charArr.length){
//下一个字符
String nextText=String.valueOf(this.charArr[i+1]);
//下一个字的宽度
int nextTextW=fm.stringWidth(nextText)*2;
//如果当前x坐标加上下个字符的宽度 大于整个容器的宽度
if(nextTextW+rx>this.width){
//如果右边当前行数小于右边最大存储行数则下个x的坐标重置到图片右边加上边距的位置
if(rRowsCount<=rRows){
rRowsCount++;
rx=this.imgW+this.spacing;
texty=(int)((rRowsCount-1)*(charH)+fm.getAscent());
if(rRowsCount==rRows+1 || texty>this.imgH+this.spacing){
rx=0;
}
}
//如果当前行数大于右边存储最大行数则下个x的坐标重置到整个容器的起始位置x坐标0处
else{
rRowsCount++;
rx=0;
texty=(int)((rRowsCount-1)*(charH)+fm.getAscent());
}
}
else{
//如果当前x坐标加上下个字符的宽度 小于整个容器的宽度则下个x坐标为当前x坐标加上当前字符宽度
rx=rx+fm.stringWidth(currentText);
}
}
}
//循环结束后计算整个绘图的溢出高度
this.overflow=texty-this.height;
System.out.println("溢出高度:"+this.overflow);
}
}