Issue in on top side menu command - codenameone

The text in side menu command exceeds the width of the side menu, which makes somewhat peculiar effect.
see the video here
How can I set multiline as in textArea in this case?
Command protectedPlantAndSpecies = new Command(" Protected plants and species of nepal", protectedPlantIcon) {
#Override
public void actionPerformed(ActionEvent evt) {
new Notification(res).show();
}
};
f.getToolbar().addCommandToSideMenu(protectedPlantAndSpecies);

This is tickering which is enabled by default, you can disable it by calling this in your init(Object) method:
Label.setDefaultTickerEnabled(false);
You can also set the theme constant tickerSpeedInt to 0.

Related

Styling command in onTop side menu

What we do in commnads in older side menu is that we put the "uiid" in putClientProperty() method but it doesn't work in ontop side menu. How to style it?
Command services = new Command(" Services", servicesIcon) {
#Override
public void actionPerformed(ActionEvent evt) {
}
};
f.getToolbar().addCommandToSideMenu(services);
services.putClientProperty("uiid", "commandProp");
It still works but because the side menu is constructed eagerly instead of lazily you don't see this.
Instead of this:
f.getToolbar().addCommandToSideMenu(services);
services.putClientProperty("uiid", "commandProp");
Do:
services.putClientProperty("uiid", "commandProp");
f.getToolbar().addCommandToSideMenu(services);

Side Menu stopped working after new update

I have an app that has a nice side menu that comes from the left, after today's update it is completely empty when it slides out and I have no idea why.
here is how I show it,
SideMenuBar smb = (SideMenuBar) Display.getInstance().getCurrent().getMenuBar();
smb.openMenu(null);
Here is how it is created (remember this worked perfectly until today when I updated libs):
private void addSideMenuToLeft(Form f)
{
_("addSideMenuToLeft");
//make a toolbarForLeftMenu so we can use its sidemenu (we can only have one on the left!)
if (toolbarForLeftMenu==null)
{
toolbarForLeftMenu = new Toolbar();
}
toolbarForLeftMenu.setHidden(true);
f.setToolbar(toolbarForLeftMenu);
if (SideMenuLEFT==null) //otherwise it keeps adding each time
{
SideMenuLEFT = (Container)this.createContainer(resources, "SideMenuLEFT");
SideMenuLEFT.setWidth(Display.getInstance().getDisplayWidth()/2);
SideMenuLEFT.setHeight((Display.getInstance().getDisplayHeight()));
SideMenuLEFT.setUIID("SideNavigationPanel");//so we get the nice background.
toolbarForLeftMenu.setUIID("Container");
toolbarForLeftMenu.addComponentToSideMenu(SideMenuLEFT);
//make each button live, there are 2 buttons the icon and the words, for each one
Button btCategory = (Button) Tools.findByNameX("btCategory", SideMenuLEFT,sm );
btCategory.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt) {
}
});
_("made left menu");
}
}
We deprecated the SideMenuBar and replaced it with the new on-top side menu. It was announced multiple times and discussed quite a bit.
To disable this and use the "old" functionality you can use:
Toolbar.setOnTopSideMenu(false);

add pull2refresh to tabs in codenameone

i have added the following codes for pull2refresh but the run method is not called. I have tested for form and its ok for form. How to make it workable for tabs so that I can update all tab at once . and I have pull2refresh of form for whole for refresh.
findTabs1(f).getContentPane().addPullToRefresh(new Runnable() {
#Override
public void run() {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
//
}
});
Tab doesn't have contentPane but TabbedPane.
To add pullToRefresh to a tab, you should add it to the container you added to the tab and it must be scrollable-Y.
Instead of findTabs1(f).getContentPane().addPullToRefresh do findMyContainerInsideTab().addPullToRefresh

Using WPF Extended Toolkit MessageBox from other threads and curious behavior

