Enum based Combobox - java

cmbSablonSecim = new ComboBox<>();
cmbSablonSecim.setItems(EnumSablonSecim.values());
My combo box --> TUMU,GRAFIK,DAGILIM
I want fill my combobox with Enum->islemAdi
Combobox --> Tümü,Grafik,Dağılım (Enum->islemAdi)
public enum EnumSablonSecim {
TUMU(0, "Tümü"),
GRAFIK(1, "Grafik"),
DAGILIM(2, "Dağılım")
;
private final Integer islemKodu;
private final String islemAdi;
private EnumSablonSecim(Integer islemKodu, String islemAdi) {
this.islemKodu = islemKodu;
this.islemAdi = islemAdi;
}
public Integer getIslemKodu() {
return islemKodu;
}
public String getIslemAdi() {
ResourceBundle messages = I18n.getInstance(this.getClass());
if (messages.containsKey(islemAdi)) {
return messages.getString(islemAdi);
} else {
return islemAdi;
}
}
public static EnumSablonSecim get(Integer islemKodu) {
for (EnumSablonSecim enumSablonSecim : EnumSablonSecim.values()) {
if (enumSablonSecim.islemKodu == islemKodu) {
return enumSablonSecim;
}
}
return null;
}
}
My combobox must return (islemAdi).is it possible or not? Thank you...

ComboBox::setItemLabelGenerator
Are you asking if you can show the islemAdi field as the label in the combo box?
You can specify code to generate a label used for displaying each item in your enum. Call ComboBox::setItemLabelGenerator. Pass a method reference for your getter. Vaadin then calls this method as needed to display each item.
cmbSablonSecim.setItemLabelGenerator(EnumSablonSecim::getIslemAdi);
See Showing a List of Data with Data Providers in the manual.

Related

Converting List<ClassName> to array object to set as JComboBoxModel

