wicket I'm using three panels, but only one is displayed at a time, when the third panel is added to the code the second never appears - bootstrap-modal

I have a Modal class, when this modal is opened, it shows a panel asking the user if the user wants to proceed with the operation. If the user selects Yes the request is sent to the DB, which takes some time, during this time the first panel should be replaced by the second (which displays a spinner). This indeed happens if we do not use the third panel. Although I want to replace the second panel by the third panel in order to inform the user if the operation was successful or not (which depends of the message object,if it is null or have an error message).
So when I use addNewPanel(panel3, target) I never see panel2. I put a thread.sleep(5000) instruction after addNewPanel(panel2, target) and even so, this panel didn't appeared, I only get the initial and panel3 in the end.
If I do not use panel3 I see panel2.
Does anyone have an idea why is this happening?
Below I have the code of the Modal class
public class DetailsModal2 extends Modal<IModel<UserDomain>>{
#SpringBean
private IService service;
private BootstrapAjaxLink<String> noButton;
private ResponseMessage message;
private ProcessingPanel panel2;
private AlertPanel panel3;
private Panel replacedPanel;
public DetailsModal2(String id, IModel<UserDomain> model){
super(id);
replacedPanel = new AreYouSure("replacedPanel");
replacedPanel.setOutputMarkupId(true);
add(replacedPanel);
panel2 = new ProcessingPanel("replacedPanel");
panel3 = new AlertPanel("replacedPanel");
addButton(new BootstrapAjaxLink<String>("button", null, Buttons.Type.Warning, new ResourceModel("details")){
private static final long serialVersionUID = 1L;
#Override
public void onClick(AjaxRequestTarget target) {
// TODO Auto-generated method stub
//I was expecting to see this panel
addNewPanel(panel2,target);
// this puts this button invisible
this.setVisible(false);
target.add(this);
//this changes the label of the No button to Close
noButton.setLabel(Model.of("Close"));
target.add(noButton);
if(!service.retrieveData())
{
message = service.addUser("X");
if(message == null){
panel3.updateClassAndText(true);
addNewPanel(panel3,target);
}
else {
panel3.updateClassAndText(false);
addNewPanel(panel3,target);
System.out.println(""+ message.getError());
}
}//close if
else if(service.retrieveData())
{
message = service.removeUser("X");
if(message == null){
panel3.updateClassAndText(true);
addNewPanel(panel3,target);
}
else{
panel3.updateClassAndText(false);
addNewPanel(panel3,target);
System.out.println(""+ message.getError());
}
}
else{
System.out.println("It was not possible to access the db");
}
}
}
});
noButton = new BootstrapAjaxLink<String>("button", null, Buttons.Type.Primary){
private static final long serialVersionUID = 1L;
#Override
public void onClick(AjaxRequestTarget target) {
close(target);
}
}.setLabel(Model.of("No"));
addButton(noButton);
}
public void addNewPanel(Panel addpanel, AjaxRequestTarget target ){
Panel newPanel = null;
newPanel = addpanel;
newPanel.setOutputMarkupId(true);
replacedPanel.replaceWith(newPanel);
target.add(newPanel);
}
}//close class
HTML
<wicket:extend>
<div><span wicket:id="replacedPanel"> </span></div>
</wicket:extend>

Wicket atmosphere is deprecated from wicket 8 and will not be supported anymore, so do not use it ..

Related

List<models.object1> updates every time an instance of Object1 is changed

I'm working on a wpf app. visual studio 2022
I have the following code in a file for testing and have set a button click event to run WriteWorkOrderList(). nothing gets passed to it: there are no other methods or anything:
private List<Models.WorkOrder> _workOrderList = new List<Models.WorkOrder>();
public List<Models.WorkOrder> WorkOrderList
{
get
{
return _workOrderList;
}
set
{
if (_workOrderList != value)
{
_workOrderList = value;
NotifyPropertyChanged();
}
}
}
private Models.WorkOrder _currentWorkOrder = new Models.WorkOrder();
public Models.WorkOrder CurrentWorkorder
{
get
{
return _currentWorkOrder;
}
set
{
if (_currentWorkOrder != value)
{
_currentWorkOrder = value;
NotifyPropertyChanged();
}
}
}
public void WriteWorkOrderList()
{
CurrentWorkorder.Customer.Name = "Billy";
WorkOrderList.Add(CurrentWorkorder);
}
I placed a Breakpoint at the beginning of the WriteWorkOrderList()
method
I'll let it continue the first time. and get one record in
WorkOrderList with Customer.Name=Billy.
the second time I click the
button and get to the breakpoint I will change the
CurrentWorkOrder.Customer.Name= "joe".
I'll Step through the code
as soon as the line CurrentWorkorder.Customer.Name = "Billy"; gets processed the record in WorkOrderList updates to the new name
I can't figure out how they are connecting to each other. All I'm trying to do is add a new WorkOrder to the Workorderlist but I haven't Even gotten that far

How to close the card by itself after executed a HTTP request?

