Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-调整字体大小以适应区域_Java_Fonts_Font Size - Fatal编程技术网

Java-调整字体大小以适应区域

Java-调整字体大小以适应区域,java,fonts,font-size,Java,Fonts,Font Size,多年来,我多次面临调整文本大小以适应JavaGUI上特定区域的问题。我的解决方案通常是通过以下方式解决该问题: 重新设计接口以避免问题 更改区域以适应文本的大小 对适合字符串的正确大小字体进行二进制搜索(当我无法执行前2项中的任何一项时) 最近,我在做另一个需要快速确定给定区域正确字体大小的项目时,我的二进制搜索方法太慢了(我怀疑是因为创建和测量字体的过程中需要动态内存分配),并在我的应用程序中引入了明显的延迟。我需要的是一种更快、更简单的方法来计算字体大小,以允许在GUI的定义区域内呈现给

多年来,我多次面临调整文本大小以适应JavaGUI上特定区域的问题。我的解决方案通常是通过以下方式解决该问题:

  • 重新设计接口以避免问题

  • 更改区域以适应文本的大小

  • 对适合字符串的正确大小字体进行二进制搜索(当我无法执行前2项中的任何一项时)


最近,我在做另一个需要快速确定给定区域正确字体大小的项目时,我的二进制搜索方法太慢了(我怀疑是因为创建和测量字体的过程中需要动态内存分配),并在我的应用程序中引入了明显的延迟。我需要的是一种更快、更简单的方法来计算字体大小,以允许在GUI的定义区域内呈现给定字符串。

最后,我想到了一种更简单、更快速的方法,在运行时只需要少量分配。这种新方法不需要任何类型的搜索,只需要进行一次测量,然而,它确实需要做出一个假设,一个对大多数应用完全合理的假设

  • 字体的宽度和高度必须与字体的点大小成比例。除了对渲染上下文执行的最模糊的转换之外,其他所有转换都会发生这种情况
使用这个假设,我们可以计算字体尺寸与点大小的比率,然后线性外推以找到给定区域所需的字体大小。下面是我为此编写的一些代码:

编辑: 初始测量的精度受基本字体大小的限制。使用一个非常小的字体大小作为基础可能会产生错误的结果。但基本字体的大小越大,线性近似值越精确

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;

public class FontUtilities
{   
    public static Font createFontToFit
    (
        String value,
        double width,
        double height,
        Font base,
        Graphics context
    )
    {
        double measuredWidth;
        double measuredHeight;
        double baseFontSize;
        FontMetrics ruler;
        Rectangle2D bounds;
        double heightBasedFontSize;
        double widthBasedFontSize;
        GlyphVector vector;
        Shape outline;

        if
        (
            (value == null) ||
            (base == null) ||
            (context == null) ||
            (width != width) ||
            (height != height)
        )
        {
            return null;
        }

        //measure the size of the string in the current font size
        baseFontSize = base.getSize2D();
        ruler = context.getFontMetrics(base);


        vector = base.createGlyphVector(ruler.getFontRenderContext(), value);

        //use the bounds measurement on the outline of the text since this is the only
        //measurement method that seems to be bug free and consistent in java
        outline = vector.getOutline(0, 0);
        bounds = outline.getBounds();

        measuredWidth = bounds.getWidth();
        measuredHeight = bounds.getHeight();

        //assume that each of the width and the height of the string
        //is proportional to the font size, calculate the ratio
        //and extrapolate linearly to determine the needed font size.
        //should have 2 font sizes one for matching the width, and one for
        //matching the height, return the least of the 2
        widthBasedFontSize = (baseFontSize*width)/measuredWidth;
        heightBasedFontSize = (baseFontSize*height)/measuredHeight;

        if(widthBasedFontSize < heightBasedFontSize)
        {
            return base.deriveFont(base.getStyle(), (float)widthBasedFontSize);
        }
        else
        {
            return base.deriveFont(base.getStyle(), (float)heightBasedFontSize);
        }
    }
}
导入java.awt.Font;
导入java.awt.FontMetrics;
导入java.awt.Graphics;
导入java.awt.Shape;
导入java.awt.font.GlyphVector;
导入java.awt.geom.Rectangle2D;
公用事业
{   
公共静态字体createFontToFit
(
字符串值,
双倍宽度,
双高,
字体库,
图形上下文
)
{
双测量宽度;
双测量高度;
双基尺寸;
方格尺;
矩形二维边界;
双高度基准字体;
基于双宽度的字体大小;
字形矢量;
外形轮廓;
如果
(
(值==null)||
(base==null)||
(上下文==null)||
(宽度!=宽度)||
(高度!=高度)
)
{
返回null;
}
//以当前字体大小测量字符串的大小
baseFontSize=base.getSize2D();
标尺=context.getFontMetrics(基本);
vector=base.createGlyphVector(标尺.getFontRenderContext(),值);
//使用文本轮廓上的边界测量,因为这是唯一
//java中似乎没有bug且一致的度量方法
outline=vector.getOutline(0,0);
bounds=outline.getBounds();
measuredWidth=bounds.getWidth();
measuredHeight=bounds.getHeight();
//假设字符串的宽度和高度
//与字体大小成比例,计算比例
//并线性外推以确定所需的字体大小。
//应该有两种字体大小,一种用于匹配宽度,另一种用于
//匹配高度,返回2个值中的最小值
widthBasedFontSize=(baseFontSize*宽度)/measuredWidth;
heightBasedFontSize=(baseFontSize*高度)/测量高度;
if(宽度基准字体大小<高度基准字体大小)
{
返回base.deriveFont(base.getStyle(),(float)widthBasedFontSize);
}
其他的
{
返回base.deriveFont(base.getStyle(),(float)heightBasedFontSize);
}
}
}

