जावा में एक स्ट्रिंग की प्रदर्शन चौड़ाई की गणना करें


91

जावा में एक स्ट्रिंग की लंबाई (पिक्सेल में) की गणना कैसे करें?

स्विंग के उपयोग के बिना पसंदीदा।

संपादित करें: मैं Java2D में ड्रॉस्ट्रिंग () का उपयोग करके स्ट्रिंग को आकर्षित करना चाहूंगा और वर्ड रैपिंग के लिए लंबाई का उपयोग करूंगा।


4
स्विंग के बिना? आप किस उपकरण का उपयोग कर रहे हैं? क्या फ़ॉन्ट? कौन सा आकार? क्या स्टाइल है? ये सभी चीजें डिस्प्ले की चौड़ाई बदलती हैं।
एस.लूट

3
आप स्ट्रिंग कैसे आकर्षित करने जा रहे हैं? AWT के साथ? या किसी और टूलकिट के साथ? पिक्सेल में स्ट्रिंग का आकार ड्राइंग एपीआई पर निर्भर करता है जो बाद में पिक्सेल को आकर्षित करेगा (और निश्चित रूप से आप किस फ़ॉन्ट का उपयोग करते हैं और क्या फ़ॉन्ट आकार और यदि फ़ॉन्ट बोल्ड / इटैलिक है, आदि)। डब्ल्यू / ओ ड्राइंग एपीआई और फ़ॉन्ट गुणों को जानते हुए, एक स्ट्रिंग का कोई आकार नहीं है।
मीकी

1
@S। लोट। आपके पास एक है। मुझे इसे गैर-प्रश्न के रूप में बंद करने का प्रलोभन दिया गया।
डेविड अरनो

1
@ डेविड अरनो: मैं n00bz पर सॉफ्टी हूं। मैं [शुरुआत] टैग जोड़ूंगा।
एस.लूट

.NET समतुल्य के लिए TextRenderer वर्ग है, देखें stackoverflow.com/questions/604298/…
Spoike

जवाबों:


137

यदि आप केवल AWT का उपयोग करना चाहते हैं, तो निर्दिष्ट स्ट्रिंग के लिए चौड़ाई खोजने के लिए ( और Graphics.getFontMetricsगैर-डिफ़ॉल्ट वाले के लिए वैकल्पिक रूप से फ़ॉन्ट निर्दिष्ट करना) का उपयोग करें ।FontMetricsFontMetrics.stringWidth

उदाहरण के लिए, यदि आपके पास एक Graphicsचर है g, तो आप उपयोग करेंगे:

int width = g.getFontMetrics().stringWidth(text);

अन्य टूलकिट के लिए, आपको हमें अधिक जानकारी देनी होगी - यह हमेशा टूलकिट-डिपेंडेंट रहने वाला है।


8
यदि आप एक उदाहरण उपयोग प्रदान करते हैं तो यह स्पष्ट हो सकता है, शुरू में मैंने इसे एक स्थिर विधि के रूप में उपयोग करने का प्रयास किया था, जैसा कि आपने इसे इस तरह लिखा है।
असिताटस

पदावनत! लेकिन फिर भी सबसे अच्छी विधि!, जब बेहतर तरीका नहीं है तो वे एक विधि को क्यों दर्शाते हैं !!! मुझे यह बिलकुल समझ में नहीं आया!
इमान

2
@Zich: मुझे यकीन नहीं है कि आप जो विधि कह रहे हैं वह पदावनत है - उनमें से कोई भी जावा 8 दस्तावेज में पदावनत नहीं है जहाँ तक मैं देख सकता हूँ ...
जॉन स्कीट

2
@Zich: यह एक तरीका है Graphics, नहीं FontMetrics। लेकिन आप कॉल कर रहे हैं Toolkit.getFontMetrics, जो वास्तव में पदावनत है, और जो इस पद्धति के बारे में बात नहीं करता है ... आपको इस तरह की चीज़ के बारे में वास्तव में सावधान रहने की ज़रूरत है, विशेष रूप से इससे पहले कि आप बग की रिपोर्ट करना शुरू कर दें ...
जॉन स्कीट

1
@Zich: वैसे मुझे अनुमान नहीं है - मैं Toolkit.getFontMetricsइसके बजाय सुझाव देने वाली गैर-पदावनत विधि या गैर-पदावनत विधियों का उपयोग करूँगा ।
जॉन स्कीट

55

यह हमेशा टूलकिट-आश्रित होने की आवश्यकता नहीं है या किसी को हमेशा FontMetrics दृष्टिकोण का उपयोग करने की आवश्यकता नहीं है क्योंकि इसे पहले एक ग्राफिक्स ऑब्जेक्ट प्राप्त करने की आवश्यकता होती है जो एक वेब कंटेनर में अनुपस्थित है या एक सिर रहित वातावरण में है।

