Can you setup a Swing TableColumn to automatically truncate/remove the left/leading characters of a cell when resizing? - truncation

I am needing to have the elipses (...) at the beginning/left edge of a cell rather than the end/right edge when the value is too long for the cell width, whether when initially loaded or when resizing the column.
I've tried to handle this by right justifying the column with the code below, hoping it would handle the resizing in the same manner. However, that is not the case. It right justifies the values but continues to truncate the right size of the value when too large.
DefaultTableCellRenderer r = new DefaultTableCellRenderer();
r.setHorizontalAlignment(SwingConstants.RIGHT);
appCol.setCellRenderer(r);

Related

I want to print 90,000 toString lines to a TextField in JavaFX. It's taking super long. Any fixes?

I'm using an iterator to iterate through a Linked List of 90,000 Book Objects. Each of them have titles, ISBNs, authors and prices.
In my GUI, I have a text field, and a button which would display these 90,000 Books.toString() in the text field. The user can search for a book, remove a book, or update fields in the book, so I feel like the user should be able to see all the books and all their fields.
The problem is, this takes way too long, I get the beach ball of death and it never loads. When I change the for loop to 10 or 1000, it works fine. Must be an O(n^2), right?
Or is there some other problem?
Thank you.
#FXML
void refreshListButtonPressed(ActionEvent event) {
listBooksTextArea.clear();
bookbag.myIter.reset();
for(int i = 0; i < 1000; i++) {
listBooksTextArea.appendText(bookbag.myIter.getCurrent().getData().toString() +
"\n");
bookbag.myIter.nextLink();
if(bookbag.myIter.atEnd()) {
listBooksTextArea.appendText(bookbag.myIter.getCurrent().getData().toString()+
"\n");
}
}
}
Ideally, I wouldn't even use a for loop, I'd use while (!bookbag.myIter.atEnd()), but the for loop proves to me the code works and the size or efficiency is the issue.
Your code is inefficient in a couple of different ways:
The TextArea stores the text as a String, which is an immutable object. Consequently, each time you call appendText(...) a new String is created, by copying the existing characters plus the new characters to a new string object. Since the size of the string grows essentially linearly on each iteration, this becomes an O(n^2) operation.
The TextArea creates a UI node for the entire text. UI nodes are generally quite expensive, and here you are creating a huge node to lay out, style, and display all 90,000 lines of text, the vast majority of which are not visible on the screen at any given time.
You can at least partially fix the first by concatenating the string in a StringBuilder, and then setting the text of the TextArea once, though this will not fix the second issue.
The preferred approach here is to use a virtualized control, such as a ListView or TableView. These controls create a limited number of cells (one per row in the case of a ListView, one per column per row in the case of a TableView), essentially creating cells only for the visible data. As the user scrolls around, cells are reused to display new data. This greatly enhances performance.
Additionally, these controls probably allow for a better interaction between your UI and your actual data. Using a TableView, each row would represent a Book object, and each cell in the row a property of that object. If you make your table editable, you can validate changes to each cell, i.e. on a property-by-property basis. Using a text area, you would need to carefully parse the changes to the text to make sure the result was a valid list of books.
I would generally recommend working through a tutorial on TableView, e.g. this one. In brief, create a Book class using JavaFX Properties. Create a TableView<Book> and configure the columns to point to appropriate properties using the setCellValueFactory(...) method. You can make the data editable by supplying, for example, a TextFieldTableCell in the cell factory for the column. Then simply add your Book instances to the table's items list.

Does anyone know why an object would miss a property?

