GXT 3.x EditorGrid: choose cell editor type on a cell by cell basis - gxt

Is there anyway to define the editor type on a cell by cell basis in GXT 3.0?
I need to create a transposed table; the column become the row and the row is the column. That being the case, a column (from a normal table point of view) will have various editor type, whereby a row will have identical editor type.
I am trying to use following approach - It seems to be working fine, and allow to open up editors based on data type but when i click out; it doesn't close/hide editor.
I would really appreciate if someone can please point me in right direction.
final GridInlineEditing<MyModel> editing = new GridInlineEditing<MyModel>(mygrid){
#SuppressWarnings("unchecked")
#Override public <O> Field<O> getEditor(ColumnConfig<MyModel, ?> columnConfig) {
if(valueColumnName.equals(columnConfig.getHeader().asString())) {
MyModel myModel = tree.getSelectionModel().getSelectedItem();
if(MyModelType.STRING.equals(myModel.getMyModelType())) {
TextField textField = new TextField();
textField.setAllowBlank(Boolean.FALSE);
return (Field<O>) textField;
}
else {
TextArea textField = new TextArea();
textField.setAllowBlank(Boolean.FALSE);
return (Field<O>) textField;
}
}
return super.getEditor(columnConfig);
}
};
editing.setClicksToEdit(ClicksToEdit.TWO);
PS:
This is similar to question below; but answer is specific to post GXT 3.0. I am new to stackoverflow and it seems recommendation was to create new question instead of adding new post to old thread.
GXT EditorGrid: choose cell editor type on a cell by cell basis

After playing around all day; my colleague(Praveen) and I figured it out. So instead of trying to override GridInlineEditing's getEditor() method override startEditing() method. Also, you will need converters if you have data like Date, List etc. Below is sample code; hope this help others.
final GridInlineEditing<MyModel> editing = new GridInlineEditing<MyModel>(tree){
#Override public void startEditing(GridCell cell) {
MyModel myModel= tree.getSelectionModel().getSelectedItem();
if(MyModelType.TEXT.equals(myModel.getContextVariableType())) {
TextArea textField = new TextArea();
textField.setAllowBlank(Boolean.FALSE);
super.addEditor(valueColumn, textField);
}
else if(MyModelType.BOOLEAN.equals(myModel.getContextVariableType())) {
SimpleComboBox<String> simpleComboBox = new SimpleComboBox<String>(new StringLabelProvider<String>());
simpleComboBox.setTriggerAction(TriggerAction.ALL);
simpleComboBox.add("YES");
simpleComboBox.add("NO");
super.addEditor(valueColumn, simpleComboBox);
}
else if(MyModel.INTEGER.equals(myModel.getContextVariableType())) {
SpinnerField<Integer> spinnerField = new SpinnerField<Integer>(new IntegerPropertyEditor());
spinnerField.setIncrement(1);
Converter<String, Integer> converter = new Converter<String, Integer>(){
#Override public String convertFieldValue(Integer object) {
String value = "";
if(object != null) {
value = object.toString();
}
return value;
}
#Override public Integer convertModelValue(String object) {
Integer value = 0;
if(object != null && object.trim().length() > 0) {
value = Integer.parseInt(object);
}
return value;
}
};
super.addEditor(valueColumn, converter, (Field)spinnerField);
}
else {
TextField textField = new TextField();
textField.setAllowBlank(Boolean.FALSE);
super.addEditor(valueColumn, textField);
}
super.startEditing(cell);
}
};
editing.setClicksToEdit(ClicksToEdit.TWO);

I think the reason you are not seeing the fields not closing is because you are not actually adding them to the GridInlineEditing class.
In the parts where you have the following return statements;
return (Field<O>) textField;
Those textfields are never added to the grid.
I would try substituting the following code for your first two return statement;
super.addEditor(columnConfig, (Field<O>) textField;
This adds the editor to some maps used by AbstractGridEditing. Specifically, the AbstractGridEditing.removeEditor(GridCell, Field<?>) method, which is used in GridInlineEditing.doCompleteEditing() and GridInlineEditing.cancelEditing() needs the field to be in the map so it can be detached from its parent.

Related

What's the proper way to edit text in objectlistview

I have an objectlistview with 4 columns and a dynamic number of rows, I'm struggling with programmable editing a cell text value, and optionally change the forecolor
I've read everything and anything that I could put my hands on, but couldn't find any valid and right to the point example on how to do it.
the ObjectListView is created this why
List<VideoItem> list = new List<VideoItem>();
foreach (dynamic item in VideoItems)
{
list.Add(new VideoItem { Index = (int)item.index, OldName = (string)item.oldname, NewName = (string)item.newname });
}
olv1.AddObjects(list);
VideoItem class look like this
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
but i need to programmably edit a cell text on event. I'm doing some logical operations on other cell at the end im storing the result to to cell next to it.
You should be storing the result (making the change) to the underlying model object and then call RefreshObject(myModelObject);
About the forcolor, i need to change only the cell I've changed
"To change the formatting of an individual cell, you need to set UseCellFormatEvents to true and then listen for FormatCell events."
Take a look at this.
Just to add to Rev1.0 Answer, i needed to update the object that contains the items (in my case a List) then, use olv1.RefreshObject(list); flow by olv1.BuildList(true);
the olv1.BuildList(true); refresh the GUI immediately.
here a small code snippet to make thing bit more clear
it's changing the data in column 3 when a checkbox is checked.
using System.Collections.Generic;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Initializeolv();
}
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
private List<VideoItem> list = new List<VideoItem>();
private void Initializeolv()
{
for (var i = 1; i <= 10; i++)
{
list.Add(new VideoItem { Index = i, OldName = $"old{i}", NewName = $"new{i}" });
}
olv1.AddObjects(list);
}
private void olv1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
list[e.Item.Index].NewName = "new200";
olv1.RefreshObject(list);
olv1.BuildList(true);
}
}
}

