LWUIT Custom expandable component in list item - java-me

In my project I use lwuit List(main), with a custom renderer.
I`m following the purpose of implementing the expandable list item, that expands/collapses another List (wrapped).
Initially, I'd created Container with Button and List (without collapse/expand behaviour), but when I used it in main list, I faced problem with inability to select Items in wrapped list.
So, I will happy if you helps me with two problems:
Can I fix it using standard lwuit tools?
How can I hide my wrapped list by clicking HeaderBar (visibility just hides the content, but leaves a big gap)?
Images for clarity (ListItem - item of main List, which does not display on image):
private void fillForm() {
mF = new Form();
fillList1();
fillList2();
fillList();
mF.show();
}
private void fillList() {
mList = new CList();
mList.setRenderer(new CRenderer());
mList.addItem(c1);
mList.addItem(c2);
mF.addComponent(c1);
mF.addComponent(c2);
}
private void fillList1() {
c1 = new Container();
b1 = new Button();
b1.getUnselectedStyle().setBorder(Border.createLineBorder(2, 0x000000));
b1.addActionListener(this);
mList1 = new List();
mList1.setName("l1");
mList1.setRenderer(new DefaultListCellRenderer());
mList1.addItem("one");
mList1.addItem("two");
mList1.addItem("three");
mList1.addItem("four");
mList1.addItem("five");
c1.addComponent(b1);
c1.addComponent(mList1);
}
private void fillList2() {
c2 = new Container();
b2 = new Button();
b2.getUnselectedStyle().setBorder(Border.createLineBorder(2, 0x000000));
b2.addActionListener(this);
mList2 = new List();
mList2.setName("l2");
mList2.setRenderer(new DefaultListCellRenderer());
mList2.addItem("путин");
mList2.addItem("ест");
mList2.addItem("детей");
mList2.addItem("больше чем");
mList2.addItem("любит родину");
c2.addComponent(b2);
c2.addComponent(mList2);
}
private class CRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
return (Container)value; //To change body of generated methods, choose Tools | Templates.
}
}

Can this component solve your issue?
PopupChoiceGroup

Related

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()

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

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.

How to add a new item into ObjectListView?

I tried the demo code in demo project but I can't add new item successfully.
It just add new new NULL group and NULL item.
Please give me an simple example code to add new item (text and image).
Thank you!
Oh sorry! I forgot it. This is the first time I participate in this site.
I use C#. And the code is:
objectListView1.BeginUpdate();
objectListView1.AddObject(new string [] {"Hello","dfdsF" });
objectListView1.EndUpdate();
and
objectListView1.BeginUpdate();
OLVListItem item = new OLVListItem(new string [] {"Hello","dfdsF" });
objectListView1.Items.Add(item);
objectListView1.EndUpdate();
It's so different form ListView and EXListView which I can define a text or a image when creating new item. But in ObjectListView, I don't understand OBJECT?
I get ObjectListView anh it's demo code form here http://nchc.dl.sourceforge.net/project/objectlistview/objectlistview/v2.5/ObjectListViewFull-2.5.0.zip
I will show you what to do to add items. Try to create a class, then make getters and setters for the properties you want to show on your ObjectListView.
SetObjects method takes a List<T>:
public Form1()
{
InitializeComponent();
this.objectListView1.SetObjects(haha.GET());
}
Now this is my class, I called it haha, I've two properties in it (Name and Detail):
class haha
{
string name;
string detail;
public haha(string name , string detail)
{
this.name = name;
this.detail = detail;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Detail
{
get { return detail; }
set { detail = value; }
}
static internal List<haha> GET()
{
haha item = new haha("zeko", "dunno");
haha xx = new haha("sheshe", "dunno");
haha ww = new haha("murhaf", "dunno");
haha qq = new haha("soz", "dunno");
haha ee = new haha("HELLO", "dunno");
List<haha> x = new List<haha>();
x.Add(item);
x.Add(xx);
x.Add(ww);
x.Add(qq);
x.Add(ee);
return x;
}
}
Now
change ShowGroups in ObjectListView to false
then add the columns that you want; I've added two columns, one for Name and one for Detail
and as in the picture when you add a column, see the AspectName and write exactly the same name of its property that you want to show from your class
Here's the result:
If you want to use AddObject(), which takes an object, I'd write this:
private void button1_Click(object sender, EventArgs e)
{
haha newObject = new haha("memo","zezo");
objectListView1.AddObject(newObject);
}
Happy coding :)
The best thing is to use an entity class. Then make a list of items and add this list to your ObjectListView.
myObjectListView.SetObjects(myListofEntityItems);
But before you do that, you have to setup the columns in your designer. Just add a column, and in the field AspectName enter the exact name of the attribute of your entity item.

Adding icons to each list item in a List

I want to add an icon to each items in a list an image. This is my code for creating list :
Form f3=new Form("DEMO FORM");
f3.setScrollable(true);
f3.setLayout(new BorderLayout());
f3.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
String items[] = {"one","two","three","four"};
DefaultListModel myListModel = new DefaultListModel(items);
List lst=new List(myListModel);
f3.addComponent(lst);
f3.show();
How can I do that?
Use this List Renderer
import com.sun.lwuit.Component;
import com.sun.lwuit.Font;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import com.sun.lwuit.List;
import com.sun.lwuit.list.ListCellRenderer;
import com.sun.lwuit.plaf.Border;
import java.io.IOException;
public class MyListRenderer extends Label implements ListCellRenderer {
private Image[] images;
/** Creates a new instance of MyListRenderer */
public MyListRenderer() {
super("");
images = new Image[2];
try {
images[0] = Image.createImage("/on.png");
images[1] = Image.createImage("/off.png");
} catch (IOException ex) {
ex.printStackTrace();
}
}
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
setText(value.toString());
//getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,Font.SIZE_MEDIUM));
if (isSelected) {
setFocus(true);
setIcon(images[1]);
getStyle().setBgColor(0xffcc99);
getStyle().setBgTransparency(55);
getStyle().setBorder(Border.createRoundBorder(15, 15, 0xff9900, true));
} else {
setFocus(false);
setIcon(images[0]);
getStyle().setBgColor(0xffffff);
getStyle().setFgColor(0x000000);
getStyle().setBorder(Border.createRoundBorder(15, 15, 0xffcc99, true));
getStyle().setBgTransparency(255);
}
return this;
}
public Component getListFocusComponent(List list) {
setIcon(images[1]);
setText("");
getStyle().setBgColor(0x0000ff);//no effect
setFocus(true);
getStyle().setBgTransparency(100);
return this;
}
}
You can remove unwanted embelishments from this renderer: color changes on focus, etc, ...I have also given code for two different icons for the unselected and selected list item.
Then set the renderer of the list like this:
lst.setListCellRenderer(new MyListRenderer());
You need to place the image data in the model or provide some way for the renderer to extract and apply that data. See samples for this in the LWUIT demo where you have both the renderer demo or the Scrolling demo which show off lists that have icons and various entry layouts.
I have used newer 'Generic List Cell Renderer' to produce thumbnail(icons) in a list. I found it easier to implement than other options for list rendering. Following link has example code to show how to create list using this technique.
http://codenameone.blogspot.in/2011/03/list-rendering-easy-way-generic-list.html
To show thumbnail i did the following which is pretty much boilerplace in LWUIT.
private Container createGenericRendererContainer() throws IOException {
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label xname = new Label("");
Label description = new Label();
//create box layout to contain name and description
Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS));
xname.setName("Name");
xname.getStyle().setBgTransparency(0);
xname.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
description.setFocusable(true);
description.setName("Description");
cnt.addComponent(xname);
cnt.addComponent(description);
c.addComponent(BorderLayout.CENTER, cnt);
//thumbail or icon goes here. we add to the left in our borderlayout
Button thumb = new Button(Image.createImage("/res/home-work.png"));
c.addComponent(BorderLayout.WEST, thumb);
return c;
}

Resources