2011-06-16 14 views
10

मेरे पास एक JTextArea है जिसके लिए मैंने वर्ड-रैप और रैप-स्टाइल-शब्द को सत्य पर सेट किया है। मैं JTextArea को निर्दिष्ट चौड़ाई के अनुसार न्यूनतम संभव ऊंचाई पर "पैक" करना चाहता हूं।रैपिंग के कारण जेटीक्स्टएरिया में लाइनों की संख्या को कैसे गिनना है?

ऐसा करने के लिए, मैं का उपयोग कर फॉन्ट की ऊंचाई की गणना के लिए योजना बना रहा हूँ ...

Font font = jTextArea.getFont(); 
    FontMetrics fontMetrics = jTextArea.getFontMetrics(font); 
    int lineHeight = fontMetrics.getAscent() + fontMetrics.getDescent(); 

... और फिर JTextArea में इस्तेमाल किया लाइनों की संख्या से गुणा। समस्या यह है कि JTextArea.getLineCount() लिपटे लाइनों को अनदेखा करते हुए लाइन रिटर्न की संख्या की गणना करता है।

मैं JTextArea में उपयोग की जाने वाली लाइनों की संख्या को कैसे गिन सकता हूं, जिनमें शब्द रैप के कारण होते हैं?

इस समस्या को आसान बनाने के लिए यहां कुछ डेमो कोड दिया गया है। मेरे पास एक श्रोता है जो खिड़की का आकार बदलने पर प्रत्येक बार लाइनों की संख्या को प्रिंट करता है। फिलहाल, यह हमेशा 1 प्रिंट करता है, लेकिन मैं शब्द लपेटने के लिए क्षतिपूर्ति करना चाहता हूं और प्रिंट करना चाहता हूं कि वास्तव में कितनी लाइनों का उपयोग किया जा रहा है।

संपादित करें: मैंने नीचे दिए गए कोड में समस्या का समाधान शामिल किया है। स्थैतिक गिनती विधि समाधान प्रदान करती है।

package components;                   

import java.awt.*; 
import java.awt.event.*; 
import java.awt.font.*; 
import java.text.*; 
import javax.swing.*; 

public class JTextAreaLineCountDemo extends JPanel {           
    JTextArea textArea;                   

    public JTextAreaLineCountDemo() {               
    super(new GridBagLayout());                

    String inputStr = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo"; 
    textArea = new JTextArea(inputStr);              
    textArea.setEditable(false);                
    textArea.setLineWrap(true);                
    textArea.setWrapStyleWord(true);               

    // Add Components to this panel.               
    GridBagConstraints c = new GridBagConstraints();           
    c.gridwidth = GridBagConstraints.REMAINDER;            

    c.fill = GridBagConstraints.BOTH;               
    c.weightx = 1.0;                   
    c.weighty = 1.0;                   
    add(textArea, c);                   

    addComponentListener(new ComponentAdapter() {            
     @Override                    
     public void componentResized(ComponentEvent ce) {     
     System.out.println("Line count: " + countLines(textArea));       
     }                      
    });                      
    }                       

    private static int countLines(JTextArea textArea) { 
    AttributedString text = new AttributedString(textArea.getText()); 
    FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()) 
     .getFontRenderContext(); 
    AttributedCharacterIterator charIt = text.getIterator(); 
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc); 
    float formatWidth = (float) textArea.getSize().width; 
    lineMeasurer.setPosition(charIt.getBeginIndex()); 

    int noLines = 0; 
    while (lineMeasurer.getPosition() < charIt.getEndIndex()) { 
     lineMeasurer.nextLayout(formatWidth); 
     noLines++; 
    } 

    return noLines; 
    } 

    private static void createAndShowGUI() {              
    JFrame frame = new JFrame("JTextAreaLineCountDemo");          
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);          

    frame.add(new JTextAreaLineCountDemo());             

    frame.pack();                    
    frame.setVisible(true);                 
    }                       

    public static void main(String[] args) {              
    javax.swing.SwingUtilities.invokeLater(new Runnable() {         
     public void run() {                  
     createAndShowGUI();                 
     }                      
    });                      
    }                       
}                        
+0