I am designing classes based on DAO Pattern.
I have 3 classes and 1 GUI Form.
public interface SchoolYearDao {
List<SchoolYear> getAllSchoolYearInfo();
List<SchoolYear> getAllSchoolYearStart();
List<SchoolYear> getAllSchoolYearEnd();
List<SchoolYear> getSchoolYearById(int aSchoolYearId);
int getSchoolYearId(SchoolYear schoolyear);
boolean addSchoolYear(SchoolYear schoolyear);
}
public class SchoolYear {
//setters and getters
}
public class SchoolYearDaoImpl implements SchoolYearDao{
#Override
public List<SchoolYear> getAllSchoolYearStart() {
List<SchoolYear> listOfSchoolYearStart = new ArrayList<>();
SchoolYear mySchoolYear = new SchoolYear();
String SQL = "{CALL getAllSchoolYearInfo()}";
try(Connection con = DBUtil.getConnection(DBType.MYSQL);
CallableStatement cs = con.prepareCall(SQL);) {
try(ResultSet rs = cs.executeQuery();){
while(rs.next()){
mySchoolYear.setStart(rs.getInt("yearFrom"));
}
listOfSchoolYearStart.add(mySchoolYear);
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null,e.getMessage());
}
System.out.println(listOfSchoolYearStart);
return listOfSchoolYearStart;
}
}
The problem is with the GUI.
public class SchoolYearGUI extends javax.swing.JPanel {
public SchoolYearGUI() {
initComponents();
schoolYearStartJcbx.setModel(new DefaultComboBoxModel(schoolyear.getAllSchoolYearInfo().toArray());
schoolYearEndJcbx.setModel(new DefaultComboBoxModel(schoolyear.getAllSchoolYearEnd().toArray()));
}
}
I can't get the years to show correctly. I get this.
Instead of the actual integer numbers 2015,2016,2017 and so on...
I research online and found similar problems but most of them were not using a list of class as List<SchoolYear>. In this case, "SchoolYear" is the name of class.
I used toArray(); and tried Arrays.toString(array); but can't get it right.
I thought I'd change the return type to DefaultComboBoxModel of getAllSchoolYearStart() method but I realized I have to keep my List<SchoolYear> as return type in case I need to use the result set as model for JTables etc..
So, I want to just stick with List<SchoolYear> as return type. (If it's a good idea?)
What is the best way to get the actual value?
Thanks in advance.
=============== Solution ==============================
Thanks to MadProgrammer for the advice and to other answerers.
So I studied the listcellrenderer overnight and finally got the basic idea of how to use it.
public MainFrame() {
initComponents();
SchoolYearDaoImpl sy = new SchoolYearDaoImpl();
DefaultComboBoxModel model = new DefaultComboBoxModel(sy.getAllSchoolYearStart().toArray());
jcmbSchoolYearStart.setModel(model);
jcmbSchoolYearStart.setRenderer(new DefaultListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value instanceof SchoolYear){
SchoolYear schoolyear = (SchoolYear) value;
setText(""+schoolyear.getStart());
}
return this;
}
} );
}
I overridden the getListCellRendererComponent and created an if-statement to test if value is an instance of my class which is "SchoolYear" Then I cast whatever the raw value is to SchoolYear then used the getter of SchoolYear model, getStart() to get the value stored in the list.
I'm now moving the renderer to an external class file in my project.
Exactly as #MadProgrammer said, in new DefaultComboBoxModel(schoolyear.getAllSchoolYearInfo().toArray(), you put in an array of Objects, and the constructor of a JComboBox will try to use the toString() method to convert every instance of SchoolYear to present it as plain text. If you don't overwrite the default toString() method to present it as you like, you will see what you see in the combobox you have now: the class's name with some numbers.
You can implement the toString() method, but it's not the best way. You can construct some utility method, along with getSchoolYearId() you have, to get the ID of every object in the List and fill an array with the IDs.
private int[] getIDAndFillAnArray(List<SchoolYear> syrs) {
int[] ids = new int[syrs.size()];
for (int i=0; i<syrs.size(); i++) {
ids[i] = syrs.get(i).getSchoolYearId();
}
return ids;
}
And just use it like:
schoolYearStartJcbx.setModel(new DefaultComboBoxModel(getIDAndFillAnArray(schoolyear.getAllSchoolYearInfo()));
That's simple enough.
Use this class:
public class ComboItem {
private String value;
private String label;
public ComboItem(String value, String label) {
this.value = value;
this.label = label;
}
public String getValue() {
return this.value;
}
public String getLabel() {
return this.label;
}
#Override
public String toString() {
return label;
}
}
Put this method where you connect to your DB:
public ComboItem[] getListOfSchoolYearStart(params..)
{
List<ComboItem> result = new ArrayList<ComboItem>();
ComboItem[] items;
.....
rs = stmt.executeQuery(query);
while (rs.next()) {
ComboItem item = new ComboItem(rs.getInt("id_school") + "", rs.getString("description"));
result.add(item);
}
items = result.toArray(new ComboItem[result.size()]);
return items;
}
Add your JComboBox:
private ComboItem[] listOfSchoolYearStart;
private int selectedIdSchool=-1;
....
listOfSchoolYearStart= getListOfSchoolYearStart();
JComboBox comboList = new JComboBox(listOfSchoolYearStart);
//If you want to keep previous selection
if (listOfSchoolYearStart.length > 0)
{
boolean isFound=false;
for (ComboItem comb : listOfSchoolYearStart) {
if(Integer.parseInt(comb.getValue())==selectedIdSchool)
{
comboList.setSelectedItem(comb);
isFound=true;
break;
}
}
if(!isFound)
{
comboList.setSelectedIndex(0);
selectedIdSchool=Integer.parseInt(listOfSchoolYearStart[0].getValue());
}
}
This works for me at least, I hope it helps.

How Customize Component Label in ZK

Haii all i need help, i want to custom Label component in zk and i nedd to add a property wich is mandatory property when i set mandatory="true" the asterix symbol will be appear and if i set mandatory="false" the asterix symbol disappear,and i am trying like this :
private Label label;
private Label sign;
private String lblValue;
private String REQUIRED_SIGN = " *";
private boolean mandatory;
public SignLabelCustom()
{
label = new Label();
label.setSclass("form-label");
appendChild(label);
sign = new Label();
if(mandatory=true){
sign.setValue(REQUIRED_SIGN);
sign.setStyle("color: red");
appendChild(sign);
}
else{
sign.setValue("");
sign.setStyle("color: red");
removeChild(sign);
}
}
public String getValue() {
return lblValue;
}
public boolean isMandatory() {
return mandatory;
}
public void setMandatory(boolean mandatory) {
this.mandatory = mandatory;
}
public void setValue(String lblValue) {
label.setValue(lblValue);
this.lblValue = lblValue;
}
but the condition does'nt working, how to solve it?
What you probably want is called an HtmlMacroComponent, which combines a label and a textbox...
You start with a zul file:
<zk>
<label id="mcLabel"/><textbox id="mcTextbox"/>
</zk>
...and create a component for it...
public class MyTextbox extends HtmlMacroComponent {
#Wire("#mcTextbox")
private Textbox textbox;
#Wire("#mcLabel")
private Label label;
private String caption;
private boolean mandatory;
public MyTextbox() {
compose(); // this wires the whole thing
}
public void setMandatory(final boolean value) {
mandatory = value;
updateCaption();
}
public boolean isMandatory() {
return mandatory;
}
public void setCaption(final String value) {
caption = value;
updateCaption();
}
public String getCaption() {
return caption;
}
protected void updateCaption() {
label.setValue(mandatory ? caption + "*" : caption);
}
public String getValue() {
return textbox.getValue();
}
public void setValue(final String value) {
textbox.setValue(value);
}
}
...and now you can use it, for example by defining it on the top of your zul file... (adjust package and .zul name as required):
<?component name="mytextbox" macroURI="/zk/textbox.zul" class="com.example.MyTextbox"?>
...so you can simply use it...
<mytextbox id="name" value="Frank N. Furter" caption="Your name" mandatory="true"/>
Later you can define a language addon for it...
my-language-addon
xul/html
mytextbox
com.example.MyTextbox
/zk/textbox.zul
...so that you don't need to put the definition on top of every .zul file where you use it anymore. See the documentation for more on this.
Of course, you also could only create a new label, etc. but I found it's a good think to create MacroComponents for those jobs that combine various components, since this way, for example, you could also automatically add validation, etc.

How to listen even choose item from combobox in ZK 7?

I am use MVC design pattern. In file FmCompress.zul, I have:
<combobox id="cboFmCompress" model="${$composer.listTypeOfProcess}" mold="rounded" hflex="1">
<attribute name="onCreate">self.setSelectedIndex(1);</attribute>
<template name="model">
<comboitem label="${each.typeOfCompress}" value="${each.typeOfCompressId}"></comboitem>
</template>
</combobox>
Model for combo box: TypeOfCompressDTO.java
public class TypeOfCompressDTO {
private String typeOfCompressId;
private String typeOfCompress;
public TypeOfCompressDTO() {
}
public TypeOfCompressDTO(String typeOfCompressId, String typeOfCompress) {
this.typeOfCompressId = typeOfCompressId;
this.typeOfCompress = typeOfCompress;
}
public String getTypeOfCompressId() {
return typeOfCompressId;
}
public void setTypeOfCompressId(String typeOfCompressId) {
this.typeOfCompressId = typeOfCompressId;
}
public String getTypeOfCompress() {
return typeOfCompress;
}
public void setTypeOfCompress(String typeOfCompress) {
this.typeOfCompress = typeOfCompress;
}
}
In file controller: FmCompressComposer.java , I try something like this (my idea):
public class FmCompressComposer extends BaseCustomComposer<FmCompressService, FmCompressDTO> {
//....
#Wire
private Combobox cboToggleZipUnzip;
//....
// initialize value for combo box.
public ListModel<TypeOfCompressDTO> getListTypeOfProcess() {
lstTypeOfCompress = new ArrayList<TypeOfCompressDTO>();
TypeOfCompressDTO t1 = new TypeOfCompressDTO("1", "Zip file");
TypeOfCompressDTO t2 = new TypeOfCompressDTO("2", "Unzip file");
lstTypeOfCompress.add(t1);
lstTypeOfCompress.add(t2);
listTypeOfProcess = new ListModelList(lstTypeOfCompress, true);
return listTypeOfProcess;
}
// Listen even select item in combo box.
public void onSelect$cboZipUnzip(){
searchDTO = new FmCompressDTO();
searchDTO.setType("1");
// my problem focus at this method, and at this line, get value what user choosen. searchDTO.setType(cboToggleZipUnzip.getSelectedItem().getValue().toString());
List<FmCompressDTO> listDTO = fmCompressService.search(searchDTO);
if (listDTO != null && !listDTO.isEmpty()) {
ListModelList model = new ListModelList(listDTO);
model.setMultiple(true);
gridDataFmCompress.setModel(model);
refreshGridData(null);
}
}
//...
}
Please help me: In combo box, when user has event selecting, call method. (In method, get value what user choosen from combobox).
I assume your BaseCustomComposer is extending a GenericForwardComposer.
If so, you are strictly bound to the naming conventions.
As your id of the combobox is cboFmCompress your wired variable should be
// no need for #Wire
private Combobox cboFmCompress;
and the event listener method should be
public void onSelect$cboFmCompress(Event event) {}
Here you can find a minimized zkfiddle: http://zkfiddle.org/sample/3hnhc92/2-SO-33120026

TableView doesn't refresh

I've got a project written in JavaFX and I'm trying to get a refresh on a tableview without result.
I've googled around and tried some examples I've found but it still doesn't work.
I populate a tableview with information each row in this table can have new comments added to by double click on the row. The a new Tabpane is opened and the new comment can be added there. On close of this tabpane I'd like the one I clicked from to be refreshed.
I must be doing something wrong. I just don't know what.
In my StoreController
private void populateTableView(List<Store> stores) {
ObservableList<Store> data = FXCollections.observableArrayList(stores);
storeNumberColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("id"));
storePhoneColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("phoneNbr"));
chainColumn.setCellValueFactory(
new PropertyValueFactory<Store, String>("chainId"));
commentColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Store, ImageView>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Store, ImageView> p) {
Integer numberOfComments = p.getValue().getCommentsCount();
ReadOnlyObjectWrapper wrapper = null;
if (numberOfComments == 0) {
wrapper = null;
} else if (numberOfComments == 1) {
wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_SINGLE_FLAG_SOURCE));
} else {
wrapper = new ReadOnlyObjectWrapper(new ImageView(COMMENT_DOUBLE_FLAG_SOURCE));
}
return wrapper;
}
});
storeTable.setItems(data);
sortTable(storeTable, missedColumn);
}
#FXML
public void handleTableAction(MouseEvent event) {
if (event.getClickCount() == 2) {
showNewCommentStage();
}
}
private void showNewCommentStage() {
initCommentController();
Store store
= storeTable.getSelectionModel().selectedItemProperty().getValue();
commentController.showNewStage(commentPane, store);
}
It seems like the call-function doesn't get called when the commentpane is closed.
CommentController
public void showNewStage(Pane pane, Store store) {
this.store = store;
initStage(pane);
windowHandler = new WindowHandler(stage);
effectHandler.playEffect(pane);
constructCommentHeaders();
List<Comment> comments;
comments = commentService.listByStoreId(store.getId());
populateCommentTable(comments);
}
Like I said I've tried a lot of the solutions found here on Stackoverflow but with no results. The Tableview doesn't refresh. The Stores and the Comments are in different database tables if that's important
Can someone point me in the right direction?
Thanks!
****EDIT****
The Store.class
public class Store extends CommentEntity {
private String id;
private String chainId;
private String phoneNbr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getChainId() {
return chainId;
}
public void setChainId(String chainId) {
this.chainId = chainId;
}
public String getPhoneNbr() {
return phoneNbr;
}
public void setPhoneNbr(String phoneNbr) {
this.phoneNbr = phoneNbr;
}
#Override
public String toString() {
return "Store{" + "id=" + id + ", chainId=" + chainId + '}';
}
#Override
public String getCommentIdentifier() {
return id;
}
}
The CommentEntity.Class
public abstract class CommentEntity {
private int commentsCount;
public int getCommentsCount() {
return commentsCount;
}
public void setCommentsCount(int commentsCount) {
this.commentsCount = commentsCount;
}
public abstract String getCommentIdentifier();
}
Thank you for input, I hadn't even reflected over the ImageView / String.
Two issues:
First, you need to distinguish between the data the cells in your column are displaying, and the cells that actually display those data. The cellValueFactory determines the data that are displayed. The PropertyValueFactory is a cellValueFactory implementation that references a JavaFX Property, so when you call
storeNumberColumn.setCellValueFactory(new PropertyValueFactory<Store, String>("id"));
it effectively tells the cells in the storeNumberColumn to call the idProperty() method on the Store object in the current row to get the data for the cell. (If no such method exists, it will try to use getId() as a backup plan.)
By default, you get a cellFactory that displays text resulting from calling toString() on the data generated by the cellValueFactory. In the case where your data are simply Strings, this is usually what you need. In other cases, you often need to provide a cellFactory of your own to get the correct way to display the data.
In your case, the data for the commentColumn are simply the number of comments. You are going to display that by choosing an image based on that numeric value.
So you should have
TableColumn<Store, Number> commentColumn = new TableColumn<>("Comments");
For the cellValueFactory, you can just use
commentColumn.setCellValueFactory(new PropertyValueFactory<>("commentsCount"));
Then you need a cellFactory that displays the appropriate ImageView:
commentColumn.setCellFactory(new Callback<TableColumn<Store, Number>, new TableCell<Store, Number>>() {
#Override
public TableCell<Store, Number>() {
private ImageView imageView = new ImageView();
#Override
public void updateItem(Number numberOfComments, boolean empty) {
super.updateItem(count, empty) ;
if (empty) {
setGraphic(null);
} else {
if (numberOfComments.intValue() == 0) {
setGraphic(null);
} else if (numberOfComments.intValue() == 1) {
imageView.setImage(new Image(COMMENT_SINGLE_FLAG_SOURCE));
setGraphic(imageView);
} else {
imageView.setImage(new Image(COMMENT_DOUBLE_FLAG_SOURCE));
setGraphic(imageView);
}
}
}
}
});
The second issue is actually about the update. A TableView keeps its contents "live" by observing JavaFX properties that are provided by the cellValueFactory as ObservableValues. If the value might change while the table is displayed, you must provide an actual property that can be observed: using a ReadOnlyObjectWrapper is no good (because it's read only, so it's wrapped value will not change). The PropertyValueFactory will also return a ReadOnlyObjectWrapper if you do not have JavaFX property accessor methods (i.e. if it is only using getXXX() methods to access the data). So your model class must provide JavaFX Properties.
You can make an immediate fix to this by updating CommentEntity to use an IntegerProperty:
public abstract class CommentEntity {
private final IntegerProperty commentsCount = new SimpleIntegerProperty();
public final int getCommentsCount() {
return commentsCountProperty().get();
}
public final void setCommentsCount(int commentsCount) {
commentsCountProperty().set(commentsCount);
}
public IntegerProperty commensCountProperty() {
return commentsCount ;
}
public abstract String getCommentIdentifier();
}
I would also strongly recommend updating the Store class to use JavaFX Properties in a similar manner.

