Vaadin 23 Grid only grid-cell-content counts as hitbox for selecting a row - vaadin

The problem appears in the vaadin grid in the version Vaadin 23.3.0.
I noticed, that clicking on any part of a row does not always trigger the row-select. In marked the hitbox in the image below. Clicking anywhere in the cell will trigger the itemClickEvent, but only the content part (green area in the provided image) triggers the select.
grid with hitbox highlighted
Grid<Client> grid = new Grid<>();
grid.addColumn(Client::getName).setHeader("name");
grid.addColumn(Client::getOutput).setHeader("output");
ArrayList<Client> list = new ArrayList<>();
list.add(new Client("test 1", "output 1", null));
list.add(new Client("test 2", "output 2", null));
list.add(new Client("test 3", "output 3", null));
list.add(new Client(null, "output 4", null));
list.add(new Client("test 5", null, null));
list.add(new Client(null, null, null));
grid.setSelectionMode(Grid.SelectionMode.SINGLE);
grid.setItems(list);
Given the explanation in the vaadin documentation:
In single selection mode, the user can select and deselect rows by clicking anywhere on the row.
I except this exact behaviour.
After noticing the problem, I created the grid, to which I provided code and image above, to narrow down a possible cause.

Issue was fixed with vaadin 23.3.2:
https://github.com/vaadin/web-components/pull/5157

Related

How to allocate more space to Option's text in SettingsPane?

If I create a settings pane and add new DefaultOption(...) to it with an icon and text then the controller on the right takes more space than it needs and trims the text in the middle.
Option<BooleanProperty> antiAliasingOption = new DefaultOption<>(MaterialDesignIcon.BLUR_OFF.graphic(),
"Anti-aliasing", "Toggle anti-Aliasing", null, new SimpleBooleanProperty(), true);
You can see that there's a lot of space (red line) for the toggle button which is not used and the text is cut off. I want the controls to be justified to the right like in a border pane where the center takes all unallocated space.
If you use Scenic View to inspect the Settings control, you will find that for every Option there is an HBox that contains a left HBox for the icon, a central VBox for the text and a right HBox for the editor.
All these containers have style classes, so an easy way to modify any of them on runtime is by using lookups.
As for the right HBox, you can look for the secondary-graphic and then set the preferred width:
public BasicView(String name) {
super(name);
Option<BooleanProperty> antiAliasingOption = new DefaultOption<>(MaterialDesignIcon.BLUR_OFF.graphic(),
"Anti-aliasing", "Toggle anti-Aliasing", null, new SimpleBooleanProperty(), true);
SettingsPane settings = new SettingsPane(FXCollections.<Option>observableArrayList(antiAliasingOption));
settings.setSearchBoxVisible(false);
setCenter(settings);
setOnShown(e -> {
HBox rightBox = (HBox) settings.lookup(".secondary-graphic");
rightBox.setPrefWidth(60);
});
}
Another option is to override the default styling within your css file:
.settings-pane .options-grid > .option-row > .secondary-graphic {
-fx-pref-width: 60;
}

Table merge cells - Vaadin

