滚动时黑莓的TableModel被搞砸 [英] Blackberry Tablemodel gets messed up when scrolling

查看:124
本文介绍了滚动时黑莓的TableModel被搞砸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现它的字母顺序排序滚动列表。
作为参考,我使用它自带的Eclipse IDE中提供的树屏样品。

我改变了的DataTemplate适合我的需要,直到要滚动它就像一个魅力。整个UI被搞砸了,我不知道该怎么办。我使用的是JRE 7.1和BlackBerry模拟器9860 7.0(我也测试了它真正的设备)。

有谁知道这是一个已知的问题还是我错过了什么?

 包lifeApp;进口net.rim.device.api.command.Command;
进口net.rim.device.api.command.CommandHandler;
进口net.rim.device.api.command.ReadOnlyCommandMetadata;
进口net.rim.device.api.ui.DrawStyle;
进口net.rim.device.api.ui.Field;
进口net.rim.device.api.ui.Manager;
进口net.rim.device.api.ui.XYEdges;
进口net.rim.device.api.ui.XYRect;
进口net.rim.device.api.ui.component.Dialog;
进口net.rim.device.api.ui.component.LabelField;
进口net.rim.device.api.ui.component.SeparatorField;
进口net.rim.device.api.ui.component.table.DataTemplate;
进口net.rim.device.api.ui.component.table.RegionStyles;
进口net.rim.device.api.ui.component.table.SortedTableModel;
进口net.rim.device.api.ui.component.table.TableController;
进口net.rim.device.api.ui.component.table.TableModel;
进口net.rim.device.api.ui.component.table.TableView;
进口net.rim.device.api.ui.component.table.TemplateColumnProperties;
进口net.rim.device.api.ui.component.table.TemplateRowProperties;
进口net.rim.device.api.ui.container.MainScreen;
进口net.rim.device.api.ui.decor.Border;
进口net.rim.device.api.ui.decor.BorderFactory;
进口net.rim.device.api.util.StringComparator;公共类ProductsScreen扩展MainScreen
{
私人SortedTableModel _tableModel;私有静态最终诠释ROW_HEIGHT = 40;公共ProductsScreen()
{
    超(Manager.NO_VERTICAL_SCROLL | Manager.HORIZONTAL_SCROLL);    的setTitle(ALLE PRODUKTE A-Z);    添加(新的LabelField(黑莓设备,LabelField.FIELD_HCENTER));
    添加(新SeparatorField());    _tableModel =新SortedTableModel(StringComparator.getInstance(真),0);    _tableModel.addRow(新的对象[] {A,Produkt1});
    _tableModel.addRow(新的对象[] {B,Produkt2});
    _tableModel.addRow(新的对象[] {C,Produkt3});
    _tableModel.addRow(新的对象[] {C,Produkt4});
    _tableModel.addRow(新的对象[] {B,Produkt5});
    _tableModel.addRow(新的对象[] {C,Produkt6});
    _tableModel.addRow(新的对象[] {C,Produkt7});
    _tableModel.addRow(新的对象[] {R,Produkt8});
    _tableModel.addRow(新的对象[] {T,Produkt9});
    _tableModel.addRow(新的对象[] {C,Produkt10});
    _tableModel.addRow(新的对象[] {B,Produkt11});
    _tableModel.addRow(新的对象[] {U,Produkt12});
    _tableModel.addRow(新的对象[] {V,Produkt13});
    _tableModel.addRow(新的对象[] {T,Produkt14});
    _tableModel.addRow(新的对象[] {C,Produkt15});
    _tableModel.addRow(新的对象[] {B,Produkt16});
    _tableModel.addRow(新的对象[] {U,Produkt17});
    _tableModel.addRow(新的对象[] {V,Produkt18});    RegionStyles风格=新RegionStyles(BorderFactory.createSimpleBorder(新XYEdges(1,1,1,1),Border.STYLE_SOLID),NULL,NULL,
        空,RegionStyles.ALIGN_LEFT,RegionStyles.ALIGN_TOP);    TableView中的tableView =新的TableView(_tableModel);
    TableController tableController =新TableController(_tableModel,的tableView);    tableController.setFocusPolicy(TableController.ROW_FOCUS);    tableController.setCommand(新司令部(新CommandHandler()
    {
        公共无效的execute(ReadOnlyCommandMetadata元数据,对象上下文)
        {
            Dialog.alert(命令来执行);
        }
    }));    tableView.setController(tableController);    DataTemplate中的DataTemplate =新的DataTemplate(的tableView,1,1)
    {
        / **
         * @see的DataTemplate#getDataFields(INT)
         * /
        公共字段[] getDataFields(INT modelRowIndex)
        {
            最终目标[]数据=(对象[])((TableModel的)getView()getModel()。)的getRow(modelRowIndex)。            现场[] =领域新的实地[1];
            场[0] =新的LabelField((字符串)数据[1],Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);            返回领域;
        }
    };    dataTemplate.createRegion(新XYRect(0,0,1,1),风格);
    dataTemplate.setColumnProperties(0,新TemplateColumnProperties(100,TemplateColumnProperties.PERCENTAGE_WIDTH));
    dataTemplate.setRowProperties(0,新TemplateRowProperties(ROW_HEIGHT));    tableView.setDataTemplate(DataTemplate中);
    dataTemplate.useFixedHeight(真);    添加(的tableView);
}
}


