I am wondering if this is a bug or just my faulty code. I've been trying to render table with some horizontal spanning. This is how it should look like:
In LWUIT 1.4 everything worked correctly. Since 1.5 the table looks like:
My implementation:
DefaultTableModel model = new DefaultTableModel(new String[]{"", "", "", ""}, new String[][]{
{"Header", null, null, null},
{"1", "2", "3", "4"},
{"1", "2", "3", "4"},
{"String", null, "String", null}});
Table tab = new Table(model, false) {
protected Component createCell(Object value, final int row, final int column, boolean editable) {
Component c = super.createCell(value, row, column, editable);
c.setFocusable(false);
return c;
}
protected TableLayout.Constraint createCellConstraint(java.lang.Object value, int row, int column) {
TableLayout.Constraint tlay = super.createCellConstraint(value, row, column);
if (row == 0 && column == 0) {
tlay.setHorizontalSpan(4);
tlay.setHorizontalAlign(Table.CENTER);
} else if (row == 3)) {
if (column == 0) {
tlay.setHorizontalSpan(2);
tlay.setWidthPercentage(50);
} else if (column == 2) {
tlay.setHorizontalSpan(2);
tlay.setWidthPercentage(50);
}
} else if (row != 0) {
tlay.setWidthPercentage(25);
}
return tlay;
}
};
The bug (in LWUIT) is triggered by the tlay.setWidthPercentage(50); which you can remove and still get the expected result. It seems the width percentage value doesn't take spanning into consideration which I'm guessing it should.
You should file a bug for this in the issue tracker, thanks for the bug.
I added this line
TableLayout.setDefaultColumnWidth(1);
before
Table tab = new Table(model, false) {
...
and it worked out.
Related
I am trying to hide these duplicate inventory ID values for the "price" and "Cost" lines (when one "adds" an item to the grid it creates three lines), but the selector description still appears.
How can I just make these value come up blank in the grid?
Even better, how can I disable a link command so if someone inadvertently clicks then it wont link to the stock item screen?
Here is my code thus far:
protected void _(Events.FieldSelecting<FPPriceSheetDetail, FPPriceSheetDetail.inventoryID> e)
{
if (e.Row is null) return;
if (e.Row.RowType == FPPriceSheetRowType.BreakQty) return;
var state = PXFieldState.CreateInstance(e.ReturnState, typeof(string), true, false, 1, null, null, null, nameof(FPPriceSheetDetail.inventoryID));
state.SelectorMode = PXSelectorMode.TextMode;
state.DescriptionName = "";
state.ValueField = "";
state.Visibility = PXUIVisibility.Visible;
state.Visible = true;
e.ReturnState = state;
e.ReturnValue = "";
}
I would rather review the pxSelector and in the condition only show 1-row type - this will remove the duplicates. The point of the selector is to select one of the values within the result - assuming all the information the selector are selectable.
var user = Db.Single<User>(x => x.Id==1);
if(user.Id!=1||user.Id==0)
{logger.Error($"Incorrect result{user.Id}")}
can see any result in Log file.
This problem has troubled me for a long time
And never seen before
I also think it is possible a concurrency issue. so i code a simple select use ado.net , the problem is still
string sql = $" select * from where Id=1 ";
using (SqlConnection connection = new SqlConnection(dbConnectionString))
{
DataTable dt = new DataTable();
connection.Open();
SqlDataAdapter sda = new SqlDataAdapter(sql , connection);
sda.Fill(dt);
connection.Close();
sda.Dispose();
if (dt != null && dt.Rows.Count > 0)
{
var user= dt.ToSingleModel<User>();
}
}
This problem is difficult to reproduce, and it will only appear after millions of queries. Of course, it may not be so much, there is not much regularity. So I just uploaded the code, and you may not be able to reproduce it.
In order to capture the log, I rewrote SingleById
public T SingleById( int id)
{
var result = Db.SingleById<T>(id);
if (result == null || result.Id != id)
{
var first = result.ToIndentedJson();
result = Db.SingleById<T>(id);
if (result == null || result.Id != id)
{
result =Db.SingleById<T>(id);
if (result != null)
{
LogQueryError(first,result, 2);
}
}
else
{
LogQueryError(first, result, 1);
}
}
return result;
}
public static readonly Logger LoggerMustDeal = LogManager.GetLogger("MustDeal");
public void LogQueryError(string first, IEntityBase entityBase, int level = 1)
{
StackTrace st = new StackTrace(true);
var frames = st.GetFrames();
foreach (var sf in frames)
{
if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sf.GetILOffset()) break;
var fileName = sf.GetFileName();
if (sf.GetMethod() == null || (!fileName.IsNullOrEmpty() && !fileName.Contains("LastOne")))
{
break;
}
var str =
$"{fileName} {sf.GetMethod().Name} {sf.GetFileLineNumber()} {sf.GetFileColumnNumber()}";
LoggerMustDeal.Error($"sqlserver error {str}");
}
LoggerMustDeal.Error($"sqlserver error first data {first}");
LoggerMustDeal.Error($"sqlserver error times {level} {entityBase.ToIndentedJson()} {Db.ConnectionString}");
var spId = Db.Single<int>("select ##SPID");
LoggerMustDeal.Error($"spid:{spId}");
}
now the log id=219 is the correct result,This just happened in the production environment
And very strangely, ##SPID return 0 or throw an exception Input string was not in a correct format. Just like select ##spid int but return varchar
2020-04-27 16:28:34.9112 ERROR sqlserver error first data {
"Name": "",
"StartTime": "0001-01-01T00:00:00",
"EndTime": "0001-01-01T00:00:00",
"ActivityType": 0,
"ActivityRangeType": 0,
"IsOpen": false,
"ActivityFlag": null,
"Timer": 0,
"State": 2,
"Id": 3,
"Delstatus": false,
"AddTime": "2020-02-04T18:36:03.883",
"UpdateTime": "2020-04-27T10:04:13.713",
"MallId": 1
}
2020-04-27 16:28:34.9112 ERROR sqlserver error times 1 {
"Name": "test",
"StartTime": "2020-04-18T00:00:00",
"EndTime": "2020-04-19T00:00:00",
"ActivityType": 1,
"ActivityRangeType": 1,
"IsOpen": true,
"ActivityFlag": "test",
"Timer": 0,
"State": 2,
"Id": 219,
"Delstatus": false,
"AddTime": "2020-04-13T17:38:48.83",
"UpdateTime": "2020-04-13T17:38:48.83",
"MallId": 15
} server=xxxx;uid=xxxx;pwd=xxxx;database=xxxx;max pool size=40000;Pooling=true;
Another interesting thing happened today
In redis
key value
Urn:sid {"__type":"UserSession"}
OrderPaySettle {"__type":"ServiceInterface.SettleOrder"}
Thread A Redis.Get<UserSession>("Urn:sid") at 2020-04-29 06:27:53.0000
Thread B Redis.Get<object>("OrderPaySettle") at 2020-04-29 06:27:53.8009
var item = Redis.Get<object>("OrderPaySettle")
then we found item's type is UserSession in Log file
A few days ago, through log analysis, the database was almost the same. The wrong result was queried, usually the result that another thread just queried and got
Does it feel like a memory or network layer problem?
What is your opinion on this? #mythz
The problem seems to have been solved.
In my code , There will be many such examples , one api service resolve any other service and every service will open a dbconnction , and dbconnction dispose on service dispose . so there may be many opened dbconnections at the same time.
public object Post(RequestA request)
{
using var servceA=ResolveService<ServiceA>();
using var servceB=ResolveService<ServiceB>();
using var servceC=ResolveService<ServiceC>();
.......
using var servceN=ResolveService<ServiceN>();
...
...
}
I created the DAL layer ,dbconnction will dispose after exec
public T Single(SqlExpression<T> exp)
{
using var db = HostContext.AppHost.GetDbConnection(Request);
var result = db.Single(exp);
return result;
}
Since this change, there have been no problems for more than 20 consecutive days
But I still don’t know where the problem is.
May be many opened dbconnections at the same time will abnormal ?
I have a custom multi-select drop-down element in one of my kendo grid header columns titled "Status". Each selection in the drop-down represents many statuses, but they are grouped together for simplicity, and so we can show groups of like statuses.
Since this is a custom filter, I know I have to manipulate the kendo filter manually, and this seems to be giving me fits.
When any selection is changed in my custom drop-down, I fire off a function to modify the filters (the section where I spin through the status array has been truncated for easier reading):
// Apply the status filters from the multi-select drop down
function applyStatusFilter(statusValues) {
var gridData = $("#accountsGrid").data("kendoGrid");
var currentFilterObj = gridData.dataSource.filter();
var currentFilters = currentFilterObj ? currentFilterObj.filters : []; // If there are no current filters, set to empty array
var statusFilters = { logic: "or", filters: [] };
var statusArray = statusValues.split(','); // Convert status selections to array
// Remove any pre-existing status filters from the existing filter
if (currentFilters && currentFilters.length > 0) {
for (var i = 0; i < currentFilters.length; i++) {
if (currentFilters[i].field == 'status') {
currentFilters.splice(i, 1);
//break;
}
}
}
if (statusArray[0].length > 0) {
$.each(statusArray, function (key, value) {
if (value == 'AC') {
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "A"
});
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "G"
});
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "O"
});
if (value == 'OH') {
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "G"
});
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "H"
});
statusFilters.filters.push({
field: "status",
operator: "eq",
value: "I"
});
}
});
}
currentFilters.push(statusFilters);
gridData.dataSource.filter({
logic: "and",
filters: currentFilters
});
}
This isn't working as expected, although it's still a work in progress. There are two main issues; when I call this function, I want to remove all current "status" related filters, then rebuild. I can't clear all filters, as I need to maintain other column filters that might be applied. My remove status filters block doesn't seem to be working.
Second big issue, is how to properly combine two filter objects; when one can be a nested blocked of status filters using "or" logic, then combining it to any possible existing filters using "and" logic between the two filter objects.
About your first issue. There are sure several ways to remove all current "status" related filters, but I have built a recursive function that clear the filters for a given column.
function clearFilter(filter, columnToClear) {
if (filter == undefined)
return filter;
if (filter.logic != undefined) {
filter.filters = $.map(filter.filters, function (val) {
if (val.field == undefined && typeof (val.filters) == "object" && typeof (val.logic) == "string") {
val.filters = clearFilter(val.filters, columnToClear)
if (val.filters.length == 0)
val = null;
return val;
}
else if (val.field != columnToClear)
return val;
});
if (filter.filters.length == 0)
filter = null;
}
else {
filter = $.map(filter, function (val) {
if (val.field != columnToClear)
return val;
});
}
return filter;
}
In your case the function should be called as:
clearFilter(currentFilterObj, "status");
afaik The TableView in javafx have 2 column resize policies: CONSTRAINED_RESIZE_POLICY and UNCONSTRAINED_RESIZE_POLICY, but I want columns is resized to fit the content of theirs cells
I think it's a simple problem in other platform (like datagridview in C#) but can not resolve
After 3 years I come back to this problem again, some suggestions are calculating the size of text of data in each cell (it's complicated depending on font size, font family, padding...)
But I realize that when I click on the divider on table header, it's resized fit to content as I want. So I dig into JavaFX source code I finally found resizeColumnToFitContent method in TableViewSkin, but it is protected method, we can resolve by reflection:
import com.sun.javafx.scene.control.skin.TableViewSkin;
import javafx.scene.control.Skin;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GUIUtils {
private static Method columnToFitMethod;
static {
try {
columnToFitMethod = TableViewSkin.class.getDeclaredMethod("resizeColumnToFitContent", TableColumn.class, int.class);
columnToFitMethod.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void autoFitTable(TableView tableView) {
tableView.getItems().addListener(new ListChangeListener<Object>() {
#Override
public void onChanged(Change<?> c) {
for (Object column : tableView.getColumns()) {
try {
columnToFitMethod.invoke(tableView.getSkin(), column, -1);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
});
}
}
Note that we call "tableView.getItems()" so we have to call this function after setItems()
After testing the previous solutions I finally found one that worked for me.
So here is mine (call the method after inserting the data into table):
public static void autoResizeColumns( TableView<?> table )
{
//Set the right policy
table.setColumnResizePolicy( TableView.UNCONSTRAINED_RESIZE_POLICY);
table.getColumns().stream().forEach( (column) ->
{
//Minimal width = columnheader
Text t = new Text( column.getText() );
double max = t.getLayoutBounds().getWidth();
for ( int i = 0; i < table.getItems().size(); i++ )
{
//cell must not be empty
if ( column.getCellData( i ) != null )
{
t = new Text( column.getCellData( i ).toString() );
double calcwidth = t.getLayoutBounds().getWidth();
//remember new max-width
if ( calcwidth > max )
{
max = calcwidth;
}
}
}
//set the new max-widht with some extra space
column.setPrefWidth( max + 10.0d );
} );
}
I think just by overriding a call back function that returns true will solve your problem it will disable the re-sizing of columns and all columns will be re-sized to fit the content of their cells.
Example:
TableView<String[]> table = new TableView<>();
table.setColumnResizePolicy(new Callback<TableView.ResizeFeatures, Boolean>() {
#Override
public Boolean call(ResizeFeatures p) {
return true;
}
});
If you want that only one column fills the remaining width of a table, I have found a pretty straight forward solution, which is short and does not require the hacky reflection solution described above:
DoubleBinding usedWidth = columnA.widthProperty().add(columnB.widthProperty()).add(columnC.widthProperty());
fillingColumn.prefWidthProperty().bind(tableView.widthProperty().subtract(usedWidth));
Or to make it short:
// automatically adjust width of columns depending on their content
configAttributeTreeTable.setColumnResizePolicy((param) -> true );
I have used the other solutions on this question, and it works pretty good. However, the downside of this is when the width of the TableView is greater than the required width of the TableColumns together. I have created a hack to solve this problem, and it works OK:
orderOverview.setColumnResizePolicy((param) -> true );
Platform.runLater(() -> FXUtils.customResize(orderOverview));
where FXUtils.customResize() is created as follows:
public static void customResize(TableView<?> view) {
AtomicDouble width = new AtomicDouble();
view.getColumns().forEach(col -> {
width.addAndGet(col.getWidth());
});
double tableWidth = view.getWidth();
if (tableWidth > width.get()) {
TableColumn<?, ?> col = view.getColumns().get(view.getColumns().size()-1);
col.setPrefWidth(col.getWidth()+(tableWidth-width.get()));
}
}
I hope this could be helpful for other people as well!
This is the way I found :
tableview.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY );
idCol.setMaxWidth( 1f * Integer.MAX_VALUE * 50 ); // 50% width
nameCol.setMaxWidth( 1f * Integer.MAX_VALUE * 30 ); // 30% width
ageCol.setMaxWidth( 1f * Integer.MAX_VALUE * 20 ); // 20% width
This code autoresizes all column widths in relational proportions to the table width,
while it can fix the first column width to a given value when table width is lower than x
// To generalize the columns width proportions in relation to the table width,
// you do not need to put pixel related values, you can use small float numbers if you wish,
// because it's the relative proportion of each columns width what matters here:
final float[] widths = { 1.2f, 2f, 0.8f };// define the relational width of each column
// whether the first column should be fixed
final boolean fixFirstColumm = true;
// fix the first column width when table width is lower than:
final float fixOnTableWidth = 360; //pixels
// calulates sum of widths
float sum = 0;
for (double i : widths) {
sum += i;
}
// calculates the fraction of the first column proportion in relation to the sum of all column proportions
float firstColumnProportion = widths[0] / sum;
// calculate the fitting fix width for the first column, you can change it by your needs, but it jumps to this width
final float firstColumnFixSize = fixOnTableWidth * firstColumnProportion;
// set the width to the columns
for (int i = 0; i < widths.length; i++) {
table.getColumns().get(i).prefWidthProperty().bind(table.widthProperty().multiply((widths[i] / sum)));
// ---------The exact width-------------^-------------^
if (fixFirstColumm)
if (i == 0) {
table.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> arg0, Number oldTableWidth, Number newTableWidth) {
if (newTableWidth.intValue() <= fixOnTableWidth) {
// before you can set new value to column width property, need to unbind the autoresize binding
table.getColumns().get(0).prefWidthProperty().unbind();
table.getColumns().get(0).prefWidthProperty().setValue(firstColumnFixSize);
} else if (!table.getColumns().get(0).prefWidthProperty().isBound()) {
// than readd the autoresize binding if condition table.width > x
table.getColumns().get(0).prefWidthProperty()
.bind(table.widthProperty().multiply(firstColumnProportion));
}
}
});
}
}
advice to put the code in an separated TableAutoresizeModel class, there you can handle further calculations, for example on hiding columns add listener...
#HarleyDavidson 's answer in kotlin
val String.fxWidth: Double
get() = Text(this).layoutBounds.width
// call the method after inserting the data into table
fun <T> TableView<T>.autoResizeColumns() {
columnResizePolicy = TableView.UNCONSTRAINED_RESIZE_POLICY
columns.forEach { column ->
column.setPrefWidth(
(((0 until items.size).mapNotNull {
column.getCellData(it)
}.map {
it.toString().fxWidth
}.toMutableList() + listOf(
column.text.fxWidth
)).maxOrNull() ?: 0.0) + 10.0
)
}
}
This will set the minimum width of columns based on the font and the text, so that the column names wont be cropped.
public static void setDataTableMinColumnWidth(TableView<?> dataTable)
{
for (Node columnHeader : dataTable.lookupAll(".column-header"))
{
var columnString = columnHeader.getId();
if (columnString != null)
{
for (Node columnHeaderLabel : columnHeader.lookupAll(".label"))
{
var tableColumn = dataTable.getColumns()
.stream()
.filter(x -> x.getId()
.equals(columnString))
.findFirst();
if (columnHeaderLabel instanceof Label && tableColumn.isPresent())
{
var label = (Label) columnHeaderLabel;
/* calc text width based on font */
var theText = new Text(label.getText());
theText.setFont(label.getFont());
var width = theText.getBoundsInLocal()
.getWidth();
/*
* add 10px because of paddings/margins for the button
*/
tableColumn.get()
.setMinWidth(width + 10);
}
}
}
}
}
How to use:
dataTable.needsLayoutProperty()
.addListener((obs, o, n) -> setDataTableMinColumnWidth(dataTable));
For the Columns, the id property needs to be set first:
TableColumn<BundImportTask, String> columnTask = new TableColumn<>("My Column");
columnTask.setId("MyColumnId");
columnTask.setCellValueFactory(data -> new SimpleStringProperty(data.getValue()
.fileName()));
I implemented a solution that it's fairly more complicated than the ones that I found here, but that allows a specific column to be resized by double clicking on the header, while still letting the user resize columns manually.
This is achieved by listening to click events on the header of the table (TableHeaderRow). When a double click occurs, the specific column header is found by matching the mouse event X and Y.
Note: to make this work it's necessary that each column has an ID set.
// when skin is loaded (hence css), setup click listener on header to make column fit to content max width on double click
tableView.skinProperty().addListener((a, b, newSkin) -> {
TableHeaderRow headerRow = (TableHeaderRow) tableView.lookup("TableHeaderRow");
NestedTableColumnHeader headers = (NestedTableColumnHeader) (headerRow.getChildren().get(1));
headerRow.setOnMouseClicked(evt -> {
if (evt.getClickCount() != 2 || evt.getButton() != MouseButton.PRIMARY) return;
// find the header column that contains the click
for (TableColumnHeader header : headers.getColumnHeaders()) {
if (header.contains(header.parentToLocal(evt.getX(), evt.getY()))) {
fitColumnWidthToContent(header.getId());
}
}
evt.consume();
});
});
The method that takes care of the resizing is the following:
private void fitColumnWidthToContent (String colId) {
// find column matching id
TableColumn column = null;
for (TableColumn tempCol : tableView.getColumns()) {
if (tempCol.getId().equals(colId)) {
column = tempCol;
break;
}
}
if (column == null) {
throw new IllegalStateException("Column ID doesn't match any actual column");
}
// set default width to column header width
Text text = new Text(column.getText());
double max = text.getLayoutBounds().getWidth();
for (int i = 0; i < tableView.getItems().size(); i++ ) {
if (column.getCellData(i) == null) continue;
text = new Text(column.getCellData(i).toString());
double textWidth = text.getLayoutBounds().getWidth();
if (textWidth > max) {
max = textWidth;
}
}
column.setPrefWidth(max + 12);
}
I hope this can be useful to anyone.
In order to allow also manual resizing, it's necessary to add a bit more code on table initalization:
// listen to width changes in columns and set to pref width (otherwise if for example width changes because of
// user resizing the column, applying the old pref width won't work because it stayed the same)
for (TableColumn col : tableView.getColumns()) {
col.widthProperty().addListener((obs, oldVal, newVal) -> {
col.setPrefWidth(newVal.doubleValue());
});
}
I have implemented a solution for TreeTableView. It is still in evolution but it manifests now promising results. Hereafter a description of the solution.
In the control skin class, I added to the control children the TreeTableView and an invisible VBox. A cell factory provide derived cells to the target TreeTableColumn. The derived cells wrap a Label node which is added or removed to the invisible VBox according to the empty property, and which its prefWidth is set according to the cell width. The cells make use of:
getProperties().put(Properties.DEFER_TO_PARENT_PREF_WIDTH, Boolean.TRUE)
I override the cell's computePrefWidth() method as follow:
#Override
protected double computePrefWidth(double height) {
return Double.max(_box.prefWidth(-1.0), super.computePrefWidth(height) + 24.0);
}
The Vbox width property is bind to the TreeTableColumn's prefWidth. This is required to resize as well the header of the column.
Is worth to note, that at the time being, to simplify the development of a solution, this approach works well with built in sort, order, and resize feature disabled. Ie.
_nameColumn = new TreeTableColumn<>("Name");
_nameColumn.setResizable(false);
_nameColumn.setReorderable(false);
_nameColumn.setSortable(false);
Happy coding
After long research. Best Solution is..
tblPlan.setColumnResizePolicy((param) -> true );
Platform.runLater(() -> customResize(tblPlan));
"Custom Resize"
public void customResize(TableView<?> view) {
AtomicLong width = new AtomicLong();
view.getColumns().forEach(col -> {
width.addAndGet((long) col.getWidth());
});
double tableWidth = view.getWidth();
if (tableWidth > width.get()) {
view.getColumns().forEach(col -> {
col.setPrefWidth(col.getWidth()+((tableWidth-width.get())/view.getColumns().size()));
});
}
}
<TableView fx:id="datalist" layoutX="30.0" layoutY="65.0" prefHeight="400.0" AnchorPane.bottomAnchor="100.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="100.0">
<columns>
<TableColumn fx:id="number" minWidth="-1.0" prefWidth="-1.0" style="width: auto;" text="number" />
<TableColumn fx:id="id" minWidth="-1.0" prefWidth="-1.0" text="id" />
<TableColumn fx:id="name" minWidth="-1.0" prefWidth="-1.0" text="name" />
<TableColumn fx:id="action" minWidth="-1.0" prefWidth="-1.0" text="todo" />
</columns>
**<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>**
</TableView>
I am using LWUIT and showing data with Table, say, flight information!
Instead of writing air companies with text I just like to replace them with icons.
So, I need to override protected Component createCell(Object value, final int row, final int column, boolean editable) method of Table.
This is how I've implemented:
Initializing
imgAln[i]=null;
try {
imgAln[i] = Image.createImage(strPathToImage[i]);
//e.g /uta.png,/somonair.png and so on
lAln[i] = new Label(imgAln[i]);
} catch (IOException e) { }
Creating Table object
Table table = new Table(model) {
protected Component createCell(Object value, final int row,
final int column, boolean editable) {
final Component c = super.createCell(value, row, column, editable);
if (column == 6) {
return lAln[value]; //it does not work here
}
}
};
need help to add Image to table cell!!!
Is there any example??? links are welcome!
The problem in your createCell(...) implementation is that it does not return the super.createCell(...) when the column is not 6. Also your array of labels (lAln) may not be properly created. Try my implementation below, but make sure you store the appropriate image name in the table models' column 0.
This should solve it:
TableModel model = new DefaultTableModel(
new String[]{"Uneditable", "Editable", "CheckBox", "Multiline"},
new Object[][]{
{"/animations.png", "", new Boolean(false), "Multi-line text\nright here"},
{"/buttons.png", "", new Boolean(true), "Further text that\nspans lines"},
{"/dialogs.png", "", new Boolean(true), "No span"},
{"/fonts.png", "", new Boolean(false), "Spanning\nFor\nEvery\nWord"},
});
Table table = new Table(model) {
protected Component createCell(Object value, final int row,
final int column, boolean editable) {
if (row != -1 && column == 0) {
try {
//In my case Column 0 store the resource path names
return new Label(Image.createImage((String)value));
} catch (Exception ex) {
ex.printStackTrace();
}
}
return super.createCell(value, row, column, editable);
}
};
NOTE: If you see the names instead of images in column 0 it means the image path is incorrect, fix it to see the images.
Did you manage to have a look at TableLayoutDemo.java in project LWUITDemo? If i remember it correct, this comes bundled download package LWUIT1.5.zip (or you can always google it).
Let me know if you need more specific help.