I'm Creating table with Vaadin. Some of the cells are repeating. So I want them to merge in one cell, as you can see on the image:
The first image show how the table looks now, and the second is how I want to look with merged cells.
I'm using this code:
Table table = new Table(AppData.getMessage("menu.report2"));
table.addContainerProperty(tableHeaders[0], String.class, null);
table.addContainerProperty(tableHeaders[1], String.class, null);
table.addContainerProperty(tableHeaders[2], String.class, null);
table.addContainerProperty(tableHeaders[3], String.class, null);
List<User> employeeList = employeeDAO.findAllEmployees();
int i;
for (i = 0; i < employeeList.size(); i++) {
User employee = employeeList.get(i);
table.addItem(new Object[]{
CaseStatus.OPEN,
tasksDAO.countTasks(CaseStatus.OPEN),
employee.getFirstAndLastName(),
tasksDAO.countTasks(employee, CaseStatus.OPEN)},
i);
}
for (int j = 0; j < employeeList.size(); j++) {
User employee = employeeList.get(j);
table.addItem(new Object[]{
CaseStatus.CLOSED,
tasksDAO.countTasks(CaseStatus.CLOSED),
employee.getFirstAndLastName(),
tasksDAO.countTasks(employee, CaseStatus.CLOSED)},
i + j);
}
table.setPageLength(table.size());
addComponent(table);
setComponentAlignment(table, Alignment.TOP_CENTER);
setMargin(true);
I think, this is not possible in "normal way". But I have an idea how to simulate this.
First solution:
You could simply use GridLayout to build grid as you want. Then nothing limit your imagination beside size of such grid. It shouldn't be to big (also pointed here).
Second solution:
Another advice is a bit crazy.
Disable Table/Grid stripes.
In group of similar cells just fill only first row. Left rest blank (or space in string).
Then you dispose of repeated data (from your first and second column), but you can't alignment them vertically (the text will stay at top - first row from group).
Third solution:
Check Add-ons list. For example ItemGrid.

add label to check box item in smart gwt

I need to add a label to my checkbox in smart GWT. For example, I have three fruits: apple, mango and banana. How can I add the label Fruits as heading. I am also unable to use CheckboxGroup.
CheckBox check1 = new CheckBox();
check1.setBoxLabel("Classical");
CheckBox check2 = new CheckBox();
check2.setBoxLabel("Rock");
check2.setValue(true);
CheckBox check3 = new CheckBox();
check3.setBoxLabel("Blue");
CheckBoxGroup checkGroup = new CheckBoxGroup();
checkGroup.setFieldLabel("Music");
checkGroup.add(check1);
checkGroup.add(check2);
checkGroup.add(check3);
Hy Abhaya, first of all i don't know what version of smart GWT you use but i can see that this is not smart GWT, its more like gwt component and that CheckBoxGroup is some awt component.
If You want to use smart GWT check box component then use CheckboxItem widget, if its item that means you need to use dynamic form.
So lets say:
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.DynamicForm;
CheckBoxItem item1 = new CheckBoxItem();
item1.setTitle("Classical");
CheckBoxItem item2 = new CheckBoxItem();
item1.setTitle("Rock");
So now we have 2 check box items, wee need to put them in dynamic form like this (I set border so u can see what happens):
DynamicForm box = new DynamicForm();
box.setBorder("1pt solid red")
box.setFields(item1,item2);
Lets draw that:
box.draw();
This is output:
drawn dynamic form
Ok now we need title, best way is to add lable before dynamic form. Now dynamic form is root element, lets put it in some layout (new package), layout will be vertical so for every new member it will be one beneath other:
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.Label;
Label title = new Label();
title.setContents("Music");
title.setHeight(20);
VLayout lay = new VLayout();
lay.setBorder("1pt solid black");
lay.addMember(title);
lay.addMember(box);
So wee added title in layout then dynamic form named "box", now u don't need to draw() box, only layout because that layout consists of label and box that will be automatically drawn:
lay.draw();
And output is this:
drawn vertical layout
Here is the little bit styled look:
Styled look
Entire code:
CheckboxItem item1 = new CheckboxItem();
item1.setTitle("Classical");
CheckboxItem item2 = new CheckboxItem();
item2.setTitle("Rock");
CheckboxItem item3 = new CheckboxItem();
item3.setTitle("Metal");
CheckboxItem item4 = new CheckboxItem();
item4.setTitle("House");
DynamicForm box = new DynamicForm();
box.setFields(item1,item2, item3, item4);
box.setWidth100();
box.setHeight100();
box.draw();
Label title = new Label();
title.setContents("<h3>Music:</h3>");
title.setHeight(20);
VLayout lay = new VLayout();
lay.setMargin(20);
lay.setBorder("1pt solid black");
lay.setPadding(10);
lay.setBackgroundColor("#e6e6e6");
lay.addMember(title);
lay.addMember(box);
lay.draw();
In property setContents() u can use HTML tags and CSS
I hope it helps.
Regards, Jakov A.

