I am using Kotlin with JavaFX. In a TextArea which is programmatically appended, I want the scrollbar to always jump to the bottom when text is added.
To test this, I wrote this code:
taConsole.text = "Running " + pythonScriptPath
// retrieve output from python script
val bfr = BufferedReader(InputStreamReader(p.inputStream))
val lines = bfr.readLines()
for (i in 1..10) {
for (line in lines) {
taConsole.appendText("\n" + line)
}
}
Sadly, I cant get it to scroll to bottom. I already tried:
ta.selectEnd();
ta.deselect();
dataPane.setScrollTop(Double.MAX_VALUE);
and
val caret = taConsole.selectPositionCaret(taConsole.length)
I inserted them after the:
appendText("\n" + line)
Related
I'm using the angular-ui ui-scroll and it's great when I scroll down, keeps adding items as expected. However when I scroll up, it stops at the top of the last batch that I loaded. For example if I have 100 items and my buffer size is 10, and I've scrolled down so that items 61-70 are showing, when I scroll back up I want to see items 51-60. However I can't scroll up past item 61. I don't know what I'm doing wrong.
Here's the html:
<div row="row" ui-scroll="row in transactionSource" buffer-size="10" >{{row.data}}</sq-transaction>
Here's the script:
$scope.transactionSource = {
get: function (index, count, callback) {
if (index < 0) {
callback([])
}
else {
var buffer = 10;
var end = ctrl.nextIndex + buffer;
if (end > ctrl.transactions.length) end = ctrl.transactions.length;
var items = ctrl.transactions.slice(ctrl.nextIndex, end);
ctrl.nextIndex = end;
callback(items);
}
}
};
If it's related, when I console.log the index and count values received, after the first load of 10 I get an index of -9 (in which case I return an empty array - if I don't do this, the entire array gets loaded). When I scroll up, I don't get a console.log message at all so it's like the 'get' only gets called when scrolling down.
Thanks in advance for any and all help.
Your datasource looks wrong. Items retrieving (slicing in your case) should be based on index and count parameters that you have from the datasource.get method arguments. I'd like to post an example of datasource implementation where the result items array is limited from 0 to 100 and should be sliced from some external data array:
get: function(index, count, success) {
var result = [];
var start = Math.max(0, index);
var end = Math.min(index + count - 1, 100);
if (start <= end) {
result = externalDataArray.slice(start, end + 1);
}
success(result);
};
Hope it helps!
I am trying to get the journal number (Red box) from the invoice journal. I have a button inside the Lines (blue box), however in order for it to work I need the Journal Number (red box) when I clicked the Lines (blue box).
Your Line form already have variable journalNum
So on your Lines form create parm method like this
public LedgerJournalId parmJournalNum(LedgerJournalId _journalNum = journalNum)
{
journalNum = _journalNum;
return journalNum;
}
And then in main method of your batch class you can get journal number using the following code
if (classIdGet(args.caller()) == classNum(SysSetupFormRun))
{
if (formHasMethod(args.caller(), identifierStr(parmJournalNum)))
{
journalNum = args.caller().parmJournalNum();
}
}
I would like to create a QMessageBox::critical which would automatically adapt its size depending on the size of the content (the message text). How can I do it?
This is the message I would like to display on the QMessageBox
std::wstring tmpStrEx;
QDomNode tmpNodeParent = node.parentNode();
while(!tmpNodeParent.isNull() && tmpNodeParent.nodeName().toStdWString() != L"root"){
std::wstring tmpStrTmp;
tmpStrTmp = L"<"
+ tmpNodeParent.nodeName().toStdWString()
+ L" nm=\""
+ tmpNodeParent.toElement().attribute(QS(_T("nm")), QS(_T("undef")) ).toStdWString()
+ L"> ";
}
QString mex = "Error while reading vector.<br/><br/>Please check in:<br/><br/> " + tmpStrTmp ;
tmpStrTmp can be something like <vct nm="name"> <vcx nm="xyz">
I tried in these ways to build the QMessageBox:
First a simple:
QMessageBox::critical(this, "Error", mex);
This shows half message without the content in tmpStrTmp like this:
Error while reading vector.
Please check in:
I thought tmpStrTmp was the problem but if I put only tmpStrTmp in the QMessageBox, it shows its content. So, I thought it was a problem of space and I tried these two ways:
1.
QMessageBox msgBox;
QSpacerItem* spacer = new QSpacerItem(500, 500, QSizePolicy::Minimum, QSizePolicy::Expanding);
msgBox.setTextFormat(Qt::RichText);
msgBox.setText( mex );
QGridLayout* layout = (QGridLayout*)msgBox.layout();
layout->addItem(spacer, layout->rowCount(), 0, 1, layout->columnCount());
msgBox.exec();
2.
QMessageBox *box = new QMessageBox::QMessageBox(QMessageBox::critical, "Error", mex);
QGridLayout *layout = qobject_cast<QGridLayout *>(box->layout());
if (layout) {
QTextEdit *edit = new QTextEdit(mex);
edit->setReadOnly(true);
layout->addWidget(edit, 0, 1);
}
box->exec();
delete box;
but without success...any help? thanks
If you don't want your QMessageBox to simply widen out with your text, and break a new line at some point, you should create an instance of QMessageBox and set it to have a fixed width (QWidget::setFixedWidth()).
Another option is to pass in a text string with new lines (\n) in it, and it can handle it nicely.
Also, if you are using an instance, you can tell it that you are using RichText, and pass in a subset of html markups QMessageBox::setTextFormat(Qt::RichText), or even just make sure you use a valid html tag before your first newline character.
Hope that helps!
QMessageBox is a grid. I'm not sure how to adapt QMessageBox size to its text size but if you know what is going to be appear in the messagebox you can most definitely set it to a minimum(actually fixed) size by this way:-
QMessageBox messageBox;
QSpacerItem* horizontalSpacer = new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
messageBox.setText( "Put text here" );
QGridLayout* layout = (QGridLayout*)messageBox.layout();
layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount());
messageBox.exec();
I can get the line of the cursor by using QTextEdit.textCursor().blockNumber(), but when one line wrap into multi-lines, it can not return the actual line number.
How can I do that?
I wasn't sure it will work, so I wrote a quick test application (Qt 5.0.1) and this works, here is piece of it:
void MainWindow::on_plainTextEdit_cursorPositionChanged()
{
QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(sender());
Q_ASSERT(edit);
QTextCursor cursor = edit->textCursor();
cursor.movePosition(QTextCursor::StartOfLine);
int lines = 1;
while(cursor.positionInBlock()>0) {
cursor.movePosition(QTextCursor::Up);
lines++;
}
QTextBlock block = cursor.block().previous();
while(block.isValid()) {
lines += block.lineCount();
block = block.previous();
}
ui->label->setText(QString::number(lines));
}
Here is a similar solution in Python. It fixes the problem I noted in comment on the earlier one above. This is a method in a subclass of QTextEdit:
def getLineAtPosition(self, pos):
cursor = self.textCursor()
cursor.setPosition(pos)
cursor.movePosition(QTextCursor.StartOfLine)
lines = 0
lines_text = cursor.block().text().splitlines()
lines_pos = 0
for line_text in lines_text:
lines_pos += len(line_text) + 1
if lines_pos > cursor.position() - cursor.block().position():
break
lines += 1
block = cursor.block().previous()
while block.isValid():
lines += block.lineCount()
block = block.previous()
return lines
QTextCursor has a lot of useful methods, like:
int QTextCursor::position () const
Returns the absolute position of the cursor within the document. The cursor is positioned between characters.
and
int QTextCursor::positionInBlock () const
Returns the relative position of the cursor within the block. The cursor is positioned between characters.
This is equivalent to position() - block().position().
I have a text area control on a form that is supposed to accept 5 digit US zip codes. I have assigned the control a keyUp event that checks the number of characters entered until it reaches 5 then forces a new line.
public function forceNewLine(event:KeyboardEvent):void
{
var maxLineChars:int = 5;
var currentLine:int = 1;
var numChars:int;
numChars = (txtList.text.length);
currentLine = Math.round(txtList.text.length / 6);
if (numChars == (maxLineChars * currentLine))
{
txtList.text = txtList.text + "\n";
txtList.setCursorPosition()
//This is not a function I have defined but I think I need too..
}
}
<s:TextArea id="txtList" keyUp="forceNewLine(event)"/>
It works fine except that when the new line is inserted, the cursor moves to the beginning of the textarea. I want it to go to the end.
Try using the selectRange function of the spark textArea.
txtList.selectRange(txtList.text.length, txtList.text.length)