When a component is hidden, its height is forced to 0 which prevents the scrolling in Component to work when you drag it downwards. Basically, it can be dragged down to edge of the screen, but then no scrolling down happens. This issue was also mentioned earlier in SO here where Shai offered a path for investigation.
Any suggestions for a way to fix this issue?
Thanks
Here's a code sample to reproduce the issue (copy/paste into a Hello World project in replacement of the default start() method):
Image dragImage2;
Component dropPlaceholder;
void saveDragImage(Image dragIm) {
dragImage2 = dragIm;
}
public void start() {
if (current != null) {
current.show();
return;
}
/* To seee the issue: press and hold a button about 1 second to initiate the drag and drop,
then drag down to the lower edge of the screen: the list doesn't scroll down as normally.
When dragging upwards in a list (which must of course alreaday be scrolled down a bit),
it works as expected: When the dragged button reaches to top of the screen, the list scrolls down. */
Form hi = new Form("Hi World", new BorderLayout());
dropPlaceholder = new Label(" ... "); //used to create an empty space in the drop position
dropPlaceholder.setDropTarget(true);
Container list3 = new Container(BoxLayout.y());
for (int i = 0; i < 30; i++) {
Button draggableButton = new Button("Button number " + i) {
#Override
public void longPointerPress(int x, int y) {
setDraggable(true);
setFocusable(true);
dragImage2 = super.getDragImage();
setHidden(true);
Form f = getComponentForm();
f.pointerPressed(x, y);
pointerDragged(x - 1, y - 1); //move the dragged element a few pixels to initiate the drag
pointerDragged(x - 2, y - 2);
}
#Override
protected Image getDragImage() {
return dragImage2;
}
#Override
protected void dragFinished(int x, int y) {
setHidden(false);
if (dropPlaceholder != null)
dropPlaceholder.remove(); //remove the placeholder after drag
}
};
draggableButton.setDropTarget(true);
draggableButton.addDragOverListener((e) -> {
Component dropTarget = e.getDropTarget(); //may be null (in Component.dragFinishedImpl(int x, int y))
if (dropTarget != null) {
Container parent = dropTarget.getParent();
int index = parent.getComponentIndex(dropTarget);
dropPlaceholder.remove(); //remove placeholder from previous position
parent.addComponent(index, dropPlaceholder); //add placeholder at position of dropTarget
}
getCurrentForm().revalidate(); //refresh the screen to show the new position of placeholder
});
list3.add(draggableButton);
}
list3.setScrollableY(true);
Container cont = hi.getContentPane();
cont.add(BorderLayout.CENTER, list3);
hi.show();
}
I have a ComboBox with a ObservableList<Item> as model. I can update, externally to it, the elements of the list and I want to update the current selected item of ComboBox if it's modified.
I tried to do:
private final ObservableList<Item> list;
private ComboBox<Item> comboBox;
....
comboBox.setItems(list);
comboBox.getSelectionModel().selectFirst();
System.out.println("selected index: " + comboBox.getSelectionModel().getSelectedIndex(); );
ListChangeListener<Item> listener = new ListChangeListener<Item>() {
#Override
public void onChanged(ListChangeListener.Change<? extends Item> c) {
while (c.next()) {
for (int i = c.getFrom(); i < c.getTo(); ++i) {
int selectedIndex = comboBox.getSelectionModel().getSelectedIndex();
System.out.println("selected index: " + selectedIndex );
if (i == selectedIndex) {
comboBox.getSelectionModel().select(selectedIndex);
}
}
}
}
};
list.addListener(listener);
I added a ChangeListener to the list, so when some element in the list is updated, I can update the selected item in the comboBox. But this doesn't work 'cause comboBox.getSelectionModel().getSelectedIndex() inside onChange returns me -1 and I don't understand why (If I print the value out of onChange, for example the first System.out, the value is correct).
Can you explain me this behavior and if there is a better way to achieve what I want?
Thanks.
I have populated combobox from database in my RadGridView and I want that when it is in add mode my combobox shows its first item as default value. I used following code but I have Error in debuging on commented line in code
private void radGridView_CellValueChanged(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
if (e.Column.Name == "Productcolumn")
{
//ERROR on debuging following line
RadDropDownListEditor ed = this.radGridView.Columns["UnitPrice"] as RadDropDownListEditor;
if (ed != null)
{
// the default selected Price that will be shown will be the first price, if no price is selected for the current cell
RadDropDownListEditorElement editorElement = (RadDropDownListEditorElement)ed.EditorElement;
editorElement.SelectedIndex = 0;
}
}
}
Using this Expandable List checkbox example code as an baseline, I am trying to save and maintain the checkbox state. However, random checkboxes are being checked and unchecked ( triggering my OnCheckedChangeListener with the new values ) when I scroll them out of sight, minimize their group, or even minimize/maximize a nearby group!
public Object getChild(int groupPosition, int childPosition) {
return colors.get( groupPosition ).get( childPosition );
}
public long getChildId(int groupPosition, int childPosition) {
return (long)( groupPosition*1024+childPosition ); // Max 1024 children per group
}
public View getChildView(final int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View v = null;
if( convertView != null ) {
v = convertView;
} else {
v = inflater.inflate(R.layout.child_row, parent, false);
}
Color c = (Color)getChild( groupPosition, childPosition );
TextView color = (TextView)v.findViewById( R.id.childname );
if( color != null ) {
color.setText( c.getColor() );
}
TextView rgb = (TextView)v.findViewById( R.id.rgb );
if( rgb != null ) {
rgb.setText( c.getRgb() );
}
CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
cb.setChecked( c.getState() );
cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
colors.get(groupPosition).get(childPosition).setState(isChecked);
context.setColorBool(groupPosition, childPosition, isChecked);
Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
}
});
return v;
}
I don't know what piece of code could be responsible for this, so any suggestions on what to include here are welcome. My code only differs from the original in my attempt to save the values.
my guess is that as your adapter is creating views, the check listener is being called as the checkbox view is initialized. a lot of widgets in android work like this ... the listener is called when the view is initialized.
i don't know why things work like this, but it might be to allow the client code to initialize itself in a consistent way. e.g., whether the checkbox is checked by the user or whether it is initialized as checked, run the same code.
to counteract this, you can try doing something like setting a flag in your listener class impl to allow you to ignore the first click, something like,
cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
private void first = true;
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (first) {
first = false;
return;
}
colors.get(groupPosition).get(childPosition).setState(isChecked);
context.setColorBool(groupPosition, childPosition, isChecked);
Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked);
}
});
also, ensure that you are correctly re-using convertView in your implementation of getView() in your adapter. e.g.,
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.applications_item, null);
}
This is a very old question, but I struggled with the same problem so here is my answer for anybody looking:
The simplest way is to use CheckBox.onClickListener instead of onCheckedChangeListener.
This is only mildly annoying in terms of rearranging your logic, but will ensure that when the boxes are unchecked randomly (by, e.g. expanding an adjacent group) the event will not fire.
Honestly I think this should be considered a bug, even though I'm sure the behaviour can be explained from the Android source.
I've been implementing a way to 'tick all' checkboxes in my datagrid.
public void SelectAllCheckboxes(object sender, RoutedEventArgs e)
{
if (bindSource != null)
{
DataView list = (DataView)bindSource.List;
System.Windows.Controls.Button btn = e.OriginalSource as System.Windows.Controls.Button;
if (btn.Content.ToString() == "Select All")
{
for (int i = 0; i < list.Count; i++)
{
list[i]["Approve?"] = true;
}
}
else
{
for (int i = 0; i < list.Count; i++)
{
list[i]["Approve?"] = false;
}
}
bindSource.DataSource = list;
dataGrid.DataContext = bindSource;
}
}
When I use the method once to tick all checkboxes, it works fine. All checkboxes are ticked. However, when I try to 'select none' to untick everything the first checkbox will never ever change. The tick stays there.
This also happens in the reverse order of selection.
The datarow does retain the intended true/false value, it's just not represented on the grid.
What on earth is going on?
[edit]After some further testing, the checkbox works properly after I "wake it up" by clicking on it a few times and changing its ticked value. Very very strange.