We have a script that export our Indesign documents to HTML and one of the routine is to export tables. In this script we go throught each Tables->Rows->Cells and evaluate some of the properties (i.e. bottomEdgeStrokeType, topEdgeStrokeType, etc...) and transport them to HTML.
Now yesterday we had problem converting one particular document because some cells were missing the "bottomEdgeStrokeType" property entirely. I've discovered this by outputting the properties of each cells and compare the faulty ones with the others.
This line bellow was trowing the error: "Invalid object for this request.".
var cellType = cell["bottomEdgeStrokeType"];
Now, to fix this I've wrapped this around a try catch block to handle the case when it's not there, but now what is puzzling me is how on earth can Extendscript instantiate an object with missing properties?
Indesign version: CS5.5
A property is not only 'undefined' if it cannot exist at all (such as asking for the parent text frame for a character in overset text), but InDesign's Javascript engine also fails to return a reasonably accurate result for multiple values.
If you ask for "the" point size of a paragraph, where this paragraph contains multiple sizes, poor ID does not consider to return something like CONSTANT.Mixed, or the first value only, or (what I might have preferred) an array of the values; it returns undefined instead.
So how can a single table cell have multiple bottom strokes? If the cell underneath it is split into multiple cells, and one has a "top" stroke but the other has not.
It's difficult to recommend an adequate solution. You could first test if the current cell is "merged" (as far as InDesign's internal table model is concerned) with columnSpan; and if so, iterate over the number of columns spanned and test the next row's cells for their top stroke, which in theory should match the bottom stroke of the cell above. (I find myself wondering if this is always true. ID's table model is ... weird. It's not entirely like a HTML table, despite the functional overlaps.)
If columnSpan is greater than 1 and equal to the number of cells immediately below the current one, you could test if all of their "top" values are the same and if so use that value. (I never tested this so ID's table model may simply fail because a cell is merged, regardless of same-values or not.)
One could attempt to flag this cell's next row to output "top" strokes as well -- but alternating top and bottom strokes may not align nicely in CSS, side to side. Perhaps it's best to translate only the first top stroke value to "the" bottom stroke property for your current cell, and fix up manually where needed (how?) or, a reasonable action, hope that no-one will ever notice it.

ZedGraph scrolling left truncates data

I am using a ZedGraphControl in a WindowsForms project in C#. The ZedGraphControl is V5.1.5.
The data in the control is static and I add it all before the form is shown. The X axis of the data consists of numbers indicating seconds offset from the beginning. in other words from 0 to some number of seconds.
I want to initially show the last 5 seconds, but provide a horizontal scrollbar so the user can scroll back and forth. I set the "graphPane.XAxis.Scale.Max = maxX;" where maxX is the largest X value in my data. I set the "graphPane.XAxis.Scale.Min = maxX - 5;".
The data starts off displaying the way I want it, but when the user scrolls the horizontal bar, bizzar behavior occurs.
As you drag the thumb of the scrollbar to the left, the beginning of the data shown in the grid moves to the lower values as expected, and the thumb of the scrollbar moves to the left, but the right edge of the thumb stays at the right of the scrollbar and you cannot move back to the right. It is as if the data to the right of the viewing range gets truncated as you scroll left.
I cannot find any reason for this nor any way to control it. Does anyone have any ideas about this behavior?
Ok, found it myself.
I found a fine article that describes scrolling:
Add a ScrollBar
In it the author specifically says "the scrolling will be wacky because the scrollable range has not been set".
I used the sample "Manually Setting the Scroll Range" and the part that I was missing is setting the zedGraphControl1.ScrollMinX and zedGraphControl1.ScrollMaxX properties. Once I defined these values everything started working as expected. I also found that in my case, the value of zedGraphControl1.IsAutoScrollRange had no effect, but I left it set to false to be consistent with the example. This would probably have an effect if the dataset is dynamic.

Cocoa Autolayout - Why can't I delete or modify the (purple) width constraint on a Text Field?

I'm building a simple application using autolayout, and I've run into a strange situation. I place a Text Field in an empty part of a large open view so it's not affected by anything but the super view, but when I try to modify the "Width" constraint to be >= instead of ==, it creates a new constraint and refuses to modify the old one. I can't delete it, or change any of its attributes, because it just creates a new one.
Here is a comparison of the two constraints, the purple one being the stubborn one, and the blue one being the newly created one.
Why is the purple rounded one not modifiable?
I have worked around the presence of undeletable-but-unwanted constraints in IB by setting their priority to 1. Doesn't seem like the Right Thing to do, but sometimes I'm not smart enough to be a Cocoa developer.
My problem had to do with with fact that there weren't enough other constraints added that the width would ever be forced to change. When I added more other constraints (such as leading and trailing space), I was then able to alter the purple constraint (in fact, it disappeared and I had to add my own).
It seems strange that you cannot add your own constraints unless there is a possibility of them being broken, but I guess that's the way it's been integrated into IB in some cases.
Lowering the priority of the purple constraints will also make them editable.
I had a similar scenario, where there were two multiline labels. Based on the content size, both should resize.
When the first label resized, it was overwriting the second label because the second one had a Vertical Space constraint( "Top Space to SuperView = 40". it's a system default constraint - purple colour) which I was not able to delete/modify.
If I tried to modify it as "Top Space to SuperView >= 40", it'd be changed to a user constraint( blue colour) and a new purple constraint "Top Space to SuperView = 40" would be created automatically.
I guess this could be the reason:
When I tried to change the constraint to "Top Space to SuperView >= 40", the label's default position is undefined : >= doesn't specify a default position. It specifies only a 'range of positions'. Then I added a new constraint by selecting both the labels together and setting the space between them as a constant.
Now, since the first label had a definite position (vertical space = 15) from the top border and the second label was 5 points below the first one, the second label got a vertical position defined. I was able to delete the purple vertical space constraint.
Now, if I remove the constraint between the two labels, the second one will no more have the defined position and system will automatically create a purple constraint for the label.
When you right-click on the constraint, select "Promote to user constraint". Next time you click on constraint, you will be able to delete it as now it is in the hands of the user/developer.

List Control Adds a Space for an Image to Column 0 When Subsequent Columns Have Images

I’ve come across a problem with Windows list controls (I am specifically using MFC, but it looks like it applies to all list controls in the Windows common controls library).
In my specific case, I want to create a list control that has two or more columns. The first column (0) is text-only and is used to allow the user to jump to entries by typing the text in that row. Column two (or three, or four, or whatever) has an image (or an image and text; either way).
This much is all well and good and can be done easily without problem, however the final list control then ends up having a space to the left of the text in column 0 (it may be on the right on an RTL system). This spacer appears to be reserved for an image and I cannot figure out a way to prevent it. (Arranging the specific order of the columns did not change anything.)
Looking around, I found some other people complaining of the same thing, specifically this thread which leads to this thread. The proposed solution does not work because as was stated, simply shrinking the width of column zero merely cuts off the text rather than the image spacer (plus, you then have to prevent and/or process any changes to column widths that the user tries to make).
Does anyone have any ideas of how to fix this bug short of writing a list control from scratch or using one of the too-fancy grid controls on CodeProject/CodeGuru/etc.?
Thanks a lot.
Did you try to change the iIndent member of the LVITEM struct? MSDN says this:
iIndent Version 4.70. Number of image widths to indent the item. A
single indentation equals the width of
an item image. Therefore, the value 1
indents the item by the width of one
image, the value 2 indents by two
images, and so on. Note that this
field is supported only for items.
Attempting to set subitem indentation
will cause the calling function to
fail.
Column 0 is special in a ListView. As soon as you assign a small image list to the ListView, the control expects you to show an image in column 0, so it leaves space for it.
Solutions:
make column 0 zero-width, give it the value you want the user to be able to type. Column 1 becomes your "first" text column. Columns 2+ are for your images. You need full row select style for this to work. Yes, you have to prevent the user from resizing column 0. Yes, that is a pain.
make a column that does have an image to be column 0 and use LVM_SETCOLUMNORDERARRAY to rearrange the display order
owner draw the items.
give column 0 an icon (just to cover all bases)

Resources