Add image URL to bitmap image in listfield - java

I have 50/100 image url with specific text, i add them in vector, add listfield with callback,
I am downloading the image every time with a function call UrlToImage I am facing problem, the list is too slow , download icon showing on the top right side of simulator.
UrlToImage img = new UrlToImage(imageUrl);
bit = img.getbitmap();
pic = new BitmapField(bit);
g.drawBitmap(xpos, y+10, bit.getWidth(), bit.getHeight(), bit, DrawStyle.LEFT,0);
Can't scroll smoothly throughout the list.
Any idea, comments.

Your formatting is all messed up, but if I understand you correctly, you're downloading upon every callback?
One way to avoid that is create a thread that kicks off when the screen is needed, and asynchronously do the downloads (once each!) and stick the images in a cache. Then the drawListRow callback just pulls from the cache.

It appears as though your code is executing inside the paint method. This all occurs on the UI thread (meaning that you block the UI, make a request, wait for a response, set the image, and then draw the image, every time a paint occurs). Seeing as a request can take about 3 seconds, your UI will freeze for that long.
What you should be doing it fetching your image in the constructor of your class, set an instance variable of your class, and then g.drawBitmap with that instance variable.
In short, the only code in your paint method should be the g.drawBitmap, in order to prevent the choppy scrolling.

Related

How can I save an image, change the contrast/brightness, display the change then restore the original image, displaying those all in the same window?

The idea of my program is similar to the adjust brightness/contrast built-in plugin. I want to have the image in one window where you can see it with varying b/c values.
The original image should be saved before I make any changes to it so that I can go back to the original and make more changes to that instead of the new image created after using the setDisplayRange(), which revert the b/c settings back to how they were in the original. This should all happen in the same window. I don't want to create a new window each time to display the changes I make.
ImagePlus imp = WindowManager.getCurrentImage();
ImageProcessor ip = imp.getProcessor();
ip.snapshot();
imp.setDisplayRange(10, 30);
Thread.sleep(1000);
ip.reset();
Reading the API, I believe this should work and do what I want but it only changes the b/c without going back to what the original image was. I looked at the b/c code and this is seems to be what they did there too so I'm not sure what's really wrong here unless I am making a stupid mistake, misunderstanding what the snapshot and reset methods do?
Any help would be appreciated, thank you in advance.

Ensure that AWT Canvas is drawn on-screen before doing something else

In my application I NEED to make sure that Canvas is actually appeared on the screen before going for the next step. The reason is that I need to retrieve an AWT Drawable - i.e. the native window surface of that canvas. And that drawable would be invalid if the canvas is not visible, even if it has the flag "visible" set to true.
The problem Im having is that I can't be sure when Java actually decides to display it.
I even made a code to actually delay after Canvas constructor, but what happens is that it is displayed AFTER the delay has expired.
canvas3d = new Canvas3d();
System.err.println("Before sleep");
try
{
Thread.sleep(3000);
}
catch (Exception e) {}
System.err.println("After sleep");
canvas3d.Init();
This is odd, because the drawing and rendering of elements should be handled by a completely separate thread, and my main thread sleeping should theoretically give it enough time to process the stuff. But it still waits for some reason.
Adding Repaint() or revalidate() doesn't help.
The problem with this is that sometimes, the canvas gets displayed before the Init() gets to the point that it needs it to be visible. But other times - it doesn't get displayed before that.
Can I somehow FORCE the application to display the element before I'm doing anything else? Or can I somehow retrieve if the canvas is displayed at the moment or not? Because checking Canvas.visible is pointless - whether it's true or false, it doesn't mean that it's actually displayed or hidden in that precise moment during runtime. It's just a flag showing that it's supposed to be displayed, but oh, oopsie, Java just can't guarantee that it actually is!
It seems that I can use canvas.isShowing() to test if it's actually visible on the screen. At least by checking that parameter I got the result I wanted (so far).
I am still not certain if that's enough and if there's something more that can go wrong on the low level, particularly if I try to access the surface during X11 rendering pipeline where AWT has already completely "displayed" the component but X11 hasn't yet finished drawing it on the screen.
That's one concern.
But for now, it seems to be the best answer I can come up with.

How to notify an EditText that spans have changed without re-reading the entire string