JavaFX Table set table cell background on setEditStart

I have a table with editable cells (Strings) in JavaFX. I want to edit the value of the cells IN the table itself. Now the edit behaviour in FX is a little bit unusual. You have to press enter to commit the edited value. Changing row or cell is not enough. So my idea was to paint the cell background in yellow when I start editing it and remove the yellow color when the user presses enter to remind the user to press enter. But I have some problems to get the cell in the start-edit method. How can I change the color?
Any hint is welcome!
Here is my code
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellFactory(TextFieldTableCell.forTableColumn());
nameCol.setOnEditStart(new EventHandler<CellEditEvent<Zone, String>>() {
#Override
public void handle(CellEditEvent<Zone, String> cell)
{
if(cell.getRowValue() != null)
//how to get the cell and then ->.setStyle("-fx-background-color:yellow");
}});
Rather than relying on the setOnEditStart API, work with the table's RowFactory.
/**
*
* #author ggrec
*
*/
private class FXTableRowFactory implements Callback<TableView<FXTableRow>, TableRow<FXTableRow>>
{
#Override
public TableRow<FXTableRow> call(final TableView<FXTableRow> arg0)
{
return new TableRow<FXTableRow>() {
#Override protected void updateItem(final FXTableRow line, final boolean empty)
{
super.updateItem(line, empty);
if (line == null)
return;
if (isEditing())
{
this.setStyle(line.getStyleWhenEditing());
}
}
};
}
}

Text representation of the content of a TableView

For testing purposes (using JemmyFX), I want to check that the content of a TableView is appropriately formatted. For example: one column is of type Double and a cell factory has been applied to show the number as a percent: 20%.
How can I verify that when the value is 0.2d, the cell is showing as 20%?
Ideally I am looking for something along those lines:
TableColumn<VatInvoice, Double> percentVat = ...
assertEquals(percentVat.getTextualRepresentation(), "20%");
Note: I have tried to use the TableCell directly like below but getText() returns null:
TableCell<VatInvoice, Double> tc = percentVat.getCellFactory().call(percentVat);
tc.itemProperty().set(0.2);
assertEquals(tc.getText(), "20%"); //tc.getText() is null
The best I have found so far, using JemmyFX, is the following:
public String getCellDataAsText(TableViewDock table, int row, int column) {
final TableCellItemDock dock = new TableCellItemDock(table.asTable(), row, column);
return dock.wrap().waitState(new State<String>() {
#Override public String reached() {
return dock.wrap().cellWrap().getControl().getText();
}
});
}
You can try editing the cell factory.
tc.setCellFactory(new Callback<TableColumn, TableCell>(){
#Override
public TableCell call(TableColumn param){
return new TableCell(){
#Override
public void updateItem(Object item, boolean isEmpty){
//...logic to format the text
assertEquals(getText(), "20%");
}
};
}
});

How to do an action when a LWUIT List item clicked

I have a LWUIT application that has a list which involving some items.
The list itself has been added to a Combobox .
1/ How I change the colour of an item of list when I focus on it?
final com.sun.lwuit.List mylist = new com.sun.lwuit.List();
mylist.addItem("one");
mylist.addItem("two");
mylist.addItem("three");
mylist.addItem("four");
final com.sun.lwuit.ComboBox combo = new com.sun.lwuit.ComboBox (mylist.getModel());
final com.sun.lwuit.Form ff = new com.sun.lwuit.Form();
ff.addComponent(combo);
2/ I want to do an action when I click ( or double click ) on an item ,
ActionListener interface didn't make that for me , can someone guide me?
mylist.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
System.out.println("java");
}
}
);
You Should set a renderer to ComboBox and can use both of setRenderer and setListCellRenderer but setListCellRenderer is
deprecated than use setRenderer:
combo.setRenderer(new ListCellRenderer() {
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
Label l = new Label(String.valueOf(value));
l.getStyle().setBgColor(0xffaa00);
return l;
}
public Component getListFocusComponent(List list) {
Label l = new Label(String.valueOf(list.getSelectedItem()));
l.getStyle().setBgColor(0x00ff00);
return l;
}
});
this working well.
To change the colour of a ComboBox you should modify the ComboBoxFocusstyle from the ResourceEditor.
If you are adding the list to the ComboBox, I think that you should put the ActionListener to the ComboBox not to the List as you are doing. Try this facts.
You can work with ListCellRenderer. Its helpful tool ,
look here for example
You can implement getListCellRendererComponent(..)- this function return the compenents that display on screen and responsible on UI.
If you work with ListCellRenderer you can use actionLisiner like this:
mylist.setRenderer(getListCellRenderer());
ActionListener chooseItemActionListener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doAction(getSelected());
}
};
mylist.addActionListener(chooseItemActionListener);

