2010-08-02 35 views
6

मैं एक जेएसक्स्टपेन युक्त JSCrollPane पर स्मार्ट ऑटोस्क्रॉलिंग को लागू करने का प्रयास कर रहा हूं। JTextPane का उपयोग मेरे ऐप को रंग में लॉग इन करने के लिए किया जाता है। हालांकि मैं स्मार्ट ऑटोस्कोलिंग करने की कोशिश कर रहे दीवार में दौड़ रहा हूं। स्मार्ट ऑटोस्कोलिंग द्वारा मेरा मतलब यह नहीं है कि प्रत्येक बार कुछ बदलावों में अंधेरे से ऑटोस्क्रॉलिंग हो, मेरा मतलब है कि यह देखने के लिए जांच कर रहा है कि क्या आपका स्क्रॉल सभी तरह से नीचे है, फिर ऑटोस्क्रॉल। हालांकि कोई बात नहीं क्या मैं इसे या तो हमेशा autoscrolls या एक परीक्षण स्क्रिप्ट के रूप में बिल्कुलस्मार्ट JScrollPane autoscrolling

नहीं है, यहाँ सेटअप है बदसूरत ऑटो टेस्ट जोड़ने है (JFrame बाहर छोड़ दिया गया है)

final JTextPane textPane = new JTextPane(); 
textPane.setEditable(false); 
final JScrollPane contentPane = new JScrollPane(textPane); 
contentPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

और यहाँ लूप

while (true) 
    try { 
     Thread.sleep(1000); 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        JScrollBar scrollBar = scroll; 
        boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum())); 
        System.out.println("Value: " + scroll.getValue() 
            + " | Visible: " + scrollBar.getVisibleAmount() 
            + " | Maximum: " + scrollBar.getMaximum() 
            + " | Combined: " + (scrollBar.getValue() + scrollBar.getVisibleAmount()) 
            + " | Vis!=Max : " + (scrollBar.getVisibleAmount() != scrollBar.getMaximum()) 
            + " | Comb=Max: " + (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum()) 
            + " | Eval: " + preCheck); 
        StyledDocument doc = textPane.getStyledDocument(); 
        doc.insertString(doc.getLength(), "FAGAHSIDFNJASDKFJSD\n", doc.getStyle("")); 
        if (!preCheck) 
          textPane.setCaretPosition(doc.getLength()); 
       } catch (BadLocationException ex) { 
          ex.printStackTrace(); 
       } 
      } 
     }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

यह सुंदर नहीं है, लेकिन यह काम पूरा हो जाता है।

यहाँ हालांकि प्रासंगिक जांच

boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum())); 
if (preCheck) 
    textPane.setCaretPosition(doc.getLength()); 

हिस्सा thats Thats मुझे परेशानी दे रहा है। यह देखने के लिए पहले एक जांच है कि बार दिखाई दे रहा है लेकिन अनुपयोगी (पर्याप्त पाठ नहीं है, बार को पूर्ण लंबाई बना रहा है), फिर यदि बार का निचला भाग अधिकतम के बराबर है। सिद्धांत रूप में, यह काम करना चाहिए। हालांकि, चारों ओर चेक को स्थानांतरित करने सहित कुछ भी नहीं, मुझे जो परिणाम चाहिए वो मिल गया है।

कोई सुझाव?

this या this का कोई डिप्लिकेट नहीं है, क्योंकि वे इसे हमेशा स्क्रॉल करना चाहते हैं, न कि कभी-कभी।

+0

क्या आपने इसे हल किया? मेरे पास बिल्कुल वही कार्य है, और, वास्तव में, अभी भी समाधान नहीं मिल रहा है। –

उत्तर

7

संपादित करें:

मैं एक और अधिक लचीला संस्करण है जिसे jScrollPane में किसी भी घटक पर काम करेंगे साथ निम्नलिखित कोड बदल दिया। जांचें: Smart Scrolling

import java.awt.*; 
import java.awt.event.*; 
import java.util.Date; 
import javax.swing.*; 
import javax.swing.text.*; 

public class ScrollControl implements AdjustmentListener 
{ 
    private JScrollBar scrollBar; 
    private JTextComponent textComponent; 
    private int previousExtent = -1; 