I'm writing an Android app that syntax highlights code. Currently, the app works by taking a string, turning it into a new SpannableStringBuilder, then coloring it via setSpan(new ForegroundColorSpan(...)) based on the file extension. When all that is done, EditText.setText is called with the builder. The problem with this approach is with large files, all of the setSpan calls take a pretty long time, and the UI freezes for 10s of seconds before setText() is called and the text is displayed.
I want to overhaul the approach here. I would like to call setText() on the entire string first, so the text is displayed immediately (but is uncolored). Then I want to color the text in batches of 500 lines, flushing to the display after each batch. The user probably won't notice any difference (aside from the perf) because I can process + flush 500 lines much faster than the user can scroll down 500 lines.
I'm not sure how to implement my idea efficiently, however. The only way to 'flush' the changes by updating the display is to call setText() on the SpannableStringBuilder again after appending more spans to it. setText(), in turn, re-reads through the entire string and all its spans, when it only needs to look at the new spans. Is it possible to tell the EditText to only redraw the new spans? Thanks.
I was being dumb. I made this test app (using Xamarin / C#) before asking this question:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var editText = FindViewById<EditText>(Resource.Id.EditText);
var ssb = new SpannableStringBuilder(new string('E', 250));
editText.SetText(ssb, TextView.BufferType.Editable);
ssb.SetSpan(new ForegroundColorSpan(Color.Blue), 0, ssb.Length(), SpanTypes.InclusiveExclusive);
}
When you run the app all of the text is white. I thought this was because the EditText disregards any changes you made after SetText, and you need to call SetText again for the changes to take effect. However, I remembered that EditText by default copies your Editable when you call SetText, so you have to add this beforehand:
editText.SetEditableFactory(new NoCopyEditableFactory());
private class NoCopyEditableFactory : EditableFactory // Editable.Factory in Java
{
public override IEditable NewEditable(ICharSequence source) => (IEditable)source;
}
Now all of the text is blue even though I called SetSpan after SetText.

How do I solve problems in my screenshot-taking application?

I wrote a GUI-based Java program that takes 25 screenshots per second and saves them at a user-defined location.
It works pretty well except that it has two problems:
The mouse cursor is missing from the images and I know it will be because BufferedImages do not contain cursor information in them. They have to be added programatically.
The thread that takes screenshots is a daemon thread. So if I close the application, the thread is killed and the PNG image that was being written gets corrupted. I want to avoid that.
Here are the images of my application:
The award-winning, intuitive GUI:
The high-definition images captured look like this:
As you can see from the image the cursor information is being displayed in the console using MouseInfo's static methods.
Please let me know how to solve the above mentioned two problems.
After solving the problem, the images now look like this:
The mouse cursor is missing from the images and I know it will be
because BufferedImages do not contain cursor information in them. They
have to be added programatically.
That is correct, you have to add the cursor afterwards. The reason for this is that a screenshot taken with the Robot class never contains the cursor. Not really because "the BufferedImage doesn't contain mouse info". A BufferedImage is a class that contains a raster of pixels.
The thread that takes screenshots is a daemon thread. So if I close
the application, the thread is killed and the PNG image that was being
written gets corrupted. I want to avoid that.
Simply, in the screenshot thread, use a flag that indicates wether it should continue or not. Keep taking screenshots as long as that boolean is set to true. Make sure to make it non-deamon. So, when you close the application, set the flag to false.
Probably the most easy way to do this is to add a WindowListener:
yourFrame.addWindowListener(new WindowAdapter()
{
public void windowClosed(WindowEvent e)
{
screenshotThread.stopTakingScreenshots(); // This methods set the flag
}
}
Also notice that you are not taking the time it takes to make and save a screenshot in count. You use a fixed sleep of 40 milliseconds, but let's say that it takes 4 milliseconds to take and save the screenshot, then you should sleep for only 36 milliseconds. To time how long it takes to make the screenshot, use System.currentTimeMillis(); before and after your takeShot() method and make the difference.

Image.setIcon(Parameters) Is not refreshing the Label

I'm working with Java Swing in the making of an Online Chess(Client-Server), I have been able to make the chessTable form wonderfully with no trouble, but in the lobby I'm showing the user's Avatar, the problem is that, the user is able to change his avatar through the server, but when ever I call the setIcon of the new image, it wont refresh it.
Explanation:
The users start with a default image(Avatar.jpg) downloadead from the server,if he changes it, the server sends to the client the new image he chose with the same name of the previous one, so it gets replaced. But when ever i call setIcon of this new image(after the download), it wont do anything and the Label stick to show the first image he ever set. I'm checking the folder and the image are being sent form the server to the client with out problems, and the only way for me to make the client refresh the Avatar is by closing and opening the app. Any ideas?, I tried reprint every random thing I could find still no solution, and the labels refresh by a clickedListener.
I use this line to set the image:
this.JLProfilePic.setIcon(new javax.swing.ImageIcon(getClass().getResource("/View/Images/avatar.jpg")));
Edit1: I'm not working with a JApplet, still I don't have any idea of where the problem might be originated, since Im able to change the Label Icon to any image but when ever I try to change the Icon to Avatar, it still shows the previous one even if in the folder you can see that Avatar.jpg is not the same, it changed for a new one.
Edit2: Well I still haven't found any solutions for this, I supose might be true or not, since i setIcon once, the image is saved at the cache when ever the program re access to the same image it goes to the cache instead of checking again the source of the file. Not sure but is the only Logic I can make.
Try this,
Image img = ImageIO.read(new URL("http:\Server_IP:Port\image.jpg"));
setIconImage(img);

Categories