java - In JavaFX how can I programmatically scroll a Scrollpane to the bottom? -
i have been working on small chat client me , friends, teaching myself java , jfx 8 on side. unfortunately, reason unable programmatically scroll bottom of scrollpane chat messages are.
i have method called scrolltobottom() executes following code:
public void scrolltobottom() { platform.runlater(() -> this.getchatview().vvalueproperty().setvalue(1.0)); }
i have button works using method scrolling bottom, other programmatical approach (even firing button other methods) not correctly update scrollbar of scrollpane. however, when call getvvalue() on scrollpane after supposedly scrolling, returns correct value i'm trying scroll through. scrollpane not scrolling supposed value.
below have relevant class in application - chatbox type extension of vbox uses extended type of text.
public class mainscreencontroller { //lists //buttons private button logoutbutton; private button btn1 = new button("test button"); private button scrollbutton = new button("scroll button"); //numbers //booleans private boolean ishosting; //strings private string username = ""; //scene private stage window; private gridpane layout = new gridpane(); //other objects private textarea chatfield = new textarea(); private label usernamelabel; private textarea usersarea = new textarea("connected users: "); private vbox firstcolumn = new vbox(10); private vbox secondcolumn = new vbox(10); private imageview mediacolumn = new imageview(); private server server = new server(); private client client = new client(); private textfield dlfield = new textfield(); private audiohandler audiohandler = new audiohandler(); private chatbox chatbox = new chatbox(); private scrollpane chatview = new scrollpane(this.chatbox); private hbox buttonbox = new hbox(10); private void initchatview() { this.getchatview().setminsize(500, 500); this.getchatview().setprefsize(500, 500); this.getchatview().setmaxsize(500, 500); this.getchatview().setstyle("-fx-focus-color: transparent; -fx-background-color: gainsboro"); this.chatview.hbarpolicyproperty().set(scrollbarpolicy.never); this.chatview.vbarpolicyproperty().set(scrollbarpolicy.as_needed); /*this.chatview.vvalueproperty().addlistener(e -> { if(this.chatview.getvvalue() != 1) { system.out.println("pre: " + this.chatview.getvvalue()); this.chatview.vvalueproperty().set(1); system.out.println("post: " + this.chatview.getvvalue()); } });*/ this.scrollbutton.setonaction(e -> { scrolltobottom(); }); } private void initsecondcolumn() { this.secondcolumn.setstyle("-fx-background-color: gainsboro"); this.secondcolumn.setprefsize(525, 550); this.secondcolumn.setminsize(450, 550); this.secondcolumn.setmaxsize(525, 550); button dlbutton = new button("download link:"); dlbutton.setstyle("-fx-focus-color: transparent"); dlbutton.setonaction(e -> { if (!this.dlfield.gettext().equals(null) || !this.dlfield.gettext().equals(null)) { try { filehandler.downloadfile(this.window, this.dlfield.gettext()); } catch (exception ex) { ex.printstacktrace(); } this.dlfield.clear(); } }); this.dlfield.setprefsize(450, 20); this.dlfield.setminsize(450, 20); this.dlfield.setmaxsize(450, 20); this.mediacolumn.setfitheight(475); this.mediacolumn.setpreserveratio(true); this.mediacolumn.setstyle("-fx-border-color: red"); this.mediacolumn.prefwidth(450); this.mediacolumn.prefheight(475); this.mediacolumn.minwidth(450); this.mediacolumn.minheight(475); this.mediacolumn.maxwidth(450); this.mediacolumn.maxheight(475); this.secondcolumn.getchildren().addall(dlbutton, this.dlfield, mediacolumn); } private void initusersarea() { this.usersarea.setprefsize(500, 75); this.usersarea.setminsize(500, 75); this.usersarea.setmaxsize(500, 75); this.usersarea.seteditable(false); this.usersarea.setstyle("-fx-focus-color: transparent; -fx-background-color: gainsboro"); } public void scrolltobottom() { platform.runlater(() -> this.getchatview().vvalueproperty().setvalue(1.0)); system.out.println(this.chatview.getvvalue()); } public mainscreencontroller(gridpane layout, stage window, scene currentscene, scene nextscene, windowcontroller windowcontroller) throws urisyntaxexception, ioexception { new file(filehandler.downloadspath).mkdirs(); this.layout = layout; this.window = window; this.initchatview(); filehandler.readlog(this.getchatbox()); } private void initusernamelabel() { this.usernamelabel = new label(); this.usernamelabel.setstyle("-fx-border-color: black; -fx-background-color: silver; -fx-focus-color: transparent"); this.usernamelabel.settext(" logged in "); this.usernamelabel.settextfill(color.blue); } private void initlayout() { this.layout.setpadding(new insets(10, 10, 10, 10)); this.layout.setvgap(10); this.layout.sethgap(10); this.layout.getchildren().addall(this.firstcolumn, this.secondcolumn); gridpane.setcolumnindex(this.firstcolumn, 0); gridpane.setcolumnindex(this.secondcolumn, 1); gridpane.setvalignment(secondcolumn, vpos.bottom); this.buttonbox.getchildren().addall(this.logoutbutton, this.scrollbutton); this.firstcolumn.getchildren().addall(this.buttonbox, this.usernamelabel, this.usersarea, this.chatview, this.getchatfield()); } public void initbtn1() { btn1.setstyle("-fx-focus-color: transparent"); gridpane.setconstraints(btn1, 1, 0); gridpane.setvalignment(btn1, vpos.baseline); this.layout.getchildren().add(btn1); btn1.addeventhandler(actionevent.action, e -> { boolean b = false; if (!b) { audiohandler.startrecording(); b = !b; } else if (b) { audiohandler.stoprecording(); b = !b; } }); } public void addmessage(string msg, string color) { filehandler.writetochatlog(msg); if (!msg.startswith("*!") && !msg.startswith("/")) { platform.runlater(() -> { this.getchatbox().addtext(new chattext(msg, color)); this.scrollbutton.arm(); this.scrollbutton.fire(); }); } } private void initchatfield() { this.getchatfield().setprefsize(500, 10); this.getchatfield().setmaxheight(10); this.getchatfield().autosize(); this.getchatfield().setwraptext(true); this.getchatfield().addeventhandler(keyevent.key_pressed, key -> { if (key.getcode() == keycode.enter) { key.consume(); if (this.getchatfield().gettext().startswith("/")) { commandparser.parse(this.getchatfield().gettext(), this); } else { try { this.getclient().getclientsendingdata().writeutf(this.getchatfield().gettext().trim()); this.getchatfield().clear(); } catch (exception e) { e.printstacktrace(); } } } }); this.getchatfield().setstyle("-fx-background-color: gainsboro"); } private void initlogoutbutton() { this.logoutbutton = new button(); this.logoutbutton.settext("log out"); this.logoutbutton.setonaction(e -> { try { this.client.getclientsendingdata().writeutf("*![system] " + systeminfo.getdate() + ": " + this.client.getclientname() + " has disconnected."); system.out.println("logging out."); window.close(); new chatclient().start(new stage()); } catch (exception ex) { ex.printstacktrace(); } }); this.logoutbutton.setstyle("-fx-focus-color: transparent"); } public void initmainscreen() { initusernamelabel(); initlogoutbutton(); initchatfield(); initlayout(); initusersarea(); initbtn1(); initsecondcolumn(); } public void setusername(string username) { this.username = username; } public string getusername() { return this.username; } public label getusernamelabel() { return this.usernamelabel; } public gridpane getlayout() { return this.layout; } public void setishosting(boolean b) { this.ishosting = b; } public boolean getishosting() { return this.ishosting; } public server getserver() { return this.server; } public void setserver(server hostserver) { this.server = hostserver; } public client getclient() { return this.client; } public void setclient(client client) { this.client = client; } public scrollpane getchatview() { return chatview; } public void setchatview(scrollpane chatview) { this.chatview = chatview; } public textarea getchatfield() { return chatfield; } public void setchatfield(textarea chatfield) { this.chatfield = chatfield; } public textarea getusersarea() { return this.usersarea; } public chatbox getchatbox() { return chatbox; } public void setchatbox(chatbox chatbox) { this.chatbox = chatbox; } }
and if have other general suggestions (i'm learning java) tips welcome. :) thanks!
what scroll text in textarea bottom is, set caret in text end of text, like:
textarea.positioncaret(textarea.gettext().length());
in fact, make sure text in textarea doesn't scroll horizontally left (e.g. when last line in textarea long), set caret right behind last "\n" in text, this:
string content = textarea.gettext(); int indexoflastlinefeed = content.lastindexof("\n"); if (indexoflastlinefeed == -1) textarea.positioncaret(content.length()); else textarea.positioncaret(math.min(indexoflastlinefeed + 1, content.length()));
Comments
Post a Comment