解决方案

好了,我装了JDE 7.1 UI / TableAndListDemo 示例应用程序,并运行它的JDE 9900。

这是样品(由我未修改)具有完全相同的扭曲行为与code您发布。

所以,很遗憾,我要说的是,无论是有一个bug,或者如何使用较新的一个有效的例子 SortedTableModel 尚未生产的(我找不到找不到任何更好的)。

值得注意的:如果删除的排序,并简单地替换 SortedTableModel 的TableModel ,视觉腐败消失我。当然,你失去了排序的重要特征,并(在你的台式0列)分组。

另一种选择是自己实现排序行为。排序以外的数据的的TableModel 是不可取的,而且也不会太困难。然后,你可以添加一个额外行的重复模式,为您当前拥有显示单个字符(排序标准)分隔行的占位符。您也将改变数据模板为不可以固定高度。

此外,在数据模板,你可以定义的的区域可以的保持器的行。不论该地区将展示任何东西,或不依赖于数据行按照是否具有相同的单个字符在最后一行,还是不行。所以,这里的code可能是什么样子

DataTemplate中的DataTemplate =新的DataTemplate(的tableView,2,1)// 2行,而不是1
  {
     公共字段[] getDataFields(INT modelRowIndex)
     {
        最终目标[]数据=(对象[])_tableModel.getRow(modelRowIndex);        现场[] =领域新的实地[2];
        串rowGroup =(串)的数据[0];
        //我们在一个新的小组,如果这是第一行,如果此行的
        //数据[0]的值是从最后行的数据[0]的值不同
        布尔isNewGroup =(modelRowIndex == 0)||
              (rowGroup.compareTo((字符串)((对象[])_ tableModel.getRow(modelRowIndex - 1))[0])!= 0);
        如果(isNewGroup){
           //做一个分离器排
           场[0] =新的LabelField((字符串)数据[0]
                          Field.USE_ALL_WIDTH | Field.NON_FOCUSABLE);
        }其他{
           //这是在同一个组的最后一个产品,所以这里不添加任何东西
           场[0] =新NullField();
        }
        现在//添加实际的产品信息
        领域[1] =新的LabelField((字符串)数据[1],
                          Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);        返回领域;
     }
  };
  dataTemplate.createRegion(新XYRect(0,0,1,1),风格); //组分隔符(可能是空字段)
  dataTemplate.createRegion(新XYRect(0,1,1,1),风格); //提供产品信息的实际行
  dataTemplate.setColumnProperties(0,新TemplateColumnProperties(100,TemplateColumnProperties.PERCENTAGE_WIDTH));
  dataTemplate.setRowProperties(0,新TemplateRowProperties(ROW_HEIGHT)); // 分隔器
  dataTemplate.setRowProperties(1,新TemplateRowProperties(ROW_HEIGHT)); //产品数据
  dataTemplate.useFixedHeight(假);