I am having trouble using the WPF Extended Toolkit (version 2.1.0.0) MessageBox from other threads. The namespace is: Xceed.Wpf.Toolkit.MessageBox
I replaced my regular MessageBoxs (System.Windows.MessageBox) with the Toolkit MessageBox and get errors when I launch one from another thread. The System.Windows.MessageBox has no such problems. I saw this posting that reports the problem, but there seems to be no follow up:
https://wpftoolkit.codeplex.com/workitem/21046
I'm guessing there is a work around. An example is presented there that shows the problem, but here is my simple example:
First, I wrap the Toolkit.MessageBox. I do this primarily because I'm applying style (although I've commented that out to show that's not the problem)
public class CustomMessageBox
{
//static DummyUserControl1 _ctrl = new DummyUserControl1();
public static MessageBoxResult Show(string msgText, Style styleArg = null)
{
Cursor saveCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = null;
//Style style = styleArg != null ? styleArg : _ctrl.FindResource("MessageBoxStyle1") as Style;
// MessageBoxResult result = Xceed.Wpf.Toolkit.MessageBox.Show(msgText, "", MessageBoxButton.OK, style);
MessageBoxResult result = Xceed.Wpf.Toolkit.MessageBox.Show(msgText, "", MessageBoxButton.OK);
Mouse.OverrideCursor = saveCursor;
return result;
}
}
The main window just has two buttons on it, and here's the code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnMainThreadMsgBox_Click(object sender, RoutedEventArgs e)
{
CustomMessageBox.Show("Hello on main thread");
}
private void btnAltThreadMsgBox_Click(object sender, RoutedEventArgs e)
{
Thread altThread1 = new Thread(new ThreadStart(AltThread1Proc));
altThread1.SetApartmentState(ApartmentState.STA);
altThread1.Priority = ThreadPriority.AboveNormal;
altThread1.IsBackground = true;
altThread1.Start();
}
public void AltThread1Proc()
{
MessageBox.Show("Hello on Alt Thread");
CustomMessageBox.Show("Hello on alt thread");
}
}
The problems occur in AltThreadProc() with CustomMessageBox.Show(...). The curious behavior I referred to is this: If you hit the main thead button and then the Alt thread button, you get the error:
Cannot access Freezable 'System.Windows.Media.SolidColorBrush' across threads because it cannot be frozen.
However, if you skip the main thread button and just hit the Alt thread button, you get the error:
The calling thread cannot access this object because a different thread owns it.
I'm curious what the "Freezable" error is all about and why you can get different errors based on what would seem to be an innocuous event: clicking/not clicking button that produces message box on main thread.
Ideally, it would be nice to just replace System.Windows.MessageBox with Xceed.Wpf.Toolkit.MessageBox, but if there is some sort of extra code to write, that might be acceptable. The documentation, and the link I provided hints at using a WindowContainer, but I can't really see any examples of how you do that. I was attracted to the Toolkit MessageBox as it allows one to do some cool stuff with MessageBox (which I don't show here) such as apply styles, change the text of the OK, CANCEL button, etc.
Any ideas would be much appreciated.
Thanks,
Dave
Extra info:
User1341210 suggestion works well if you just have one window. However, if you have a second window in it's own thread it doesn't work so well. Perhaps someone can tell me what I'm doing wrong. I use the suggestion of the TaskScheduler, but the code throws an exception if the TaskScheduler used is the one of the second window. That is, all works fine if I use the TaskScheduler of the first window, but throws an exception if I use the TaskScheduler of the second window. Here is the code behind for my second window:
public partial class AltThreadWindow : Window
{
private TaskScheduler _ui;
public AltThreadWindow()
{
InitializeComponent();
_ui = TaskScheduler.FromCurrentSynchronizationContext();
}
// This constructor is for passing in the TaskScheduler of the mainwindow and works great
public AltThreadWindow(TaskScheduler scheduler)
{
InitializeComponent();
_ui = scheduler;
}
private void btnWindowsMsgBox_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Standard Windows message box");
}
private void btnCustomMsgBox_Click(object sender, RoutedEventArgs e)
{
MessageBoxResult result;
Task.Factory.StartNew(() => { result = CustomMessageBox.Show("Custom MessageBox on separate window"); }, CancellationToken.None,
TaskCreationOptions.None,
_ui);
}
}
Notice the two constructors. The default one assigns the TaskScheduler of the second window. The other constructor allows one to pas in the TaskScheduler of the main Window.
Here's the code I use to launch the second window from the main window. Again, I'm launching the second window on another thread, and I pass in the TaskScheduler of the main window. It would be nice to use the TaskScheduler of the second window instead.
_altWindowThread = new Thread(new ThreadStart(AltWinThreadProc));
_altWindowThread.SetApartmentState(ApartmentState.STA);
_altWindowThread.Priority = ThreadPriority.AboveNormal;
_altWindowThread.IsBackground = true;
_altWindowThread.Start();
And the actual threadproc:
[EnvironmentPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)]
public void AltWinThreadProc()
{
// Create our context, and install it:
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(
Dispatcher.CurrentDispatcher));
_altWindow = new AltThreadWindow(_ui);
_altWindow.Show();
System.Windows.Threading.Dispatcher.Run();
}
Notice here I pass in the TaskScheduler of the MainWindow.
we had the same issue in our application (I created the work item on codeplex).
The error messages are quite confusing and I cant provide you an answer to that.
But:
We didn't used a separated WindowContainer to solve it. Instead came up with calling the separate task/thread with the UI scheduler:
Task.Factory.StartNew(
() => { result = CustomMessageBox.Show(messageText); },
CancellationToken.None,
TaskCreationOptions.None,
_ui);
Where _ui is assigned in a method that is executed from UI context (e.g. Constructor of your Window/Control:
_ui = TaskScheduler.FromCurrentSynchronizationContext();
Hope this helps for solving the "replace System.Windows.MessageBox with Xceed.Wpf.Toolkit.MessageBox" part of your question.
If you want that the messagebox shows up on another Window you have to set the "Owner" property of the message box to the other window.
Best regards.

What is the Alternative to show "Please wait" window in wpf while the call is non threaded

Recently I needed to implement please wait dialog in wpf application. i found below code. it's really good but it always open an window in saprate thread and hold the position. is there any other alter for below code. while my request of code is non threaded.
private void NewWindowThread<T,P>(Func<P, T> constructor, P param) where T : Window
{
Thread thread = new Thread(() =>
{
T w = constructor(param);
w.Show();
w.Closed += (sender, e) => w.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
to call above method use below lines. where loading window is you window which you want to show at dialog (please wait. windows)
string t = "Please Wait…";
NewWindowThread<LoadingWindow, string>(c => new LoadingWindow(c), t);
Blocking the ui thread was never a good idea, but it is increasingly more a bad idea.
Windows will tell the user that your app stopped responding. This may incite them to force your appliccations. If you render progress bars, they will lose the animation effects, and they may render incorrect. In WPF the gui animations will stop.
Use background threads for the heavy processing, and if you need to write data back in the objects used by your main thread, marshall them back to the gui thread. BackgroundWorker can be useful there.
this might help you out.
public partial class Splash : Window
{
private static Splash splash = new Splash();
// To refresh the UI immediately
private delegate void RefreshDelegate();
private static void Refresh(DependencyObject obj)
{
obj.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render,
(RefreshDelegate)delegate { });
}
public Splash()
{
InitializeComponent();
}
public static void BeginDisplay()
{
splash.Show();
}
public static void EndDisplay()
{
splash.Close();
}
public static void Loading(string test)
{
splash.statuslbl.Content = test;
Refresh(splash.statuslbl);
}
}
using above code
Splash.BeginDisplay();
// Setting the status to show the application is still loading data
Splash.Loading("Connecting...");
// Set to sleep to simulate long running process
Thread.Sleep(1500);
Splash.Loading("Retrieving....");
Thread.Sleep(1500);
Splash.Loading("Success....");
Thread.Sleep(1500);
Splash.EndDisplay();

Resources