Not able to sort CellTable Column

Trying to make my CellTable Colum sortable but I'm not getting it to work. I'm having an MVP application which gets data from a rest service. To show the data within the table works fine but to sort is doesn't work.
public class LicenseUsageUserViewImpl<T> extends Composite implements LicenseUsageUserView<T> {
#UiTemplate("LicenseUsageUserView.ui.xml")
interface LicenseDataViewUiBinder extends UiBinder<ScrollPanel,LicenseUsageUserViewImpl> {}
private static LicenseDataViewUiBinder uiBinder = GWT.create(LicenseDataViewUiBinder.class);
#UiField
CellTable<GWTLicenseUser> licenseUserCellTable;
List<GWTLicenseUser> licenseUsers;
ListDataProvider<GWTLicenseUser> dataProvider;
public List<GWTLicenseUser> getLicenseUsers() {
return licenseUsers;
}
public void setLicenseUsers(List<GWTLicenseUser> licenseUsers) {
this.licenseUsers = licenseUsers;
}
#UiField Label header;
ListHandler<GWTLicenseUser> sortHandler;
public LicenseUsageUserViewImpl() {
initWidget(uiBinder.createAndBindUi(this));
initCellTable();
}
#Override
public void setLicenseUsersTable(List<GWTLicenseUser> tmpLicenseUsers) {
if (tmpLicenseUsers.isEmpty()) {
licenseUserCellTable.setVisible(false);
} else {
setLicenseUsers(tmpLicenseUsers);
licenseUserCellTable.setWidth("100%");
licenseUserCellTable.setVisible(true);
licenseUserCellTable.setPageSize(getLicenseUsers().size());
licenseUserCellTable.setRowCount(getLicenseUsers().size(), false);
licenseUserCellTable.setRowData(0, getLicenseUsers());
licenseUserCellTable.setVisibleRange(new Range(0, licenseUserCellTable.getRowCount()));
sortHandler.setList(getLicenseUsers());
dataProvider.getList().clear();
dataProvider.getList().addAll(getLicenseUsers());
}
}
#Override
public void initCellTable() {
sortHandler = new ListHandler<GWTLicenseUser>(getLicenseUsers());
licenseUserCellTable.addColumnSortHandler(sortHandler);
licenseUserCellTable.setWidth("100%");
licenseUserCellTable.setVisible(true);
licenseUserCellTable.setVisibleRange(new Range(0, licenseUserCellTable.getRowCount()));
// Create a data provider.
dataProvider = new ListDataProvider<GWTLicenseUser>();
// Connect the table to the data provider.
dataProvider.addDataDisplay(licenseUserCellTable);
licenseUserCellTable.setWidth("100%");
licenseUserCellTable.setAutoHeaderRefreshDisabled(true);
licenseUserCellTable.setAutoFooterRefreshDisabled(true);
// userID
TextColumn<GWTLicenseUser> userIdColumn = new TextColumn<GWTLicenseUser>() {
#Override
public String getValue(GWTLicenseUser object) {
if (object != null ){
return object.getUserId();
} else {
return "NULL";
}
}
};
userIdColumn.setSortable(true);
sortHandler.setComparator(userIdColumn, new Comparator<GWTLicenseUser>() {
#Override
public int compare(GWTLicenseUser o1, GWTLicenseUser o2) {
return o1.getUserId().compareTo(o2.getUserId());
}
});
licenseUserCellTable.addColumn(userIdColumn, "User ID");
// more column entries
licenseUserCellTable.getColumnSortList().push(userIdColumn);
licenseUserCellTable.getColumnSortList().push(countColumn);
licenseUserCellTable.addColumnSortHandler(sortHandler);
}
}
setLicenseUsersTable is called from my activity with the response list of my users. When I start my application and make a rest call my data is provide and put into my list also shown within the CellTable but its not sortable, but I have this sort icon before my colum name. I figured I post the whole code because I think its know easier to see what I'm trying to do.
Thanks for any help.
Remove this line:
sortHandler.setList(getLicenseUsers());
You already passed a List into the SortHandler constructor in
sortHandler = new ListHandler<GWTLicenseUser>(getLicenseUsers());
Also, instead of
setLicenseUsers(tmpLicenseUsers);
you may need to use
licenseUsers.addAll(tmpLicenseUsers);
I hope one of them fixes the problem.

Categories