How to add a click Listener to a table's cell in vaadin?

I created a multiselectable table in vaadin, but I can't select only a cell in this table when I click it selects all row.
Is there any way of selecting only a cell of a row ?
The title of the question doesn't reflect the actual question inside
Is there any way of selecting only a cell of a row ?
No. The whole point of a Vaadin table is to reflect rows of data in a tabular form. Setting a table to selectable keeps track of the itemIds of the selected rows with the table
You might be able to simulate selecting cells by using a ColumnGenerator in the table, and adding a listener to the generated component. Removing the listener may be tricky, however.
Alternatively, you may wish to simply generate components in a GridLayout and keep track of the selected cells yourself.
Ultimately, the approach here really depends upon exacly what you are trying to achieve.
It depends on what you're trying to accomplish. (Your question title and your question details are addressing two different questions.) If you're wondering whether or not you can target a specific cell and add a click listener to it, then yes, of course you can:
//initial layout setup
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
//Create a table and add a style to allow setting the row height in theme.
final Table table = new Table();
table.addStyleName("components-inside");
//Define the names and data types of columns.
//The "default value" parameter is meaningless here.
table.addContainerProperty("Sum", Label.class, null);
table.addContainerProperty("Is Transferred", CheckBox.class, null);
table.addContainerProperty("Comments", TextField.class, null);
table.addContainerProperty("Details", Button.class, null);
//Add a few items in the table.
for (int i=0; i<100; i++) {
// Create the fields for the current table row
Label sumField = new Label(String.format(
"Sum is <b>$%04.2f</b><br/><i>(VAT incl.)</i>",
new Object[] {new Double(Math.random()*1000)}),
Label.CONTENT_XHTML);
CheckBox transferredField = new CheckBox("is transferred");
//Multiline text field. This required modifying the
//height of the table row.
TextField commentsField = new TextField();
//commentsField.setRows(3);
//The Table item identifier for the row.
Integer itemId = new Integer(i);
//Create a button and handle its click. A Button does not
//know the item it is contained in, so we have to store the
//item ID as user-defined data.
Button detailsField = new Button("show details");
detailsField.setData(itemId);
detailsField.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
// Get the item identifier from the user-defined data.
Integer iid = (Integer)event.getButton().getData();
Notification.show("Link " +
iid.intValue() + " clicked.");
}
});
detailsField.addStyleName("link");
//Create the table row.
table.addItem(new Object[] {sumField, transferredField,
commentsField, detailsField},
itemId);
}
//Show just three rows because they are so high.
table.setPageLength(3);
layout.addComponent(table);
It might be beneficial to examine the documentation.

Tabbing from a choicebox to the next element in JavaFX

How do I get a choicebox in JavaFX to pass focus to the next element when I press tab?
I've tried setting the focus traversable to true but that didn't appear to do anything.
cbSoils.setFocusTraversable(true);
I've tried setting the key press or release to change focus but it is triggered when I tab TO the choicebox from the previous element.
cbSoils.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
// On tab press send the focus to tfAddress
if(event.getCode() == KeyCode.TAB){
tfAddress.requestFocus();
}
}
});
Anyone have a better idea?
Which version of FX do you use? I've tested with JavaFX 2.1 b18 and ChoiceBox passes focus on Tab clicks in next code:
ChoiceBox cb = new ChoiceBox(FXCollections.<String>observableArrayList("item 1", "item 2", "item 3"));
HBox root = HBoxBuilder.create().children(cb, new Button("next"), new Button("nextnext")).build();
stage.setScene(new Scene(root, 200, 200));
stage.show();

Resources