Display image in table

I am trying to insert an image into table view in JavafX. Here is how I set up my table view:
TableColumn prodImageCol = new TableColumn("IMAGES");
prodImageCol.setCellValueFactory(new PropertyValueFactory<Product, Image>("prodImage"));
prodImageCol.setMinWidth(100);
// setting cell factory for product image
prodImageCol.setCellFactory(new Callback<TableColumn<Product,Image>,TableCell<Product,Image>>(){
#Override
public TableCell<Product,Image> call(TableColumn<Product,Image> param) {
TableCell<Product,Image> cell = new TableCell<Product,Image>(){
public void updateItem(Product item, boolean empty) {
if(item!=null){
ImageView imageview = new ImageView();
imageview.setFitHeight(50);
imageview.setFitWidth(50);
imageview.setImage(new Image(product.getImage()));
}
}
};
return cell;
}
});
viewProduct.setEditable(false);
viewProduct.getColumns().addAll(prodImageCol, prodIDCol, prodNameCol, prodDescCol, prodPriceCol, col_action);
viewProduct.getItems().setAll(product.populateProductTable(category));
private SimpleObjectProperty prodImage;
public void setprodImage(Image value) {
prodImageProperty().set(value);
}
public Object getprodImage() {
return prodImageProperty().get();
}
public SimpleObjectProperty prodImageProperty() {
if (prodImage == null) {
prodImage = new SimpleObjectProperty(this, "prodImage");
}
return prodImage;
}
And this is how I retrieve the image from database:
Blob blob = rs.getBlob("productImage");
byte[] data = blob.getBytes(1, (int) blob.length());
bufferedImg = ImageIO.read(new ByteArrayInputStream(data));
image = SwingFXUtils.toFXImage(bufferedImg, null);
However I am getting error at the setting up of table view: imageview.setImage(new Image(product.getImage()));
The error message as:
no suitable constructor found for Image(Image)
constructor Image.Image(String,InputStream,double,double,boolean,boolean,boolean) is not applicable
(actual and formal argument lists differ in length)
constructor Image.Image(int,int) is not applicable
(actual and formal argument lists differ in length)
constructor Image.Image(InputStream,double,double,boolean,boolean) is not applicable
(actual and formal argument lists differ in length)
constructor Image.Image(InputStream) is not applicable
(actual argument Image cannot be converted to InputStream by method invocation conversion)
constructor Image.Image(String,double,double,boolean,boolean,boolean) is not applicable
(actual and formal argument lists differ in length)
constructor Image.Image(String,double,double,boolean,boolean) is not applicab...
I did managed to retrieve and display an image inside an image view but however, I can't display it in table column. Any help would be appreciated. Thanks in advance.
The problem that's causing the exception is that your method product.getImage() is returning an javafx.scene.Image. There's no need to do anything else at this point: You have an image, so use it (before you were trying to construct new Image(Image) - which is not even possible). This is what you want to be using:
imageview.setImage(product.getImage());
Your second problem is that while you're creating an ImageView every time you update the cell, you're not doing anything with it. Here's your original code:
TableCell<Product,Image> cell = new TableCell<Product,Image>(){
public void updateItem(Product item, boolean empty) {
if(item!=null){
ImageView imageview = new ImageView();
imageview.setFitHeight(50);
imageview.setFitWidth(50);
imageview.setImage(new Image(product.getImage()));
}
}
};
return cell;
Like #tomsontom suggested, I'd recommend using setGraphic(Node) to attach your ImageView to the TableCell. So you might end up with something like this:
//Set up the ImageView
final ImageView imageview = new ImageView();
imageview.setFitHeight(50);
imageview.setFitWidth(50);
//Set up the Table
TableCell<Product,Image> cell = new TableCell<Product,Image>(){
public void updateItem(Product item, boolean empty) {
if(item!=null){
imageview.setImage(product.getImage()); //Change suggested earlier
}
}
};
// Attach the imageview to the cell
cell.setGraphic(imageview)
return cell;
The first point #tomsontom was making is that your method of creating an Image is a little roundabout. Sure, it seems to work... but there's a simpler way. Originally you were using:
bufferedImg = ImageIO.read(new ByteArrayInputStream(data));
image = SwingFXUtils.toFXImage(bufferedImg, null);
But a better way of doing it would be switching those lines with:
image = new Image(new ByteArrayInputStream(data));
why are not creating the Image directly from the data new Image(new ByteArrayInputStream(data)) no need to rewrap it our use Swing stuff
I don't see a public Image(Object) constructor in FX8 - why passing it anyways if you are already have an image instance?
you need to set the ImageView on the cell with setGraphic()

Resources