I wrote my own custom error handler for the UI in Vaadin flow. But when I throw the exception my view crash and not show my human readable error message.
I did this in other application using Vaadin 8 and works perfectly. The idea its throw a SgiException in my backend services like:
Product not found
Incorrect value for field "XXX"
Not available stock for the product.
etc.
And then show a system notification
public static void setDefaultErrorHandler(ErrorEvent errorEvent) {
Throwable t = DefaultErrorHandler.findRelevantThrowable(errorEvent.getThrowable());
String message;
if (t != null) {
message = t.getMessage();
} else {
message = "";
}
log.error(message, t);
SgiException sgiException = getCauseOfType(t, SgiException.class);
if (sgiException != null) {
NotificationBuilder.exception(sgiException.getCode(), sgiException.getMessage());
return;
} else {
NotificationBuilder.exception(UNKNOW_ERROR, (message == null ? "" : message));
return;
}
}
private static <T extends Throwable> T getCauseOfType(Throwable th, Class<T> type) {
while (th != null) {
if (type.isAssignableFrom(th.getClass())) {
return (T) th;
} else {
th = th.getCause();
}
}
return null;
}
And this is how I set the custom error handler:
#PostConstruct
public void configBaseView() {
VaadinSession.getCurrent().setErrorHandler(Util::setDefaultErrorHandler);
}
In the view show this:
Note:
Debugging the application, seeing the code it's running, looks the method its called for some reason not show the notification.
This is a nasty behaviour that can't currently be overridden in Vaadin 10. Follow and vote (thumb up or comment) this issue to get it solved: https://github.com/vaadin/flow/issues/801
Related
I need to add header to a STOMP message currently it is working as below but i am recreating the message , is it possible to just add native header without having to recreate the message for performance .
public class MyChannelInterceptor extends ChannelInterceptorAdapter {
#Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
StompCommand command = accessor.getCommand();
if(command != null) {
log.debug("Receiving msg {} from {}",command,accessor.getUser().getName());
if(command == StompCommand.SEND) {
log.debug("Adding expires header to msg {} from {}",command,accessor.getUser().getName());
String ttlString = accessor.getFirstNativeHeader("ttl");
long ttl = 30000;
try {
ttl = Long.parseLong(ttlString);
}
catch(Exception ex) {
log.error("TTL header received but not in correct format {}",ttlString);
}
accessor.addNativeHeader("expires", Long.toString(System.currentTimeMillis() + ttl));
return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
}
}
return message;
}
}
This is what i was looking for
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
The above code will get the actual StompHeaderAccessor of the message so if you manipulate the native headers they are directly reflected on the message while
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
will get a clone of the headers and you have to create a new message with the new cloned headers
full fixed code below
#Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
// StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if(accessor != null) {
StompCommand command = accessor.getCommand();
if(command != null) {
log.debug("Receiving msg {} from {}",command,accessor.getUser().getName());
if(command == StompCommand.SEND) {
log.debug("Adding expires header to msg {} from {}",command,accessor.getUser().getName());
String ttlString = accessor.getFirstNativeHeader("ttl");
long ttl = 30000;
if(ttlString != null) {
try {
ttl = Long.parseLong(ttlString);
}
catch(Exception ex) {
log.error("TTL header received but not in correct format {}",ttlString);
}
}
accessor.addNativeHeader("expires", Long.toString(System.currentTimeMillis() + ttl));
// I don't need any more to create a new message
//return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
}
}
}
return message;
}
Since addNativeHeader succeeds, that indicates the message is still mutable - see addNativeHeader().
In any case, since the NATIVE_HEADERS message header is a MultiValueMap-valued header, you can update the header contents in-place.
Hence, there is no need to create a new message.
You would have to create a new message if you add a new header to the message itself (rather than updating the mutable contents of an existing header).
EDIT
I just ran a test; as long as the message is still mutable, you can change it...
#Test
public void test() {
Map<String, Object> map = new HashMap<String, Object>();
MutableMessageHeaders headers = new MutableMessageHeaders(map);
Message<String> message = MessageBuilder.createMessage("foo", headers);
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
accessor.addNativeHeader("foo", "bar");
System.out.println(message.getHeaders().get(NativeMessageHeaderAccessor.NATIVE_HEADERS));
accessor.setImmutable();
try {
accessor.addNativeHeader("baz", "qux");
fail("expected IllegalStateException");
}
catch (IllegalStateException e) {
}
}
That said, are you experiencing a performance problem or is this just a perceived issue. Message creation is not expensive.
I am using default android printer option (android version 4.4)
I want to byPass printManager adapter popup. how to hide the popup and give a direct print to the printer in android
you cannot extend PrintManager class. It is a final class .Please check below link
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.4_r1/android/print/PrintManager.java
These guys have designed their own printing framework.Where they are designing their own dialog.Have a look
http://apf.isb-vietnam.com/index.php/programming-with-apf.html
It seems to me like the answer is yes.
Here is the print() method from Android's PrintManager class:
public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter, PrintAttributes attributes)
{
if (mService == null)
{
Log.w(LOG_TAG, "Feature android.software.print not available");
return null;
}
if (!(mContext instanceof Activity))
{
throw new IllegalStateException("Can print only from an activity");
}
if (TextUtils.isEmpty(printJobName))
{
throw new IllegalArgumentException("printJobName cannot be empty");
}
if (documentAdapter == null)
{
throw new IllegalArgumentException("documentAdapter cannot be null");
}
PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate((Activity) mContext, documentAdapter);
try
{
Bundle result = mService.print(printJobName, delegate, attributes, mContext.getPackageName(), mAppId, mUserId);
if (result != null)
{
PrintJobInfo printJob = result.getParcelable(EXTRA_PRINT_JOB);
IntentSender intent = result.getParcelable(EXTRA_PRINT_DIALOG_INTENT);
if (printJob == null || intent == null)
{
return null;
}
try
{
mContext.startIntentSender(intent, null, 0, 0, 0);
return new PrintJob(printJob, this);
}
catch (SendIntentException sie)
{
Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
}
}
}
catch (RemoteException re)
{
Log.e(LOG_TAG, "Error creating a print job", re);
}
return null;
}
Simply create your own class (I will pretend it is named MyPrintManager) which extends PrintManager and #Override the print() method in it. Then, use the code above, but remove this line:
mContext.startIntentSender(intent, null, 0, 0, 0);
Then, get an instance of the MyPrintManager class using the code below:
MyPrintManager printManager = (MyPrintManager) appContext.getSystemService(Context.PRINT_SERVICE);
You could try this, though I am not sure if it works, because I haven't tested it. Please reply with the result, and I will try to help you further if it didn't work.
I'm attempting to implement a BroadcastReceiver that will tell me when the network status has changed. I'll be using that to sync local data back to the main server when I get internet connection back after losing it.
As a start I was looking at this example: http://fizzylogic.nl/2013/08/17/xamarin-android-by-example-monitoring-the-network-status/
public class NetworkStatusMonitor
{
private NetworkState _state;
public NetworkStatusMonitor ()
{
}
public NetworkState State {
get {
UpdateNetworkStatus ();
return _state;
}
}
public void UpdateNetworkStatus() {
_state = NetworkState.Unknown;
// Retrieve the connectivity manager service
var connectivityManager = (ConnectivityManager)
Application.Context.GetSystemService (
Context.ConnectivityService);
// Check if the network is connected or connecting.
// This means that it will be available,
// or become available in a few seconds.
var activeNetworkInfo = connectivityManager.ActiveNetworkInfo;
if (activeNetworkInfo.IsConnectedOrConnecting) {
// Now that we know it's connected, determine if we're on WiFi or something else.
_state = activeNetworkInfo.Type == ConnectivityType.Wifi ?
NetworkState.ConnectedWifi : NetworkState.ConnectedData;
} else {
_state = NetworkState.Disconnected;
}
}
}
public enum NetworkState
{
Unknown,
ConnectedWifi,
ConnectedData,
Disconnected
}
Then my broadcast receiver looks like this:
[BroadcastReceiver()]
public class NetworkStatusBroadcastReceiver: BroadcastReceiver {
public event EventHandler ConnectionStatusChanged;
public override void OnReceive (Context context, Intent intent)
{
if (ConnectionStatusChanged != null)
ConnectionStatusChanged (this, EventArgs.Empty);
}
}
Now my question is... Where do I initialize this and where do I put the following Start() and Stop() methods?
public event EventHandler NetworkStatusChanged;
public void Start ()
{
if (_broadcastReceiver != null) {
throw new InvalidOperationException (
"Network status monitoring already active.");
}
// Create the broadcast receiver and bind the event handler
// so that the app gets updates of the network connectivity status
_broadcastReceiver = new NetworkStatusBroadcastReceiver ();
_broadcastReceiver.ConnectionStatusChanged += OnNetworkStatusChanged;
// Register the broadcast receiver
Application.Context.RegisterReceiver (_broadcastReceiver,
new IntentFilter (ConnectivityManager.ConnectivityAction));
}
void OnNetworkStatusChanged (object sender, EventArgs e)
{
var currentStatus = _state;
UpdateNetworkStatus ();
if (currentStatus != _state && NetworkStatusChanged != null) {
NetworkStatusChanged (this, EventArgs.Empty);
}
}
public void Stop() {
if (_broadcastReceiver == null) {
throw new InvalidOperationException (
"Network status monitoring not active.");
}
// Unregister the receiver so we no longer get updates.
Application.Context.UnregisterReceiver (_broadcastReceiver);
// Set the variable to nil, so that we know the receiver is no longer used.
_broadcastReceiver.ConnectionStatusChanged -= OnNetworkStatusChanged;
_broadcastReceiver = null;
}
Sorry for the probably silly question but still new to Xamarin and Android.
I think following link is helpful. I get the notification when the network status changes.
networkstatusbroadcastreceiver See Bradley's answer on the bottom of the page.
I am trying to download xml files from server when my application starts. So i want to show splash screen until am done with downloading and then show next screen. below is my code:
Here, i want to show My splash screen when getTopNotDoc() method is under execution. and after completion of that method show next screen.
//get _topics and notification document<br>
_getDoc = new ServerConnectivity(this);
public class ServerConnectivity {
private Document _questionDoc;
private Document _topics;
private Document _notifications;
public ServerConnectivity(ApplicationSession appSession){
//getTopNotDoc();
_this = this;
_appSession = appSession;
new Thread(new Runnable(){
public void run(){
getTopNotDoc();
}
}).start();
}
}
private void getTopNotDoc(){
InputStream inputStream = null ;
try{
// Build a document based on the XML file.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
inputStream = getClass().getResourceAsStream("topics.xml");
_topics = builder.parse( inputStream );
inputStream = getClass().getResourceAsStream("notification.xml");
_notifications = builder.parse( inputStream );
if(_topics == null || _notifications == null){
Dialog.alert("Unable to connect to internet");
}
}
catch ( Exception e ){
System.out.println( e.toString() );
}
finally{
if(inputStream != null){
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
Usually when I do this, I create a loading screen, then I just extend the Thread class.
So I would create a loading screen like this:
public class LoadingScreen extends MainScreen {
public LoadingScreen() {
super();
this.setTitle("loading...");
// add a spinning animated gif or whatever here
final Screen me = this;
new Thread(new Runnable(){
public void run(){
// do something that takes a long time
try { Thread.sleep(1000);} catch (Exception e) {}
}
}){
public void run() {
super.run();
synchronized (UiApplication.getEventLock()) {
UiApplication.getUiApplication().popScreen(me);
}
}
}.start();
}
}
Then I push this screen, it will perform the long task, and then pop itself when its done.
(you may or may not want to disable the back button and menus on this screen)
I made the Runnable as an anonymous inner class just to compact the code, but you probably have this code already in a class somewhere else, so you would pass it in instead.
To add some flexibility and keep your classes loosely coupled together, you could make some modifications to your ServerConnectivity class so your calls could go something like the following:
// push your splash screen on to the stack
//
final SplashScreen splashScreen = new SplashScreen();
UiApplication.getUiApplication().pushScreen(splashScreen);
_getDoc = new ServerConnectivity(this, new ServerConnectivityListener() {
public void onCompleted(ServerConnectivity sender) {
// display next screen
//
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
splashScreen.close();
UiApplication.getUiApplication().pushScreen(new NextScreen());
}
});
}
public void onError(ServerConnectivity sender) {
splashScreen.close();
// display error message, retry, etc...
}
});
For this to work, you need an interface with the following definition:
public interface ServerConnectivityListener {
void onCompleted(ServerConnectivity sender);
void onError(ServerConnectivity sender);
}
So, your ServerConnectivity class maintains a reference to some object that implements the interface called ServerConnectivityListener This allows you to maintain loose coupling between the subject class and any observers that need to listen for events.
Within ServerConnectivity, you would make calls to the listener's methods something like this:
// begin excerpt from above...
//
if(_topics == null || _notifications == null) {
_listener.onError(this);
} else {
_listener.onCompleted(this);
}
catch ( Exception e ){
System.out.println( e.toString() );
_listener.onError(this);
//
// end excerpt from above...
Here is code for splash screen in java........after and call that view.........
http://www.randelshofer.ch/oop/javasplash/javasplash.html
import java.awt.*;
import java.awt.event.*;
public class SplashTest extends Frame implements ActionListener {
static void renderSplashFrame(Graphics2D g, int frame) {
final String[] comps = {"foo", "bar", "baz"};
g.setComposite(AlphaComposite.Clear);
g.fillRect(130,250,280,40);
g.setPaintMode();
g.setColor(Color.BLACK);
g.drawString("Loading "+comps[(frame/5)%3]+"...", 130, 260);
g.fillRect(130,270,(frame*10)%280,20);
}
public SplashTest() {
super("SplashScreen demo");
setSize(500, 300);
setLayout(new BorderLayout());
Menu m1 = new Menu("File");
MenuItem mi1 = new MenuItem("Exit");
m1.add(mi1);
mi1.addActionListener(this);
MenuBar mb = new MenuBar();
setMenuBar(mb);
mb.add(m1);
final SplashScreen splash = SplashScreen.getSplashScreen();
if (splash == null) {
System.out.println("SplashScreen.getSplashScreen() returned null");
return;
}
Graphics2D g = (Graphics2D)splash.createGraphics();
if (g == null) {
System.out.println("g is null");
return;
}
for(int i=0; i<100; i++) {
renderSplashFrame(g, i);
splash.update();
try {
Thread.sleep(200);
}
catch(InterruptedException e) {
}
}
splash.close();
setVisible(true);
toFront();
}
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
public static void main (String args[]) {
SplashTest test = new SplashTest();
}
}
Since,it is a thread based one,We cannot do it the normal way.So Check the following link
http://supportforums.blackberry.com/t5/Java-Development/What-is-the-Event-Thread/ta-p/446865
and Check whether parsing is done,Until that have the same screen,Check the condition of whehter it is downloaded or not ,and then push the screen
I created app which user can start from menu and from icon. I do not use GlobalEventListener in my app, just register ApplicationMenuitem. And now I am getting error: previous instance still active when launch my app.
Steps to reproduce not so trivial:
launch app from icon
do not close it, just switch to another app
launch app from icon again
I founded article in blackberry's forum about it , but I can't find solution where I should remove my ApplicationMenuItem: it added on phone boot and should show all the time.
My code:
public class Jingu extends UiApplication {
public static void main(String[] args) {
ApplicationManager app = ApplicationManager.getApplicationManager();
boolean keepGoing = true;
while (keepGoing) {
if (app.inStartup()) {
try {
Thread.sleep(1000);
} catch (Exception e) {}
} else {
keepGoing = false;
}
}
Jingu theApp = new Jingu();
theApp.initMenuItem();
theApp.showMainScreen();
theApp.enterEventDispatcher();
}
public Jingu() {
}
public void showMainScreen() {
showScreen(new JinguMainScreen(this));
}
public void initMenuItem() {
// Create menu item
Object o = RuntimeStore.getRuntimeStore().get(JinguMenuItem.MY_MENU_ID);
// register only if not done already.
if (o == null) {
new JinguMenuItem(this).registerInstance();
}
}
public void showScreen(Screen aScreen) {
synchronized (Application.getEventLock()) {
try {
UiApplication.getUiApplication().popScreen(aScreen);
} catch (Exception e) {
}
UiApplication.getUiApplication().pushScreen(aScreen);
}
}
}
public class JinguMenuItem extends ApplicationMenuItem {
public static final long MY_MENU_ID = 0xb9739d5240d5943dL;
private final Jingu jingu;
public JinguMenuItem(Jingu jingu) {
super(0x350100);
this.jingu = jingu;
}
public void registerInstance() {
Object menuItem = RuntimeStore.getRuntimeStore().remove(MY_MENU_ID);
if (menuItem == null) {
ApplicationMenuItemRepository amir = ApplicationMenuItemRepository.getInstance();
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_SYSTEM, this);
RuntimeStore.getRuntimeStore().put(MY_MENU_ID, this);
}
}
public Object run(Object context) {
jingu.setDefaultFont(Font.getDefault());
jingu.setMainApp(false);
jingu.setBbmEditField(null);
jingu.showMainScreen();
return context;
}
public String toString() {
return "My Menu";
}
}
plz advice where I should delete ApplicationMenuItem in my app?
my regards,
Vadim
If you are registering an ApplicationMenuItem from your application, as a user I would consider it bad style for your application to remove and exit, even if RIM provided a way to do this. You may want to separate your application into two parts. One provides the minimal support for responding to the ApplicationMenuItem selection, that starts automatically and runs in the background. The other has all the rest and can run and exit as needed.
My solution for this situation is:
create alternative entry point and run it on app load
register menu in it
do not use runtimeStore