    public ScrollControl(JScrollPane scrollPane) 
    { 
     Component view = scrollPane.getViewport().getView(); 

     if (! (view instanceof JTextComponent)) 
      throw new IllegalArgumentException("Scrollpane must contain a JTextComponent"); 

     textComponent = (JTextComponent)view; 

     scrollBar = scrollPane.getVerticalScrollBar(); 
     scrollBar.addAdjustmentListener(this); 
    } 

    @Override 
    public void adjustmentValueChanged(final AdjustmentEvent e) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       checkScrollBar(e); 
      } 
     }); 
    } 

    private void checkScrollBar(AdjustmentEvent e) 
    { 
     // The scroll bar model contains information needed to determine the 
     // caret update policy. 

     JScrollBar scrollBar = (JScrollBar)e.getSource(); 
     BoundedRangeModel model = scrollBar.getModel(); 
     int value = model.getValue(); 
     int extent = model.getExtent(); 
     int maximum = model.getMaximum(); 
     DefaultCaret caret = (DefaultCaret)textComponent.getCaret(); 

     // When the size of the viewport changes there is no need to change the 
     // caret update policy. 

     if (previousExtent != extent) 
     { 
      // When the height of a scrollpane is decreased the scrollbar is 
      // moved up from the bottom for some reason. Reposition the 
      // scrollbar at the bottom 

      if (extent < previousExtent 
      && caret.getUpdatePolicy() == DefaultCaret.UPDATE_WHEN_ON_EDT) 
      { 
       scrollBar.setValue(maximum); 
      } 

      previousExtent = extent; 
      return; 
     } 

     // Text components will not scroll to the bottom of a scroll pane when 
     // a bottom inset is used. Therefore the location of the scrollbar, 
     // the height of the viewport, and the bottom inset value must be 
     // considered when determining if the scrollbar is at the bottom. 

     int bottom = textComponent.getInsets().bottom; 

     if (value + extent + bottom < maximum) 
     { 
      if (caret.getUpdatePolicy() != DefaultCaret.NEVER_UPDATE) 
       caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); 
     } 
     else 
     { 
      if (caret.getUpdatePolicy() != DefaultCaret.UPDATE_WHEN_ON_EDT) 
      { 
       caret.setDot(textComponent.getDocument().getLength()); 
       caret.setUpdatePolicy(DefaultCaret.UPDATE_WHEN_ON_EDT); 
      } 
     } 
    } 

    private static void createAndShowUI() 
    { 
     JPanel center = new JPanel(new GridLayout(1, 2)); 
     String text = "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n"; 

     final JTextArea textArea = new JTextArea(); 
     textArea.setText(text); 
     textArea.setEditable(false); 
     center.add(createScrollPane(textArea)); 
     System.out.println(textArea.getInsets()); 

     final JTextPane textPane = new JTextPane(); 
     textPane.setText(text); 
     textPane.setEditable(false); 
     center.add(createScrollPane(textPane) ); 
     textPane.setMargin(new Insets(5, 3, 7, 3)); 
     System.out.println(textPane.getInsets()); 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(center, BorderLayout.CENTER); 
     frame.setSize(500, 200); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

     Timer timer = new Timer(2000, new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       try 
       { 
        Date now = new Date(); 
        textArea.getDocument().insertString(textArea.getDocument().getLength(), "\n" + now.toString(), null); 
        textPane.getDocument().insertString(textPane.getDocument().getLength(), "\n" + now.toString(), null); 
       } 
       catch (BadLocationException e1) {} 
      } 
     }); 
     timer.start(); 
    } 

    private static JComponent createScrollPane(JComponent component) 
    { 
     JScrollPane scrollPane = new JScrollPane(component); 
     new ScrollControl(scrollPane); 

     return scrollPane; 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

लिंक टूटा हुआ है, क्या आप एक और प्रदान कर सकते हैं? –

+0

महान उदाहरण। मैंने एक ही चीज़ के लिए समाधान का आविष्कार करने की कोशिश की लेकिन इसे करने का प्रबंधन नहीं किया :( – Dragon

+0

एक उत्कृष्ट समाधान - साझा करने के लिए बहुत धन्यवाद। –