im using ActionBar Sherlock 4.2. I get a null reference in my onPrepareOptionsMenu Method when the user rotates the Device. It happens when switching back from a Dual Fragment Layout in Landscape mode to Protrait Mode which only displays the 'master' fragment without the Detail Fragment. But still my Detail Fragment gets called. First i throught i did something wrong in my menu.xml, but this is simply not the case. The Activity is null returned. Anyone have a tip where what may is wrong there ?
Strange is also that the code passes the isDetached() check.
Any hints appreciated,
Kitesurfer
/*
* (non-Javadoc)
*
* #see android.support.v4.app.Fragment#onPrepareOptionsMenu(android.support. v4.view.Menu)
*/
#Override
public void onPrepareOptionsMenu(final Menu menu)
{
if (getListAdapter() == null || getListAdapter().isEmpty() && isDetached())
{
return;
}
final MenuItem item = menu.findItem(R.id.forecast_options_navigate_to_spot);
Log.d(LOG_TAG, "Menu item size:" + menu.size());
Log.d(LOG_TAG, "Activity:" + getSherlockActivity());
Output:
11-11 13:07:46.862: D/MyFragment(27997): Menu item size:8
11-11 13:07:46.862: D/MyFragment(27997): Activity:null
So, i found what is wrong. In my PagerAdapter i did something stupid.
In my
public void onTabUnselected(final Tab tab, final FragmentTransaction nullTransaction)
I did a call to getItem() which creates another Fragment, which of course gets detached in this Method. This causes the Activity to be null in onPrepareOptionsMenu.
Related
I am developing a Xamarin.Forms application targeting the iOS platform. I want to only allow stylus input (i.e. disallow finger/direct input) in my entire app except for one single control (a SwitchCell).
For that, I implemented a custom UIApplication class and overrode the SendEvent(UIEvent uievent) method.
In SendEvent I am checking whether the event is a touch event using uievent.Type == UIEventType.Touches. Then I want to detect, if the touch occurred in the SwitchCell in which touch input should be allowed.
Because the SwitchCell is created in my Xamarin.Forms project as XAML, I implemented my own TaggableSwitchCell class inheriting from SwitchCell with a Tag property and registered a CustomRenderer that sets the Tag property of the UITableViewCell on iOS (which works as expected):
public class TaggableSwitchCellRenderer : SwitchCellRenderer
{
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var cell = base.GetCell(item, reusableCell, tv);
cell.Tag = (item as TaggableSwitchCell).Tag;
Log.Debug("Setting tag to " + cell.Tag);
return cell;
}
}
Then, in the SendEvent method, I check for the tag:
var isTouchAllowed = uievent.AllTouches.Any((touch) =>
{
var uitouch = touch as UITouch;
return uitouch.View != null && uitouch.View.ViewWithTag(Constants.Tag) != null;
});
Running this code on the device (iPad Pro 3rd Generation) works fine for every touch that is not in the SwitchCell. However, if the touch is in the SwitchCell (meaning isTouchAllowed should be true), the following message is printed (the app does not crash):
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
I know, that the problem is with the uitouch.View.ViewWithTag(Constants.Tag) != null statement, but I don't know how to solve it. I already tried manually checking the view tag using uitouch.View.Tag == Constants.Tag but this leads to the same problem.
http://code.makery.ch/blog/javafx-dialogs-official/ shows how to get the stage of a JavaFX-8 dialog:
// Get the Stage.
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
Alas, this does not work for me: the dialog pane (although displayed) gives null on .getScene().
Is there any other easy way to get the stage or at least the scene of an open dialog window?
The background of the question is that, under certain circumstances, need to display an Alert to the user while keeping the underlying dialog window open. Currently, that does not work due to an invalid combination of Modality values, but that's a different topic.
Hard to say for sure if you post no context code but I think the problem is the timing. You need to get the stage before you showAndWait (or at least before the dialog is closed). Try this:
public static boolean showConfirmationDialog(String contentText, String headerText) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, contentText, ButtonType.YES, ButtonType.NO);
alert.setTitle("Test");
alert.setHeaderText(headerText);
Window alertWindow = alert.getDialogPane().getScene().getWindow();
System.out.println("alertWindow.getOpacity(): " + alertWindow.getOpacity());
Optional<ButtonType> result = alert.showAndWait();
//This would cause a NullPointerException at this point:
//alertWindow = alert.getDialogPane().getScene().getWindow();
//System.out.println("alertWindow.getOpacity(): " + alertWindow.getOpacity());
return (result.get() == ButtonType.YES);
}
So, I'm trying to delete the highlighted row in TableView in my program.
I've looked at loads of tutorials online, but really can't get my head around this.
I have followed the example from CodeMakery, which is in Eclipse, but I'm unable to get it to work on IntelliJ (because of some apparent JDK problems?)
This is the code from CodeMakery:
private void handleDeletePerson() {
int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0) {
personTable.getItems().remove(selectedIndex);
} else {
// Nothing selected.
Alert alert = new Alert(AlertType.WARNING);
alert.initOwner(mainApp.getPrimaryStage());
alert.setTitle("No Selection");
alert.setHeaderText("No Person Selected");
alert.setContentText("Please select a person in the table.");
alert.showAndWait();
}
}
Could you please help me understand how to make selected row get deleted?
just add at the beginning of this method personTable.setEditable(true). Should work now.
I am having trouble augmenting the default edit behavior of QTableView. I want the following behavior when the Enter key is pressed:
Start editing the current cell if it is not already being edited.
If the cell is being edited,
2a. commit the data and close the editor. Then,
2b. make the cell below, if present, the current cell.
2a is the default behavior, and 2b can likely be achieved by using QAbstractItemView::setCurrentIndex() in a re-implementation of QItemDelegate::eventFilter() (as suggested here in a similar context).
The problem is in achieving 1. I list below the approaches I have tried till now.
Reconfigure the "platform edit key" By default, "Editing starts when the platform edit key has been pressed over an item." (QAbstractItemView::EditKeyPressed) This key is F2 on my platform (Ubuntu 12.04). I could reconfigure the platform edit key to Enter but
Altering platform defaults seems like a bad idea.
I could not find out how to do it.
Capture the Enter key press I use QShortCut to do this as follows:
class CourseTable : public QTableView {
/* ... */
};
/* ... */
CourseTable::CourseTable(/* ... */) {
/* ... */
QShortcut* shortcut = new QShortcut(QKeySequence(Qt::Key_Return), this);
connect(shortcut, SIGNAL(activated()), this, SLOT(handleEnter_()));
/* ... */
}
/* ... */
void CourseTable::handleEnter_() {
QModelIndex idx = this->currentIndex();
if (this->state() != QAbstractItemView::EditingState)
this->edit(idx);
/* else // see below */
}
This does capture the Enter key-press and accomplishes 1 (from above) but now 2 is broken. So, I need to look into the else clause in CourseTable::handleEnter_() above, possibly calling QAbstractItemView::commitData() and QAbstractItemView::closeEditor in it. The problem is that both these functions require a QWidget *editor argument which I just cannot figure out how to get. I could subclass QAbstractItemDelegate, add a getEditor() method to the derived class, and modify existing code to pass instances of the derived delegate class to CourseTable::setItemDelegate*() functions. But that sounds like too much work.
So, any ideas how I can cleanly accomplish both 1 and 2 without having to rewrite my code?
Why cant you just filter the event also for starting the edit?
Just handle the event if state is != QAbstractItemView::EditingState
Returning true in this function makes the event stop propagating to the filtered object.
If state is Editing you can just return falseand allow the table and editor continue processing the event.
Something like this:
bool FilterObject::eventFilter(QObject *object, QEvent *event)
{
if (object == tableView && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return && tableView->state() != QAbstractItemView::EditingState) {
// set current cell to edit
return true;
} else
return false;
}
return false;
}
In my other methods (data, text, etc.) the setItem method works fine to display changes made to a tree item. However, calling setItem after changing an item's icon doesn't seem to have any effect. What is the best way to update the tree item so the new icon appears?
Thanks
public void modified()
{
FormTreeItem workingItem;
;
super();
//find the current item
workingItem = FormTreeControl.getItem(FormTreeControl.getSelection());
//update the value
workingItem.Image(1);
//update the item in the list
FormTreeControl.setItem(workingItem);
}
Found a couple of issues here:
1. Never found a way to update the icon on a tree item effectively.
2. Found out some of the tree control objects aren't initialized if you try to add/delete from a datasource method, so deleting items throws Object Not Initialized errors.
Fixed it by:
1. Create a new item (addAfterIdx of the old item).
2. Delete the old item.
3. Select the new item.
3. Move the method from the datasource to the actual form control.
Here's the code that worked for me:
public boolean modified()
{
boolean ret;
FormTreeItem workingItem = FormTreeControl.getItem(currentEditingIdx);
TreeItemIdx newItemIdx;
;
ret = super();
//create a new item
newItemIdx = SysFormTreeControl::addTreeItem(FormTreeControl, workingItem.text(), FormTreeControl.getParent(workingItem.idx()), workingItem.data(), element.imageIdx(ABC_Icon.text()));
//delete the old item
FormTreeControl.delete(currentEditingIdx);
//select the new item
FormTreeControl.selectionChanged(FormTreeControl.getItem(FormTreeControl.getRoot()), FormTreeControl.getItem(newItemIdx), FormTreeSelect::Unknown);
return ret;
}