Blackberry Tablemodel gets messed up when scrolling

佐手、 提交于 2020-01-05 07:11:58

问题


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);
}
}

回答1:


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



来源:https://stackoverflow.com/questions/11189109/blackberry-tablemodel-gets-messed-up-when-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!