I have an app with contextual commands. After triggered a contextual command, it will make a HTTP request with a link and post the result on the card, something like, "Completed!". I want this card to be closed by itself after one second so that the user need not to tap to close it. Once the result card is closed, it will go back to contextual command lists with "Ok, glass" at footer and ready for next command.
May i know how to do that?
private class HTTPRequest extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
if (mWhat.equalsIgnoreCase("GET")) {
// get json via YouTube API
URL url = new URL("http://example.com");
mUrlConnection = (HttpURLConnection)
url.openConnection();
InputStream in = new BufferedInputStream(
mUrlConnection.getInputStream());
int ch;
StringBuffer b = new StringBuffer();
while ((ch = in.read()) != -1) {
b.append((char) ch);
}
mResult = new String(b);
}
} catch (Exception e) {}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mTvInfo.setText(mResult);
}
You can use an Android Dialog for this:
Use CardBuilder to create the "Completed" card using the MENU layout.
Create a new instance of Dialog and set its content view to be the view returned by CardBuilder.getView.
Show the dialog.
Use Handler.postDelayed (or some similar mechanism) to automatically dismiss the dialog after the desired amount of time has passed.

Card not showing; goes straight to home card

I am trying to show a card so I know everything up to that point works. However, when I try to display the card, it just goes straight to the home card. The card I was trying to show was just going to display what was said in the voice recognizer before but that didn't work so I just put plain text and that didn't work either. Application goes - voice trigger --> voice recognizer --> this service:
public class MedMinderService extends Service {
public String MedName;
public String voiceResults;
private static final String TAG = "ShowData";
private static final String LIVE_CARD_ID = "showdata";
public static final String PREFS_NAME = "MyPreferencesFile";
private TimelineManager mTimelineManager;
private LiveCard mLiveCard;
#Override
public void onCreate() {
super.onCreate();
mTimelineManager = TimelineManager.from(this);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId) {
String voiceResults = intent.getExtras()
.getString(RecognizerIntent.EXTRA_RESULTS);
String MedName = voiceResults; //MedName declared
SharedPreferences MedInfo = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = MedInfo.edit();
editor.putString("MedName", MedName.toString());
editor.commit();
mLiveCard = mTimelineManager.getLiveCard(LIVE_CARD_ID);
Intent i = new Intent(this, ShowDataActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
return START_STICKY;
}
}
The intent at the bottom goes to this activity:
public class ShowDataActivity extends Activity {
private LiveCard mLiveCard;
public static final String PREFS_NAME = "MyPreferencesFile";
private GestureDetector mGestureDetector;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences MedInfo = getSharedPreferences(PREFS_NAME, 0);
Card ShowDataCard = new Card(this);
ShowDataCard.setText("IT WORKS!");
//ShowDataCard.setText(MedInfo.getString("MedName", "your medication"));
View ShowDataCardView = ShowDataCard.toView();
setContentView(ShowDataCardView);
}
The "ShowDataCard" that has been commented out is what I was origonally trying to do with the voice recognition but it wouldn't even work with the text "IT WORKS!"
Again: I am just trying to show a card with the text "IT WORKS"
thanks
The easiest way to get a live card to appear with just text is using widgets that are compatible with RemoteViews. You can find a list of them in the GDK documentation here:
https://developers.google.com/glass/develop/gdk/ui/live-cards
under the Creating low-frequency live cards section.
Here is some sample code (based on your code above) that can get that working quickly:
final String LIVE_CARD_ID = "showdata";
mLiveCard = mTimelineManager.getLiveCard(LIVE_CARD_ID);
RemoteViews remoteViews =
new RemoteViews(getPackageName(), R.layout.layout_helloglass);
mLiveCard.setViews(remoteViews);
// Make sure Glass navigates to LiveCard immediately
mLiveCard.setNonSilent(true);
mLiveCard.publish();
The layout file can look like this for layout_helloglass.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Hello, Glass!" />
</FrameLayout>
If you still want to navigate to another Activity from your LiveCard, you need to associate the Activity with a PendingIntent and then associate that PendingIntent with the LiveCard's action. This would happen immediately before the LiveCard.publish() method:
Intent i = new Intent(this, ShowCardActivity.class);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, i, 0));
That should get you up and running! Hopefully this will help.
There was a bug in the GDK Sneak Peek that prevented voice prompts from creating Services. If one inserted a Log.d() call in a Service's onStartCommand() override, they would discover that it were never called.
This bug has been fixed in the GDK Preview. This behavior should not appear again.
This question was rewritten after the GDK Preview launch to remove this outdated answer. Thanks to user Falcon for notifying me.

Repaining listfield on editfield change Input