最后,我想到了一种更简单、更快的方法,在运行时只需要少量的分配。这种新方法不需要任何类型的搜索,只需要进行一次测量,然而,它确实需要做出一个假设,一个对大多数应用完全合理的假设

  • 字体的宽度和高度必须与字体的点大小成比例。除了对渲染上下文执行的最模糊的转换之外,其他所有转换都会发生这种情况
使用这个假设,我们可以计算字体尺寸与点大小的比率,然后线性外推以找到给定区域所需的字体大小。下面是我为此编写的一些代码:

编辑: 初始测量的精度受基本字体大小的限制。使用一个非常小的字体大小作为基础可能会产生错误的结果。但基本字体的大小越大,线性近似值越精确

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;

public class FontUtilities
{   
    public static Font createFontToFit
    (
        String value,
        double width,
        double height,
        Font base,
        Graphics context
    )
    {
        double measuredWidth;
        double measuredHeight;
        double baseFontSize;
        FontMetrics ruler;
        Rectangle2D bounds;
        double heightBasedFontSize;
        double widthBasedFontSize;
        GlyphVector vector;
        Shape outline;

        if
        (
            (value == null) ||
            (base == null) ||
            (context == null) ||
            (width != width) ||
            (height != height)
        )
        {
            return null;
        }

        //measure the size of the string in the current font size
        baseFontSize = base.getSize2D();
        ruler = context.getFontMetrics(base);


        vector = base.createGlyphVector(ruler.getFontRenderContext(), value);

        //use the bounds measurement on the outline of the text since this is the only
        //measurement method that seems to be bug free and consistent in java
        outline = vector.getOutline(0, 0);
        bounds = outline.getBounds();

        measuredWidth = bounds.getWidth();
        measuredHeight = bounds.getHeight();

        //assume that each of the width and the height of the string
        //is proportional to the font size, calculate the ratio
        //and extrapolate linearly to determine the needed font size.
        //should have 2 font sizes one for matching the width, and one for
        //matching the height, return the least of the 2
        widthBasedFontSize = (baseFontSize*width)/measuredWidth;
        heightBasedFontSize = (baseFontSize*height)/measuredHeight;

        if(widthBasedFontSize < heightBasedFontSize)
        {
            return base.deriveFont(base.getStyle(), (float)widthBasedFontSize);
        }
        else
        {
            return base.deriveFont(base.getStyle(), (float)heightBasedFontSize);
        }
    }
}
导入java.awt.Font;
导入java.awt.FontMetrics;
导入java.awt.Graphics;
导入java.awt.Shape;
导入java.awt.font.GlyphVector;
导入java.awt.geom.Rectangle2D;
公用事业
{   
公共静态字体createFontToFit
(
字符串值,
双倍宽度,
双高,
字体库,
图形上下文
)
{
双测量宽度;
双测量高度;
双基尺寸;
方格尺;
矩形二维边界;
双高度基准字体;
基于双宽度的字体大小;
字形矢量;
外形轮廓;
如果
(
(值==null)||
(base==null)||
(上下文==null)||
(宽度!=宽度)||
(