I created a grid that has four columns. The first column shows a name, the other three columns represent different roles. Each of those three columns is filled with check boxes in order to assign a specific role to a specific name. That's as far as i have come so far.
In each column and in each row there should only be one selected checkbox allowed. So in total i do have exactly one selection per checkbox column. How do i implement this?
Edit: I realize I might have misunderstood the question entirely. If you want to have 3 columns, with each having multiple CheckBoxes where only 1 can be selected per column, then you should use a RadioButtonGroup in each column and bind each to a different Enum field of your griditem class.
Instead of showing how to do three columns with a CheckBox in each, while only one CheckBox can be selected, I will show a different way to achieve the same information about the item.
The reason for this is the solution that what you want to achieve is not easily doable, since each CheckBox is defined in a scope that does not know the other Checkboxes of the same item. Therefore you would need to implement your only-one-selected rule inside the itemclass' setters, which is not optimal. I mean, it is possible, but I'd rather change the structure to something more apt. Usually you don't want to put this kind of business logic into your bean classes.
How would I solve the problem at hand?
Create a new Enum, which will replace all 3 boolean fields in your item class. Now in your grid you will only need one column for a ComboBox to select the enum.
I chose an Enum because this matches your needs here perfectly. With an Enum, you may have several options, but you can select only one (or none).
To better show what I mean, let's use an example Class for the Grid items, Foo. Your version has 3 booleans which your three grid-CheckBoxes are bound to. Let's call them isA, isB, isC.
// your version of the griditem class
public class Foo {
private boolean isA, isB, isC = false;
// constructor, getters, setters
}
// how the columns are added in the grid (approximately) (without editor):
Grid<Foo> grid = new Grid<>();
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isA());
checkBox.addValueChangeListener(event -> item.setA(event.getValue()); // inside setA() method you need to set isB and isC to false if the new value is true. No good!
return checkBox;
});
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isB());
checkBox.addValueChangeListener(event -> item.setB(event.getValue()); // inside setB() method you need to set isB and isC to false if the new value is true. No good!
return checkBox;
});
grid.addComponentColumn((item) -> {
CheckBox checkBox = new CheckBox();
checkBox.setValue(item.isC());
checkBox.addValueChangeListener(event -> item.setC(event.getValue()); // inside setC() method you need to set isB and isA to false if the new value is true. No good!
return checkBox;
});
And here is how it would look after my changes
public class Foo {
private AbcEnum abcEnum = null;
// constructor, getters, setters
}
public Enum AbcEnum {
A,
B,
C;
}
// how the columns are added (without editor):
Grid<Foo> grid = new Grid<>();
grid.addComponentColumn((item) -> {
ComboBox<AbcEnum> comboBox = new ComboBox<>();
comboBox.setValue(item.getAbcEnum());
comboBox.addValueChangeListener(event -> item.setAbcEnum(item.getValue()));
return comboBox;
});
I wrote "without editor" in the comments about adding the column, because this code will add the ComboBox/CheckBox as clickable and functional components for each grid item, without needing to open the editor for an item to change the values. If you are indeed using an editor, you can add these functional inputs as editorComponents (and bind them to the editor-binder instead of using setValue and addValueChangeListener), and show only the current value in the normal columns (not editable - therefore no inputs like CheckBox or ComboBox are required)
Related
I am a little bit stuck with such an easy problem. I am using DynamicReports and I want to hide whole row if column value is null. As I know, DynamicReports is based on JasperReports and it's possible there to do that by checking TextField's option "Remove line when blank". How can I do that in Dynamic?
Components, which I use:
TextColumnBuilder, ColumnGroupBuilder, JasperReportBuilder
I want to hide whole row if any of my TextColumns would be null.
OK, after some thoughts, I found that this problem could be resolved in other way.
We gonna use column, group etc property setPrintWhenExpression(DRIExpression expression)
1. Create class, which will handle, print or not to print the row. Dynamic has the abstract class for doing this:
public class ShowExpressionDynamicReports extends AbstractSimpleExpression<Boolean> {
private String fieldName;
public ShowExpressionDynamicReports(String fieldName) {
this.fieldName = fieldName;
}
#Override
public Boolean evaluate(net.sf.dynamicreports.report.definition.ReportParameters reportParameters) {
return reportParameters.getValue(fieldName) != null;
}
}
You should extend AbstractSimpleExpression in order to pass it as parameter to methods which are listed below.
So, the column value is printed if evaluate(ReportParameters rp) returns true.
I've also added field fieldName which allows me to print (or not) column due to other's column state.
2. Add property to your
column:
setPrintWhenExpression(DRIExpression expression)
group:
.setPrintSubtotalsWhenExpression(DRIExpression expression)
or
setFooterPrintWhenExpression(DRIExpression expression)
or
setHeaderPrintWhenExpression(DRIExpression expression)
Depends on what you want to hide.
Example:
We have 2 columns in our report: Product and ProductCount columns. I would like to hide Product column if ProductCount is null (we have no information for this Product).
So, to do that i will add property PrintWhenExpression to Product column
TextColumnBuilder<String> productColumn = col.column("Product", "Product", type.stringType())
.setPrintWhenExpression(new ShowExpressionDynamicReports("ProductCount"));
I'm dynamically generating a form based on data received from an RPC call into a FormFieldData object which has details about the field to be rendered such as, Field Name, expected length and type of input, if the field is a required field or not and valid input Regex in some cases etc.
I'd like to be able to perform validation on the field depending on above attributes.
Here's an example:
private void renderTextField(FormFieldData field){
FormGroup formGroup = new FormGroup();
FormLabel formLabel = new FormLabel();
if(field.isRequired()){
formLabel.setText(field.getName()+"*");
}else{
formLabel.setText(field.getName());
}
formGroup.add(formLabel);
TextBox textBox = new TextBox();
textBox.addChangeHandler(new ChangeHandler(){
#Overrride
public void onChange(ChangeEvent event){
//TODO - find a way to get the text entered in TextBox
// and perform validation on it
//and set the TextBox Style to "Validation-error"
}
});
formGroup.add(textBox);
form.add(formGroup);
}
There're similar methods to render dropdowns, Numeric fields, radio button fields etc. which would need similar validation.
The problem is I can't access the text from the TextBox inside the onChange method without declaring it final, which I can't do because I might be rendering multiple text fields. I don't know much about ChangeEvent and if there's a way to get the text from the that.
I'd really appreciate any pointers to a way to do this in real time as the data is entered into the form, other than having to iterate through the fields and their corresponding FormFieldData object when the form is submitted.
First off, you can make the variable final, no problem.
If you don't want to do that for whatever reason, you can get the TextBox from the event like this:
textBox.addValueChangeHandler(new ValueChangeHandler(){
#Overrride
public void onValueChange(ChangeEvent event){
TextBox box = (TextBox) event.getSource();
// Do whatever you need to here
}
});
You are probably also looking for ValueChangeHandler instead of ChangeHandler.
I have been assign to one struts2 project and its one of jsp contains more than 100 radio buttons and they have handled in statically not dynamically. As jsp contains 100 radio buttons so I am able to see the below list of radio buttons catches in actions with their getter and setter
List selectRadioList001
List selectRadioList002
List selectRadioList003
List selectRadioList004
etc
List selectRadioList100
I want to add these radio button in a list dynamically iterating through 1 to 100 something like below but when I try to access the variable like "searchBoxSelectRadioList"+i then it is pretending like a simple string. I want it to be like a List as shown above.
public class SelectRadioListPOJO {
private List<TicketDesignUtil> selectRadioList;
public List<TicketDesignUtil> getSelectRadioList() {
return selectRadioList;
}
public void setSelectRadioList(List<TicketDesignUtil> selectRadioList) {
this.selectRadioList = selectRadioList;
}
}
Action code:
List<SelectRadioListPOJO> selectRadioListPOJOList = new ArrayList<>();
SelectRadioListPOJO selectRadioListPOJO;
for (int i = 1; i <= 100; i++) {
selectRadioListPOJO = new SelectRadioListPOJO();
selectRadioListPOJO.setSelectRadioList("searchBoxSelectRadioList"+i);// ERROR
selectRadioListPOJOList.add(selectRadioListPOJO);
}
It's not clear what you're asking.
You can't pass arbitrary values to methods; setSelectRadioList takes a list of TicketDesignUtil.
If your action doesn't have getters and setters for all of those radio buttons then you should resort to accessing the request parameters directly, for example, via ParameterAware.
You would then access the radio button parameters by name from the injected parameter map.
Notes:
It's not "pretending" to be a simple string, it is a simple string, because... well, because it is.
Your for loop is wrong; I corrected it in your question to avoid others commenting on it. The POJO should be added to the POJOList inside the loop.
Naming is funky; just call it selectRadioListPojos. Better yet, name it something domain-specific: variables should be semantically meaningful, not just a description of the class(es) involved.
These shouldn't be static in the first place, but a map or array.
I'd like to create a custom column for my vaadin table. All items should have a column with a checkbox. In order to have this column, I created a transient variable, which name is "selected". When the table makes its columns, the table.setTableFieldFactory() runs, but "selected" is not presented in the propertyIds' list.
table.setTableFieldFactory((container, itemId, propertyId, uiContext) -> {
if("selected".equals(propertyId)) {
CheckBox checkBox = new CheckBox();
checkBox.addValueChangeListener(event -> selectListener((Boolean)event.getProperty().getValue()));
return checkBox;
}
return null;
});
The questions are, how to create a custom field for transient variable? How should I add my transient variable to propertyIds' list? What Am I doing wrong?
Found out what was wrong. This table was a CustomTable, which was made by my mate. It has a column generator on Boolean.class. So when it was making the columns, its overwrote my definition.
I'm working on a Java application in Eclipse that pulls data out of a MySQL database. I'm populating a combo box with data. So far I can get the value of a field to show up but I can't figure out how to store the database row's unique ID value. One suggestion I found was to create a custom class that could store both the display value and the id value. However, this doesn't appear to work with the Eclipse widget combo object. This is what I have
import org.eclipse.swt.widgets.Combo;
class myClass {
public static void createCombo(ResultSet rs) {
Combo c = new Combo();
while(rs.next()) {
int id = rs.getInt("id");
int display = rs.getString("display");
comboitem ci = new comboitem(id,display);
c.add(ci);
}
}
}
class comboitem {
private int _id;
private String _display;
public comboitem(int id, String display) {
this._id = id;
this._display = display;
}
public int getID(){
return _id;
}
public String toString(){
return _display;
}
}
The above errors at c.add(ci). It's expecting a string, not an object. Is there a way to do this?
No idea but, I've always felt it was a bad move anyway.
Create a collection/list of comboitems, populate the widget from comboitem.display.
Index in the combo is index in your collection.
Means you can unit test lots of things without a UI or with simple mock, and it keeps you away from desktop specific implementations in your data models.
The combo widget displays an array of String's, so simply concatenate the two values if you want to display them both. I am not sure what your end goal is from your question. If it is to select the appropriate comboitem based on the combo selection, then store the comboitems in a Map and use the combo values as the keys.
Another approach is to use a jface ComboViewer which allows you to set the input to a complex object, provide a label provider and more complex controls around the Combo widget.
You should also look up some information on java coding conventions and not access your database directly from the UI unless this is a very simple application.
You can find some examples on using most SWT widgets here.