I am using Google place API in my application for searching location. When user input text in edit field then the API called and resulted output will shown in a list.
I implemented it successfully but the problem is that each time edit field text changes, the list is not repainting and output is added to the end of the list. I want every time the text changes in the edit text field, the list must remove its previous content that are invalid.
This can be seen in pictures:
For Implementing this, I have written this code:
public final class MyScreen extends MainScreen {
/**
* Creates a new MyScreen object
*/
private Vector _listElements;
ListField list;
JSONObject[] jsonobject;
EditField editfield;
String url = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=";
String[] locationName;
VerticalFieldManager verticalFieldManager = new VerticalFieldManager();
public MyScreen() {
ButtonField search = new ButtonField("Search");
_listElements = new Vector();
list = new ListField();
ListCallback _callback = new ListCallback(this);
// Set the displayed title of the screen
setTitle("Search Edit Field");
editfield = new EditField();
editfield.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
list.invalidate();
createField();
}
});
}
});
list.setCallback(_callback);
add(editfield);
add(new SeparatorField());
verticalFieldManager.add(list);
add(verticalFieldManager);
}
protected void createField() {
ShowList();
reloadList();
}
private void reloadList() {
list.setSize(_listElements.size());
}
class ListCallback implements ListFieldCallback {
MyScreen listDemoScreen;
public ListCallback(MyScreen listDemoScreen) {
this.listDemoScreen = listDemoScreen;
}
public void drawListRow(ListField list, Graphics g, int index, int y,
int w) {
String text = (String) _listElements.elementAt(index);
list.setRowHeight(getFont().getHeight());
g.drawText(text, 0, y, 0, -1);
}
public Object get(ListField list, int index) {
return _listElements.elementAt(index);
}
public int indexOfList(ListField list, String prefix, int string) {
return _listElements.indexOf(prefix, string);
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
}
protected void ShowList() {
HttpConnection httpConn;
InputStream in;
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
String response;
String fieldText = editfield.getText();
connDesc = connFact.getConnection(url + fieldText
+ "%#&sensor=true&key=xxxxxxxxxxxxx"
+ ConnectionType.getConnectionType());
if (connDesc != null) {
httpConn = (HttpConnection) connDesc.getConnection();
try {
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpConnection.HTTP_OK) {
in = httpConn.openInputStream();
StringBuffer buf = new StringBuffer();
int read = -1;
while ((read = in.read()) != -1)
buf.append((char) read);
response = buf.toString();
try {
JSONObject object = new JSONObject(response);
JSONArray ar = object.getJSONArray("predictions");
jsonobject = new JSONObject[ar.length()];
locationName = new String[ar.length()];
list.invalidate();
for (int i = 0; i < ar.length(); i++) {
jsonobject[i] = ar.getJSONObject(i);
_listElements.addElement(jsonobject[i]
.getString("description"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
Dialog.alert("Connection not succeded");
}
}
protected boolean onSavePrompt() {
return true;
}
}
Update and Solution:
only modify this and this rest is working fine. As Peter Suggests, we can also put a Thread.sleep(time); in order to get the UI not blocked:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_listElements.removeAllElements();
createField();
}
});
I think your problem is simply that you do not clear the _listElements Vector when you request more data. So _listElements just gets bigger.
However there is a bigger problem here and that is that your code appears to be running networking operations on the Event Thread. What your should do in your changeListener. is start a Thread that requests the data, then repopulate the ListField when this tread gets data.
As a result of this change, the UI will not be blocked, and the List updates will become asynchronous, so your user could in fact enter another character into the EditField before the first Thread response comes back. To prevent this looking silly, you could delay the Thread processing for a fraction of second to see if another character is entered, and/or you could make sure that the EditField content was still the same as the requested characters before you repopulate it.
I personally prefer this asynchronous approach, but if it bothers you, you could put a 'please wait - loading' type screen to block the user until the response comes back.
Update
Remember that if you start a background Thread, you need to get back onto the Event Thread to do Ui Processing. Typically this is done simply by including your UI code within the run method of a Runnable that is invoked later, for example:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// Ui Code in here
}
});
You should only put Ui Updating code in the runnable. Networking processing, or any other blocking action, should NOT be included.

Action Bar switching tabs automatically:

I am implementing an app where user can search some songs in a separate tab.The search results for a song are info like lyrics, meaning etc. From the results, user can mark certain songs as favorite which are in another tab. When I click on the favorite songs tab, it should switch to the first tab with fragment for the search results. Here are more specific details:
Main Activity spawns action bar which creates 2 tabs.
Search Tab - Separate Fragment, Results- separate fragment
Favorites Tab - Separate Fragment
public class TabsListener<T extends Fragment> implements ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/** Constructor used each time a new tab is created.
* #param activity The host Activity, used to instantiate the fragment
* #param tag The identifier tag for the fragment
* #param clz The fragment's Class, used to instantiate the fragment
*/
public TabsListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
/* The following are each of the ActionBar.TabListener callbacks */
#SuppressLint("NewApi")
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
#SuppressLint("NewApi")
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
// Detach the fragment, because another one is being attached
ft.detach(mFragment);
//ft.remove(mFragment);
}
}
#SuppressLint("NewApi")
public void onTabReselected(Tab tab, FragmentTransaction ft) {
ft.attach(mFragment);
// User selected the already selected tab. Usually do nothing.
}
}
How can I implement this switching from one tab to another programatically for Action Bar?