भी [कैसे पंक्तियों ... एक JTextArea में की संख्या की गणना करने के लिए?] देखें (http://stackoverflow.com/questions/5979795)। – trashgod

+0

इस समाधान में, यदि पाठ खाली है तो त्रुटि फेंक जाएगी: 'java.lang.IllegalArgumentException: पाठ में कम से कम एक वर्ण होना चाहिए' मैं _try catch_ 'new LineBreakMeasurer (charIt, frc) ' – CarlosRos

+0

के साथ घूमने का सुझाव देता हूं, यह विधि '\ n' वर्ण को नई पंक्ति के रूप में नहीं लेती है। – CarlosRos

उत्तर

5

आप LineBreakMeasurer कक्षा उपयोग कर सकते हैं।

The LineBreakMeasurer class allows styled text to be broken into lines (or segments) that fit within a particular visual advance. This is useful for clients who wish to display a paragraph of text that fits within a specific width, called the wrapping width.LineBreakMeasurer implements the most commonly used line-breaking policy: Every word that fits within the wrapping width is placed on the line. If the first word does not fit, then all of the characters that fit within the wrapping width are placed on the line. At least one character is placed on each line.

+0

ऐसा लगता है कि ऐसा करने का एक आसान तरीका होना चाहिए। हालांकि आपके सुझाव ने मुझे सही रास्ते पर ले जाया, और मैंने इस सवाल का समाधान जोड़ा है। – peskal

1

ऐसा लगता है कि यह सब जवाब खत्म नहीं हो सका। यदि फ़ॉन्ट बदलना और पाठ को विस्तारित करना लाइनकाउंट गलत हो रहा है।

संपादित करें: समाधान आप पाठ क्षेत्र के लिए और जिम्मेदार ठहराया स्ट्रिंग के लिए फ़ॉन्ट सेट करना होगा। अब लाइनकाउंट सही है। कोड में समाधान

package lineBreak;                   

import java.awt.*; 
import java.awt.event.*; 
import java.awt.font.*; 
import java.text.*; 
import javax.swing.*; 

public class JTextAreaLineCountDemo extends JPanel {           
    JTextArea textArea;  

    static Font f = new Font("Helvetiva", Font.ITALIC, 50);                   

    public JTextAreaLineCountDemo() {               
    super(new GridBagLayout());                

    String inputStr = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo, Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo, Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo, Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo"; 
    textArea = new JTextArea(inputStr);  

    textArea.setEditable(false);                
    textArea.setLineWrap(true);                
    textArea.setWrapStyleWord(true);               

    // Add Components to this panel.               
    GridBagConstraints c = new GridBagConstraints();           
    c.gridwidth = GridBagConstraints.REMAINDER;            

    c.fill = GridBagConstraints.BOTH;               
    c.weightx = 1.0;                   
    c.weighty = 1.0;                   
    add(textArea, c);                   

    addComponentListener(new ComponentAdapter() {            
     @Override                    
     public void componentResized(ComponentEvent ce) { 
      **textArea.setFont(new Font("Arial", Font.BOLD, 22));** 
     System.out.println("Line count: " + countLines(textArea));       
     }                      
    });                      
    }                       

    private static int countLines(JTextArea textArea) { 
    AttributedString text = new AttributedString(textArea.getText()); 
    text.addAttribute(TextAttribute.FONT, f); 
    FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()) 
     .getFontRenderContext(); 
    AttributedCharacterIterator charIt = text.getIterator(); 
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc); 
    float formatWidth = (float) textArea.getSize().width; 
    lineMeasurer.setPosition(charIt.getBeginIndex()); 

    int noLines = 0; 
    while (lineMeasurer.getPosition() < charIt.getEndIndex()) { 
     lineMeasurer.nextLayout(formatWidth); 
     noLines++; 
    } 

    return noLines; 
    } 

    private static void createAndShowGUI() {              
    JFrame frame = new JFrame("JTextAreaLineCountDemo");          
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);          

    frame.add(new JTextAreaLineCountDemo());             

    frame.pack();                    
    frame.setVisible(true);                 
    }                       

    public static void main(String[] args) {              
    javax.swing.SwingUtilities.invokeLater(new Runnable() {         
     public void run() {                  
     createAndShowGUI();                 
     }                      
    });                      
    }                       
} 
1

आपका countLines विधि लगभग मेरे लिए काम किया है, लेकिन मैं इसे सही ढंग से मेरे मामले में काम करने के लिए कुछ बदलाव करना था। मुझे लगता है कि आप डिफ़ॉल्ट फ़ॉन्ट का उपयोग कर रहे हैं और आपके JTextArea पर सीमा नहीं है, लेकिन एक गैर-डिफ़ॉल्ट फ़ॉन्ट या सीमा (या दोनों, जैसा कि मेरा मामला था) का उपयोग करके countLines गलत संख्या वापस करने के लिए विधि का कारण बन जाएगा । नीचे मेरा अद्यतन संस्करण है जो इन दोनों कारकों के लिए खाता है (और textArea.getSize().width के बजाय textArea.getWidth() का भी उपयोग करता है)।

private static int countLines(JTextArea textArea) 
{ 
    AttributedString text = new AttributedString(textArea.getText()); 
    text.addAttribute(TextAttribute.FONT, textArea.getFont()); 
    FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()).getFontRenderContext(); 
    AttributedCharacterIterator charIt = text.getIterator(); 
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc); 
    Insets textAreaInsets = textArea.getInsets(); 
    float formatWidth = textArea.getWidth() - textAreaInsets.left - textAreaInsets.right; 
    lineMeasurer.setPosition(charIt.getBeginIndex()); 

    int noLines = 0; 
    while (lineMeasurer.getPosition() < charIt.getEndIndex()) 
    { 
     lineMeasurer.nextLayout(formatWidth); 
     noLines++; 
    } 

    return noLines; 
} 

All credit for recognizing that the AttributedString needed to have its font set to the font of the JTextArea goes to Jenny

संबंधित मुद्दे