java - Smart JScrollPane follows output text -


i have smart jscrollpane unlike every other solution out there know if view port can follow (scrolling with) viewed component (jtextarea) if scroll pane not @ bottom , if text buffer full. functional code snippet included. thanks.

public class scrollingjtextareaexample extends jframe {     // worker thread periodically append example messages jtextarea     timer timer = new timer();     // merely informative counter, displayed example messages     int messagecounter = 0;     // gui components     jscrollpane jscrollpane;     myjtextarea jtextarea;      public scrollingjtextareaexample() {         initcomponents(); // boiler plate gui construction , layout          // configure jtextarea not update cursor position after         // inserting or appending text jtextarea. disables         // jtextarea's usual behavior of scrolling automatically whenever         // inserting or appending text jtextarea: want scrolling         // occur @ our discretion, not blindly. note         // breaks normal typing jtextarea. approach assumes         // updates scrollingjtextarea programmatic.         defaultcaret caret = (defaultcaret) jtextarea.getcaret();         caret.setupdatepolicy(defaultcaret.never_update);          // schedule task periodically append example messages jtextarea         timer.schedule(new textgeneratortask(), 250, 250);          // documentlistener takes care of re-scrolling when appropriate         document document = jtextarea.getdocument();         document.adddocumentlistener(new scrollingdocumentlistener());     }      // boring, vanilla gui construction , layout code     private void initcomponents() {         jscrollpane = new javax.swing.jscrollpane();         jtextarea = new myjtextarea();         setdefaultcloseoperation(windowconstants.exit_on_close);         jscrollpane.setviewportview(jtextarea);         getcontentpane().add(jscrollpane, java.awt.borderlayout.center);         setsize(320, 240);         setlocationrelativeto(null);     }      // scrollingdocumentlistener takes care of re-scrolling when appropriate     class scrollingdocumentlistener implements documentlistener {         public void changedupdate(documentevent e) {             maybescrolltobottom();         }          public void insertupdate(documentevent e) {             maybescrolltobottom();         }          public void removeupdate(documentevent e) {             maybescrolltobottom();         }          private void maybescrolltobottom() {             jscrollbar scrollbar = jscrollpane.getverticalscrollbar();             boolean scrollbaratbottom = isscrollbarfullyextended(scrollbar);             boolean scrolllock = toolkit.getdefaulttoolkit()                     .getlockingkeystate(keyevent.vk_scroll_lock);             if (scrollbaratbottom && !scrolllock) {                 // push call "scrolltobottom" 2 places on                 // awt-edt queue runs *after* swing has had                 // opportunity "react" appending of new text:                 // ensures "scrolltobottom" after new                 // bottom has been recalculated during natural                 // revalidation of gui occurs after having                 // appending new text jtextarea.                 eventqueue.invokelater(new runnable() {                     public void run() {                         eventqueue.invokelater(new runnable() {                             public void run() {                                 scrolltobottom(jtextarea);                             }                         });                     }                 });             }         }     }      class textgeneratortask extends timertask {         public void run() {             eventqueue.invokelater(new runnable() {                 public void run() {                     string message = (++messagecounter)                             + " lorem ipsum dolor sit amet, consectetur adipisicing elit. \n";                     jtextarea.appendtext(message);                 }             });         }     }      public static boolean isscrollbarfullyextended(jscrollbar vscrollbar) {         boundedrangemodel model = vscrollbar.getmodel();         return (model.getextent() + model.getvalue()) == model.getmaximum();     }      public static void scrolltobottom(jcomponent component) {         rectangle visiblerect = component.getvisiblerect();         visiblerect.y = component.getheight() - visiblerect.height;         component.scrollrecttovisible(visiblerect);     }      public static void main(string args[]) {         java.awt.eventqueue.invokelater(new runnable() {             public void run() {                 new scrollingjtextareaexample().setvisible(true);             }         });     }       public class myjtextarea extends jtextarea {         defaultcaret caret;         static final int buffersize = 100;          public myjtextarea() {             setborder(borderfactory.createetchedborder());                   setbackground(color.black);             setforeground(color.white);             setcaretcolor(getforeground());             setfont(new font("lucida console", font.plain, 12));             setlinewrap(false);                         seteditable(false);         }          public void appendtext(string text) {             // when line count in text window > size of buffer,              // replace first line in buffer give way last line,              // lines in buffer shift 1 line             if (getlinecount() > buffersize) {                 try {                     replacerange(null, getlinestartoffset(0), getlineendoffset(0));                 } catch (exception e) {                     append("an exception occured in replacing topmost entry in buffer");                     e.printstacktrace();                     return;                 }             }             append(text);                     }     } } 

in example have buffer of 100 lines. lets first line in viewport @ line 40 when turn scroll lock on.

if understand requirement want line 40 stay @ top of viewport once start removing lines document. lines deleted, scrollbar move top of scroll pane. when line 40 deleted scrollbar top of scroll pane.

if following (rough) code give idea:

public void removeupdate(documentevent e) {     //maybescrolltobottom();     int lineheight = jtextarea.getpreferredsize().height / jtextarea.getlinecount();     jviewport viewport = jscrollpane.getviewport();     point position = viewport.getviewposition();     position.y -= lineheight;      if (position.y > 0 )         viewport.setviewposition(position); } 

i doubt code works way want since once buffer full can't drag scrollbar down bottom have viewport continually scroll lines appended. might give ideas.


Comments

Popular posts from this blog

java - Could not locate OpenAL library -

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

sorting - opencl Bitonic sort with 64 bits keys -