मैंने एक वेब सर्वलेट में इसका परीक्षण किया है और यह पाठ की चौड़ाई की गणना करता है।

import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;

...

String text = "Hello World";
AffineTransform affinetransform = new AffineTransform();     
FontRenderContext frc = new FontRenderContext(affinetransform,true,true);     
Font font = new Font("Tahoma", Font.PLAIN, 12);
int textwidth = (int)(font.getStringBounds(text, frc).getWidth());
int textheight = (int)(font.getStringBounds(text, frc).getHeight());

आवश्यक आयाम बनाने के लिए इन आयामों के लिए आवश्यक मान जोड़ें।


1
मुझे नहीं लगता कि एक affineTransform और फॉन्टरेंडरकंटेक्स्ट बनाना इस तरह से एक अच्छा व्यवहार होगा। मुझे लगता है कि font.getTransfrom () अधिक तार्किक होगा।
Lyth

1
आपका उदाहरण अभी भी AWT कार्यक्षमता का उपयोग कर रहा है। उदाहरण के लिए, SWT फ़ॉन्ट के साथ, यह काम नहीं करने वाला है, यही कारण है कि "यह हमेशा टूलकिट पर निर्भर रहने वाला है"
serg.nechaev

1
@ ओलोफू मार्क - getStringBounds केवल तार्किक सीमा देता है। इसे बेहतर बनाने के लिए इसे वास्तविक ऊंचाई सहित, चढ़ाई + वंश को प्राप्त करने के लिए getBounds () और LineMetrics ऑब्जेक्ट का उपयोग करना चाहिए।
जोन्स

8

निम्न वर्ग में getWidth विधि का उपयोग करें:

import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;

class StringMetrics {

  Font font;
  FontRenderContext context;

  public StringMetrics(Graphics2D g2) {

    font = g2.getFont();
    context = g2.getFontRenderContext();
  }

  Rectangle2D getBounds(String message) {

    return font.getStringBounds(message, context);
  }

  double getWidth(String message) {

    Rectangle2D bounds = getBounds(message);
    return bounds.getWidth();
  }

  double getHeight(String message) {

    Rectangle2D bounds = getBounds(message);
    return bounds.getHeight();
  }

}

1

और अब पूरी तरह से अलग कुछ के लिए । निम्नलिखित एरियल फ़ॉन्ट को मानता है, और वर्ण बनाम चौड़ाई के रेखीय प्रक्षेप पर आधारित एक जंगली अनुमान लगाता है।

// Returns the size in PICA of the string, given space is 200 and 'W' is 1000.
// see https://p2p.wrox.com/access/32197-calculate-character-widths.html

static int picaSize(String s)
{
    // the following characters are sorted by width in Arial font
    String lookup = " .:,;'^`!|jl/\\i-()JfIt[]?{}sr*a\"ce_gFzLxkP+0123456789<=>~qvy$SbduEphonTBCXY#VRKZN%GUAHD@OQ&wmMW";
    int result = 0;
    for (int i = 0; i < s.length(); ++i)
    {
        int c = lookup.indexOf(s.charAt(i));
        result += (c < 0 ? 60 : c) * 7 + 200;
    }
    return result;
}

दिलचस्प है, लेकिन शायद बहुत व्यावहारिक नहीं है।


1

मैं व्यक्तिगत रूप से मुझे मल्टीलाइन स्ट्रिंग क्षेत्र की गणना करने के लिए कुछ खोज रहा था, इसलिए मैं यह निर्धारित कर सकता था कि दिए गए क्षेत्र स्ट्रिंग को प्रिंट करने के लिए पर्याप्त है - विशिष्ट फ़ॉन्ट को संरक्षित करने के साथ।

private static Hashtable hash = new Hashtable();
private Font font;
private LineBreakMeasurer lineBreakMeasurer;
private int start, end;

public PixelLengthCheck(Font font) {
    this.font = font;
}

public boolean tryIfStringFits(String textToMeasure, Dimension areaToFit) {
    AttributedString attributedString = new AttributedString(textToMeasure, hash);
    attributedString.addAttribute(TextAttribute.FONT, font);
    AttributedCharacterIterator attributedCharacterIterator =
            attributedString.getIterator();
    start = attributedCharacterIterator.getBeginIndex();
    end = attributedCharacterIterator.getEndIndex();

    lineBreakMeasurer = new LineBreakMeasurer(attributedCharacterIterator,
            new FontRenderContext(null, false, false));

    float width = (float) areaToFit.width;
    float height = 0;
    lineBreakMeasurer.setPosition(start);

    while (lineBreakMeasurer.getPosition() < end) {
        TextLayout textLayout = lineBreakMeasurer.nextLayout(width);
        height += textLayout.getAscent();
        height += textLayout.getDescent() + textLayout.getLeading();
    }

    boolean res = height <= areaToFit.getHeight();

    return res;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.