I have an eclipse application wherein I am using a TreeViewer.
There are three columns in the TreeViewer.
On click of a button, I have to align the contents of the all the columns to either right or left.
I tried the following, but I do not see any changes to the FIRST column on the TreeViewer.
The contents of the first column seem to be always left aligned.
rightAlignButton.addListener(SWT.MouseDoubleClick, new Listener() {
#Override
public void handleEvent(Event event) {
TreeColumn[] connectionViewerColumns = connectionViewer.getTree().getColumns();
for(int i = 0 ; i < connectionViewerColumns.length ; i++){
connectionViewerColumns[i].setAlignment(SWT.RIGHT);
}
}
});
Could anyone please let me how it is done, what is my mistake here? It would be very helpful. Thanks in advance
The Javadoc for TreeColumn.setAlignment says:
Note that due to a restriction on some platforms, the first column is
always left aligned.
Related
Ok, so I have a pretty specific and to me quite complicated issue, as I'm a GWT newbie.
I have a GWT flex table, which I use to dynamically add rows, whose cells contain GWT widgets. The row number changes, but the number of columns in static, always 6. Each row contains a cell with a remove button and five cells each with their own textbox.
What I need to do is somehow code a kind of relationship between the textbox in cell 6 of one row and the textbox in cell 5 in the next row (and vice versa).
To illustrate: when something changes in the textbox at [1,6] the content of textbox at [2,5] needs to be overwritten with the same value. If the textbox at [2,5] changes the textbox at [1,6] needs to change as well. I cannot use a button to commit the changes, it needs to happen via onValueChange or Blur or something similar, which doesn't require the user to perform a specific action.
My problem stems mostly from trying to figure out how to address specific cells in the flex table and their content. For the remove button the solution was easy enough with a click event handler, but for this issue I just can't seem to be able to come up with a solution.
Sadly I also cannot provide any of the code which I have up until now, since it's a business secret. I can only give a broad description of the problem like the one above.
EDIT:
Actually, it's probably more a problem of not having much code in terms of this specific problem.
What I have is a flex table, which has initially only the header row. Upon clicking a button below this table the addNewField() method is called, which just contains the creation, setting of default values and adding of the text fields into a new row.
addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}
This way I add entire rows of editable TextBoxes. What I need is a way to influence the values of the 6th column TextBox of a chosen row and the 5th column TextBox of chosen row + 1.
EDIT2: I've tried the dirty option just to see how it would go and somehow the compare inside the if breaks the app. The compiler detects a nullpointerexception and I can't even debug it with breakpoints because it fails to compile and won't start. I can't figure out why though. I threw the code directly into the event for testing purposes, so pardon the ugliness.
TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);
bis.addValueChangeHandler(new ValueChangeHandler<String>()
{
#Override
public void onValueChange(ValueChangeEvent<String> event)
{
allRows: for (int i = 0; i < subs.getRowCount(); i++)
{
for (int j = 0; j < subs.getCellCount(i); j++)
{
if ( subs.getWidget(i, j) == bis )
{
TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
String text = widgetAtColumnSix.getText();
TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(text);
break allRows;
}
}
}
}
});
EDIT: Since you edited your question and you dont want to use EventBus you could iterate over your FlexTable and set your TextBox value depending on your current rowIndex and cellIndex... Its not nice but it should work:
public class CellWidget extends Composite {
private TextBox nameBox;
public CellWidget() {
FlowPanel flowPanel = new FlowPanel();
Button deleteButton = new Button("x");
nameBox = new TextBox();
nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
notifiyTextBox(CellWidget.this, event.getValue());
}
});
flowPanel.add(nameBox);
flowPanel.add(deleteButton);
initWidget(flowPanel);
}
public void setText(String text) {
nameBox.setText(text);
}
}
public void notifiyTextBox(CellWidget source, String string) {
rows: for (int i = 0; i < flextable.getRowCount(); i++) {
columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
if (flextable.getWidget(i, j) == source) {
CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
widgetAtColumnSix.setText(string);
CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(string);
break rows;
}
}
}
}
I still would recommend using an eventbus. To make it even more convenient there is the GWT Event Binder lib, which makes using events a breeze.
So when you change a value in your textbox[2,5] it also fires your CustomEvent. All Widgets, that need to change their textbox value just need to catch...
I have found an interesting issue, and I am wondering if I am misusing or overlooking something. I have a large CellTable that is vertically scrollable. I want to show all the rows at once instead of traditional pagination. So at the bottom of my table I have a row that the user can click to load 50 more rows. I have provided the table with a custom table builder (setTableBuilder(new Builder());). When the user clicks "load more" I query the data, add to the ListDataProvider and call table.setVisibleRange(0, dataProvider.getList().size());.
I put a log statement in the
#Override
public void buildRowImpl(Object rowValue, int absRowIndex) {
}
method to see when it was building rows. I notice that it would build 0-dataProvider.getList().size() (all the rows), then it would build oldLength-dataProvider.getList().size() (the new rows). For instance, if I have 100 rows and then load 50 more it would build 0-150, and then rebuild 100-50. What I want is for it to only build the new rows, obviously.
So I start debugging to see why it is rebuilding the whole table each time. What I found was in com.google.gwt.user.cellview.client.HasDataPresenter it would set the "redrawRequired" flag to true at line 1325:
else if (range1 == null && range0 != null && range0.getStart() == pageStart
&& (replaceDiff >= oldRowDataCount || replaceDiff > oldPageSize)) {
// Redraw if the new data completely overlaps the old data.
redrawRequired = true;
}
So my question is why does it think that the new data completely overlaps the old data?
Am I using something incorrectly, is there a better way? This gets to be quite a slow down when it has to redraw thousands of rows that don't need to be redrawn.
Thanks,
Will
I think that, in this situation, the only way a CellTable can react to the call of the setVisibleRange() method is to redraw all rows.
You have just informed a CellTable that now it has to display new range (0-150 rows) instead of last (0-100 rows). There is no information that rows 0-100 remain unchanged and there is no need to redraw them.
The interesting thing is that you found the new rows are updated (rebuild) twice:
For instance, if I have 100 rows and then load 50 more it would build 0-150, and then rebuild 100-50
I've tried to reproduce this behavior in the smallest example:
public class ListDataProviderTest implements EntryPoint {
private static final int ADD_COUNT = 10;
private int nextVal = 0;
public void onModuleLoad() {
final CellTable<Integer> cellTable = new CellTable<Integer>();
cellTable.addColumn(new TextColumn<Integer>() {
#Override
public String getValue(Integer object) {
return object.toString();
}});
final ListDataProvider<Integer> listDataProvider = new ListDataProvider<Integer>();
listDataProvider.addDataDisplay(cellTable);
RootPanel.get().add(cellTable);
RootPanel.get().add(new Button("Add more...", new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
List<Integer> list = listDataProvider.getList();
for(int i = 0; i < ADD_COUNT; i++)
list.add(nextVal++);
cellTable.setVisibleRange(0, list.size());
}
}));
}
}
But I get all the rows updated once.
Can you confirm that this example reproduces the issue or provide one that is more accurate?
AFAIK a CellTable always redraws all cells.
This is how the renderer from the CellTable works. Although it always redraws all cells, it is in most times still faster than using a FlexTable and only updating a few cells.
I have an cell table and the column data are the check boxes i want align these check boxes to center of that column
i tried withcolumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
and using text-align:middle in css. but it doesn't seem to work .Please help
Column<Person, Boolean> checkColumn = new Column<Person, Boolean>(
new CheckboxCell(true, false)) {
#Override
public Boolean getValue(Person object) {
// check box function
}
};
checkColumn.setHorizontalAlignment(HasAlignment.ALIGN_CENTER);
Works fine for me.
Since you didn't provide much code I can only make several assumptions:
Check that your cell table CSS [if your using custom ones] isn't over writing the alignment
Double check your aligning the right column [happens]
If you are using UiBinder, check to make sure you only set alignment in either your java class or the xml
When I select a row in a CellTable which contains several columns, the whole row gets colored in yellow. It does not depend on which area of the row I click (which column of the row).
What I try to do is to keep the selected row colored in yellow as long as no other row of this very table is selected. At the moment, as soon as I click somewhere else in the browser, the row gets back its original color.
I tried to use a selection model, but this changed nothing. Do you have any advise or is this simply not possible, since the focus is managed by the browser? The behavior is the same in the Google showcase for the CellTable...
The selection model actually does what you want to do: it paints a row blue and the row does not change color if you click elsewhere in the page. (Only when another row is selected)
There are 2 selection models:
One that lets you select only one row, and another one that lets you select multiple rows.
MultiSelectionModel<Row> selectionModel = new MultiSelectionModel<Row>();
table.setSelectionModel(selectionModel);
SingleSelectionModel<Row> selectionModel = new SingleSelectionModel<Row>();
table.setSelectionModel(selectionModel);
The solution of user905374 did actually work. I mentioned in my first post that I already tried the solution with a selectionModel and that it did not work. This was partially true. It does work, but only if the table does NOT contain a CheckboxCell.
Following a working and the not working example. I think this might be a bug, but I am not sure if I miss something.
final CellTable<LicenceDto> licenseTable = new CellTable<LicenceDto>();
final SingleSelectionModel<LicenceDto> selectionModel = new SingleSelectionModel<LicenceDto>();
licenseTable.setSelectionModel(selectionModel);
//--- If I add this column, the selection does work.
Column<LicenceDto, String> workingColumn = new Column<LicenceDto, String>(new TextCell()) {
#Override
public String getValue(LicenceDto object) {
return "Works";
}
};
workingColumn.setFieldUpdater(new FieldUpdater<LicenceDto, String>() {
#Override
public void update(int index, LicenceDto object, String value) {
;
}
});
licenseTable.addColumn(workingColumn);
//--- If I add this column, the selection does NOT work anymore.
Column<LicenceDto, Boolean> notWorkingColumn = new Column<LicenceDto, Boolean>(new CheckboxCell(true, true)) {
#Override
public Boolean getValue(LicenceDto object) {
return object.getEnabled();
}
};
notWorkingColumn.setFieldUpdater(new FieldUpdater<LicenceDto, Boolean>() {
#Override
public void update(int index, LicenceDto object, Boolean value) {
presenter.enableLicense(object, value);
}
});
licenseTable.addColumn(notWorkingColumn);
You can even combine multiple cells and add them to the table (e.g. LinkActionCell etc). As long as there is no CheckboxCell, the blue selection with the SingleSelectionModel does work like a charm. Does anyone see what I do wrong with this CheckboxCell or is there a bug?
UPDATE
It was simply a usage error of me. The problem was that I set handlesSelection to true (second parameter of the CheckboxCell constructor) even thought I don't handle anything. Setting it to false solves the problem.
Bottomline: Use a selection model (e.g. SingleSelectionModel) and do not set the handlesSelection parameter to true of the CheckboxCell constructor to true, if you don't handle the selection by yourself.
You should observe the Showcase demo again. This time use the checkbox on the left most column i.e the first column. On selection the row turns blue indicating the row selection is made. This is when you have SelectionModel set up. Click on the page anywhere outside the CellTable/DataGrid the selection is not changed.
Now, instead of choosing the row via checkbox from first column, you click on a row in any other column. The row turns yellow. Click on the page anywhere outside the CellTable/DataGrid the focus/yellow is lost.
"colored in yellow" indicates row is under focus and being edited and not selected.
Note - you can force row selection by using click events per cell.
Try something like this:
CellTable table;
YourDataObject object = new YourDataObject(...);
SingleSelectionModel<YourDataObject> selectionModel =
new SingleSelectionModel<YourDataObject>();
table.setSelectionModel(selectionModel);
...
table.setSelected(object, true);
Use MultiSelectionModel if you wish more than one line to be highlighted.
Store the selected row's index. When user selects row, change row's style to some "selected-style" appropriate for your case (defined in your css file) and remove selected style from the previously selected row. Also don't forget to update selected row's index.
If you provide some code from the original version I help you out with some code with pleasure.
I am facing problem with lastButton of SimplePager.
I have 3 pages in celltable, Page size=11 (1 empty record + 10 records(with value)), Total record=26.
I used CustomerPager by extending SimplePager.
In 1st attempt 1+10 records display in celltable : Next & Last page button is enabled (First & Prev button disabled) which is correct.
But LastPage button not working... :( Dont know whats the issue... (event not fires)
Strange behavior:
#1 Last page button is working only when I visit to last page(3 page in my case).
#2 Assume I am on 1st page n I moved to 2nd page(Total 3 pages in celltable). that time all buttons are enabled which is correct.
In this case Last button is working but behave like Next Button
My GWT application integrated into one of our product so cant debug it from client side.
May be index value is improper in setPage(int index) method from AbstractPager
Code flow is as follows for Last button
//From SimplePager
lastPage.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
lastPage();
}
});
#Override
public void lastPage() {
super.lastPage();
}
// From AbstractPager
/**
* Go to the last page.
*/
protected void lastPage() {
setPage(getPageCount() - 1);
}
protected void setPage(int index) {
if (display != null && (!isRangeLimited || !display.isRowCountExact() || hasPage(index))) {
// We don't use the local version of setPageStart because it would
// constrain the index, but the user probably wants to use absolute page
// indexes.
int pageSize = getPageSize();
display.setVisibleRange(pageSize * index, pageSize);
}
}
or may be some conditions false from above code(from setPage())
actual record = 26 and 3 Empty record (1st Empty record/page)
May b problem with dataSize :|
How I can check number of pages based on the data size?
?
How can I solve this problem?
edit: I found out that the default constructor of the pager doesn't give you a "last" button, but a "fast forward 1000 lines" button instead (horrible, right?) .
call the following constructor like so, and see your problem solved:
SimplePager.Resources resources = GWT.create(SimplePager.Resources.class);
SimplePager simplePager = new SimplePager(TextLocation.CENTER, resources , false, 1000, true);
the first "false" flag turns off the "fastforward button" and the last "true" flag turns on the "last" button.
also the last button will work only if the pager knows the total amount of records you have.
you can call the table's setRowCount function to update the total like so:
int totalRecordsSize = 26; //the total amount of records you have
boolean isTotalExact = true; //is it an estimate or an exact match
table.setRowCount(totalRecordsSize , isTotalExact); //sets the table's total and updates the pager (assuming you called pager.setDisplay(table) before)
if you are working with an attached DataProvider, than all it's updateRowCount method instead (same usage).
Without seeing more of your code, this is a hard question to answer as there could be multiple places where things are going wrong.
I would make sure you call setDisplay(...) on your SimplePager so it has the data it needs calculate its ranges.
If you can't run in devmode, I recommend setting up some GWT logging in the browser (write the logs to a popup panel or something, see this discussion for an example).
I think the problem is related with condition in the setPage(). Try putting SOP before if condition or debug the code
Only added cellTable.setRowCount(int size, boolean isExact) in OnRange change method AsyncDataProvider. My problem is solved :)
protected void onRangeChanged(HasData<RecordVO> display) {
//----- Some code --------
cellTable.setRowCount(searchRecordCount, false);
//----- Some code --------
}