在上面的code,我选择了把分离器行相同的高度和风格作为产品数据行。当然,你可以改变,如果你喜欢的。

这这仍然没有解决的一个问题是焦点绘图。当突出​​显示的隔板行下的第一行,它绘制注重产品行,和隔板行它上面。

您可能需要实现一些自定义的焦点图。我会离开,接下来的问题......不知道你甚至想走这条路。但愿我是错的,但它看起来像RIM库给我了一个错误:(

I want to implement a scrollable List which is sorted alphabetically. As a reference I am using the Tree Screen sample which comes delivered with the Eclipse IDE.

I changed the datatemplate to fit my needs and it works like a charm until you want to scroll. The whole UI gets messed up and I don't know what to do. I'm using JRE 7.1 and the Blackberry Simulator 9860 7.0 (I've also tested it on a real device).

Does anybody know if this is a known issue or do I miss something?

package lifeApp;

import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.table.DataTemplate;
import net.rim.device.api.ui.component.table.RegionStyles;
import net.rim.device.api.ui.component.table.SortedTableModel;
import net.rim.device.api.ui.component.table.TableController;
import net.rim.device.api.ui.component.table.TableModel;
import net.rim.device.api.ui.component.table.TableView;
import net.rim.device.api.ui.component.table.TemplateColumnProperties;
import net.rim.device.api.ui.component.table.TemplateRowProperties;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.decor.Border;
import net.rim.device.api.ui.decor.BorderFactory;
import net.rim.device.api.util.StringComparator;

public class ProductsScreen extends MainScreen
{
private SortedTableModel _tableModel;

private static final int ROW_HEIGHT = 40;

public ProductsScreen()
{
    super(Manager.NO_VERTICAL_SCROLL | Manager.HORIZONTAL_SCROLL);

    setTitle("Alle Produkte A-Z");

    add(new LabelField("BlackBerry Devices", LabelField.FIELD_HCENTER));
    add(new SeparatorField());

    _tableModel = new SortedTableModel(StringComparator.getInstance(true), 0);

    _tableModel.addRow(new Object[] {"A", "Produkt1"});
    _tableModel.addRow(new Object[] {"b", "Produkt2"});
    _tableModel.addRow(new Object[] {"c", "Produkt3"});
    _tableModel.addRow(new Object[] {"c", "Produkt4"});
    _tableModel.addRow(new Object[] {"b", "Produkt5"});
    _tableModel.addRow(new Object[] {"c", "Produkt6"});
    _tableModel.addRow(new Object[] {"c", "Produkt7"});
    _tableModel.addRow(new Object[] {"r", "Produkt8"});
    _tableModel.addRow(new Object[] {"t", "Produkt9"});
    _tableModel.addRow(new Object[] {"c", "Produkt10"});
    _tableModel.addRow(new Object[] {"b", "Produkt11"});
    _tableModel.addRow(new Object[] {"u", "Produkt12"});
    _tableModel.addRow(new Object[] {"v", "Produkt13"});
    _tableModel.addRow(new Object[] {"t", "Produkt14"});
    _tableModel.addRow(new Object[] {"c", "Produkt15"});
    _tableModel.addRow(new Object[] {"b", "Produkt16"});
    _tableModel.addRow(new Object[] {"u", "Produkt17"});
    _tableModel.addRow(new Object[] {"v", "Produkt18"});

    RegionStyles style = new RegionStyles(BorderFactory.createSimpleBorder(new XYEdges(1, 1, 1, 1), Border.STYLE_SOLID), null, null,
        null, RegionStyles.ALIGN_LEFT, RegionStyles.ALIGN_TOP);

    TableView tableView = new TableView(_tableModel);
    TableController tableController = new TableController(_tableModel, tableView);

    tableController.setFocusPolicy(TableController.ROW_FOCUS);

    tableController.setCommand(new Command(new CommandHandler()
    {
        public void execute(ReadOnlyCommandMetadata metadata, Object context)
        {
            Dialog.alert("Command Executed");
        }           
    }));

    tableView.setController(tableController);

    DataTemplate dataTemplate = new DataTemplate(tableView, 1, 1)
    {
        /**
         * @see DataTemplate#getDataFields(int)
         */
        public Field[] getDataFields(int modelRowIndex)
        {
            final Object[] data = (Object[]) ((TableModel) getView().getModel()).getRow(modelRowIndex);

            Field[] fields = new Field[1];
            fields[0] = new LabelField((String)data[1], Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);

            return fields;
        }
    };

    dataTemplate.createRegion(new XYRect(0, 0, 1, 1), style);  
    dataTemplate.setColumnProperties(0, new TemplateColumnProperties(100, TemplateColumnProperties.PERCENTAGE_WIDTH));
    dataTemplate.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));

    tableView.setDataTemplate(dataTemplate);
    dataTemplate.useFixedHeight(true);

    add(tableView);
}
}

