天天看點

JAVA字元串根據寬度(像素)換行問題

前言

在一些場景下,我們經常會通過判斷字元串的長度,比如個數來實作換行(這個具體實施,請參考String根據字數進行分隔,然後邏輯自己控制),但是中文、英文、數字、其實在展示的時候同樣長度的字元串,其實它的寬度是不一樣的,這也是們我通俗意義上說的寬度(像素)

1、根據像素寬度進行換行

需求:

/**
     * 10、自己做圖檔 ,根據文本寬度進行換行
     */
    @Test
    public void creatMyImage(){

        //整體圖合成
        BufferedImage bufferedImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
        //設定圖檔的背景色
        Graphics2D main = bufferedImage.createGraphics();
        main.fillRect(0, 0, 500, 500);

        String text = "111122223是以比傳統紙巾更環保3334441比傳統紙巾更環11111111111111122223是以比傳統紙巾更環保3334441比傳統紙巾更環11111111111111122223是以比傳統紙巾更環保3334441比傳統紙巾更環11111111111111122223是以比傳統紙巾更環保3334441比傳統紙巾更環11111111111";

        Graphics2D textG = bufferedImage.createGraphics() ;

        textG.setColor(new Color(37,37,37));
        Font hualaoContentFont = new Font("PingFang SC", Font.PLAIN, 20);
        textG.setFont(hualaoContentFont);
        textG.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        drawString(textG,text,30,100,4,10,50,true,false);

        //存儲到本地
        String saveFilePath = "/Users/healerjean/Desktop/new.png";
        saveImageToLocalDir(bufferedImage, saveFilePath);

    }


    /**
     *
     * @param g
     * @param text 文本
     * @param lineHeight 行高(注意字型大小的控制哦)
     * @param maxWidth 行寬
     * @param maxLine 最大行數
     * @param left 左邊距 //整段文字的左邊距
     * @param top 上邊距 //整頓文字的上邊距
     * @param trim 是否修剪文本(1、去除首尾空格,2、将多個換行符替換為一個)
     * @param lineIndent 是否首行縮進
     */
    public static void drawString(Graphics2D g, String text, float lineHeight, float maxWidth, int maxLine, float left,
                                  float top, boolean trim, boolean lineIndent) {
        if (text == null || text.length() == 0) return;
        if(trim) {
            text = text.replaceAll("\\n+", "\n").trim();
        }
        if(lineIndent) {
            text = "  " + text.replaceAll("\\n", "\n  ");
        }
        drawString(g, text, lineHeight, maxWidth, maxLine, left, top);
    }

    /**
     *
     * @param g
     * @param text 文本
     * @param lineHeight 行高
     * @param maxWidth 行寬
     * @param maxLine 最大行數
     * @param left 左邊距
     * @param top 上邊距
     */
    private static void drawString(Graphics2D g, String text, float lineHeight, float maxWidth, int maxLine, float left,
                                   float top) {
        if (text == null || text.length() == 0) return;

        FontMetrics fm = g.getFontMetrics();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            sb.append(c);
            int stringWidth = fm.stringWidth(sb.toString());
            if (c == '\n' || stringWidth > maxWidth) {
                if(c == '\n') {
                    i += 1;
                }
                if (maxLine > 1) {
                    g.drawString(text.substring(0, i), left, top);
                    drawString(g, text.substring(i), lineHeight, maxWidth, maxLine - 1, left, top + lineHeight);
                } else {
                    g.drawString(text.substring(0, i - 1) + "…", left, top);
                }
                return;
            }
        }
        g.drawString(text, left, top);
    }