2012-05-21 22 views
13

की शुरुआत में सेट की गई स्थिति के साथ टेक्स्ट एरिया (JTextArea) के लिए ऑटो टेक्स्ट स्क्रॉल मेरे पास एक साधारण जावा प्रश्न है। मैं JTextArea का उपयोग करके बनाए गए टेक्स्ट एरिया की अंतिम पंक्ति की शुरुआत में ऑटो स्क्रॉल करना चाहता हूं। टेक्स्ट क्षेत्र की प्रति पंक्ति टेक्स्ट की मात्रा टेक्स्ट क्षेत्र की चौड़ाई से काफी लंबी है।अंतिम क्षेत्र

यहां कोड स्निपेट है जिसे मैं सेट अप करने के लिए उपयोग करता हूं।

JTextArea textArea = new JTextArea(); 
DefaultCaret caret = (DefaultCaret)textArea.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 

समस्या अब है, इसके बाद के संस्करण कोड के साथ, डिफ़ॉल्ट व्यवहार कि कैरट ऑटो दस्तावेज़ के अंत पर रखा जाता है, एक परिणाम के रूप, पूरे पाठ क्षेत्र की शुरुआत हिस्सा दायरे से बाहर हो जाता है है । मैं दस्तावेज़ में अंतिम पंक्ति की शुरुआत के लिए ऑटो स्क्रॉल करना पसंद करूंगा।

यह स्पष्ट करने के लिए यहां दो स्क्रीन शॉट,

हैं क्या मैं चाहता हूँ पहले एक है, लेकिन क्या हो रहा है दूसरे से एक है।

What I want is this What I get is this

उत्तर

13

आप सही स्थान पाठ क्षेत्र के पाठ को अद्यतन करने के बाद getLineCount और getLineStartOffset का उपयोग करने के कैरेट को हिलाने।

import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultCaret; 

public class Test { 

    private JFrame frame; 
    private JTextArea ta; 

    protected void initUI() { 
     frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     ta = new JTextArea(); 
     DefaultCaret caret = (DefaultCaret) ta.getCaret(); 
     caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 
     frame.add(new JScrollPane(ta)); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
     new UpdateText().execute(); 
    } 

    class UpdateText extends SwingWorker<String, String> { 

     @Override 
     public String doInBackground() { 
      for (int i = 0; i < 1000; i++) { 
       publish("Hello-" + i); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      return null; 
     } 

     @Override 
     public void process(List<String> chunks) { 
      for (String s : chunks) { 
       if (ta.getDocument().getLength() > 0) { 
        ta.append("\n"); 
       } 
       ta.append(s); 
      } 
      try { 
       ta.setCaretPosition(ta.getLineStartOffset(ta.getLineCount() - 1)); 
      } catch (BadLocationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void done() { 

     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new Test().initUI(); 
      } 
     }); 
    } 

} 
+0

कूल समाधान:

यहाँ अपने वांछित व्यवहार को दर्शाता हुआ एक काम उदाहरण है! लेकिन मेरे यहां एक सवाल है। क्या कोई तरीका है कि मैं ta.setCaretPosition (ta.getLineStartOffset (ta.getLineCount() - 1) सेट कर सकता हूं; हर बार इसे अद्यतन करने के बजाय केवल एक बार, ताकि यह पूरे आवेदन के लिए मान्य रहे? –

+0

इसके अलावा, हालांकि आप डिफॉल्ट कैरेट कैरेट = (डिफॉल्ट कैरेट) ta.getCaret(); caret.setUpdatePolicy (DefaultCaret.ALWAYS_UPDATE) का उपयोग कर रहे हैं; आपका कोड इन बयानों के बिना भी काम करेगा? इस संबंध में आपका क्या विचार है? –

+0

@JtheRocker मुझे नहीं पता कि। पाठ अद्यतन होने पर कैरेट स्थिति आगे बढ़ती रहती है। इसका मतलब यह है कि हर समय इसकी जगह को फिर से गणना की जानी चाहिए। आप पहले JTextArea को बढ़ा सकते हैं और setText को ओवरराइड कर सकते हैं, पहले सुपर.सेटटेक्स्ट को कॉल करके और फिर कैरेट को स्थिति दें। आपके दूसरे प्रश्न के लिए, यह वांछित व्यवहार और क्षुद्रग्रह का सवाल है। आपके प्रश्न में आपने यही पूछा है। अब, यदि आप वास्तव में स्क्रोलपैन के निचले बाएं कोने में स्क्रॉल कर रहे हैं, तो आप कुछ और ढूंढ रहे हैं। यदि ऐसा है, तो SO पर एक और प्रश्न पोस्ट करने पर विचार करें। –