解决方案

Well, I loaded up the JDE 7.1 UI/TableAndListDemo sample app, and ran it on the JDE 9900.

That sample (unmodified by me) exhibits the exact same screwy behaviour as the code you posted.

So, unfortunately, I would say that either there is a bug, or a valid example of how to use the relatively new SortedTableModel has not been produced (I couldn't find any better ones).

Of note: if you remove the sorting, and simply replace SortedTableModel with TableModel, the visual corruption goes away for me. Of course, you lose the important feature of the sorting, and the grouping (column 0 in your table model).

Another option would be to implement the sorting behaviour yourself. Sorting the data outside of the TableModel is undesirable, but also not too difficult. Then, you could add an extra row to the repeating pattern, as a placeholder for the separator row that you currently have showing the single character (the sort criterion). You would also change the data template to not be fixed height.

Also, in the data template, you would define a region that can hold the separator row. Whether or not that region will show anything or not depends on whether the data row to follow has the same single character as the last row, or not. So, here's what the code might look like

  DataTemplate dataTemplate = new DataTemplate(tableView, 2, 1)    // 2 "rows", not 1
  {
     public Field[] getDataFields(int modelRowIndex)
     {
        final Object[] data = (Object[]) _tableModel.getRow(modelRowIndex);

        Field[] fields = new Field[2];
        String rowGroup = (String)data[0];
        // we're in a new group if this is the very first row, or if this row's
        //  data[0] value is different from the last row's data[0] value
        boolean isNewGroup = (modelRowIndex == 0) || 
              (rowGroup.compareTo((String) ((Object[])_tableModel.getRow(modelRowIndex - 1))[0]) != 0);
        if (isNewGroup) {
           // make a separator row
           fields[0] = new LabelField((String)data[0], 
                          Field.USE_ALL_WIDTH | Field.NON_FOCUSABLE);
        } else {
           // this is in the same group as the last product, so don't add anything here
           fields[0] = new NullField();
        }
        // now, add the actual product information
        fields[1] = new LabelField((String)data[1], 
                          Field.USE_ALL_WIDTH | Field.FOCUSABLE | DrawStyle.HCENTER);

        return fields;
     }
  };


  dataTemplate.createRegion(new XYRect(0, 0, 1, 1), style);    // group separator (maybe a null field)
  dataTemplate.createRegion(new XYRect(0, 1, 1, 1), style);    // actual rows with product information
  dataTemplate.setColumnProperties(0, new TemplateColumnProperties(100, TemplateColumnProperties.PERCENTAGE_WIDTH));
  dataTemplate.setRowProperties(0, new TemplateRowProperties(ROW_HEIGHT));   // separator
  dataTemplate.setRowProperties(1, new TemplateRowProperties(ROW_HEIGHT));   // product data
  dataTemplate.useFixedHeight(false);

In the above code, I chose to make the separator rows the same height and style as the product data rows. Of course, you could change that if you like.

One problem that this still doesn't solve is that of focus drawing. When you highlight the first row under the separator row, it draws focus on the product row, and the separator row above it.

You may need to implement some custom focus drawing. I'll leave that for the next question ... not sure if you even want to go this route. Hopefully I'm wrong, but it kind of looks like a bug in the RIM libraries to me :(

这篇关于滚动时黑莓的TableModel被搞砸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