I try to use the ClientBundle implementation to manage my Images to a large File and minimize the HTTP-Requests.
I put in my gwt.xml
Generate the ClientBundle
public interface ResourceBundle extends ClientBundle {
public static final ResourceBundle INSTANCE = GWT.create(ResourceBundle.class);
#Source("tiles/smiley.png")
ImageResource smiley();
}
The Image would be found, no errors.
Here is the code
#Override
public void onModuleLoad() {
CLogger.log("Start Engine");
int width = 800;
int height = 600;
Canvas canvas = Canvas.createIfSupported();
canvas.setWidth(width + "px");
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setCoordinateSpaceHeight(height);
Context2d c = canvas.getContext2d();
Image img = new Image(ResourceBundle.INSTANCE.smiley());
img.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
CLogger.log(event.getSource() + " loaded");
}
});
CLogger.log("Visible: " + img.isVisible());
c.drawImage((ImageElement) new Image(ResourceBundle.INSTANCE.smiley()).getElement().cast(), 0, 0);
RootPanel.get().add(canvas);
}
I create a simple Canvas and set the size to 800x600. I create a new Context2D Object to draw the Image at the Context and add the Canvas to the RootPanel.
The logs shows:
[20:10:21.676] - Start Engine
[20:10:21.851] - Visible: true
[20:10:21.853] - http://127.0.0.1:8888/engine/7D39451825E9952050F44A6B8E2E15F3.cache.png
The Image exists under the logged URL so everything looks fine. But the Image would not be draw or it would draw but not display.
Anybody an idea?
I thought the ClientBundle loads the Images as the start in the backend. So if I get an Instance every Image/Css and others fill be loaded?
Regars Markus
Image contents aren't guaranteed to be loaded synchronously. Depending on the capabilities of the browser and the size of the image data, the resource may be stored as a standalone file, which appears to be the case that you're describing (i.e. cache.png). Does a formulation like this make any difference?
final Image img = new Image(ResourceBundle.INSTANCE.smiley());
img.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent e) {
c.drawImage((ImageElement) img.getElement());
}
}
RootPanel.get().add(img);
If you use CSSResources and ImageBundles outside of UiBinder you have to make sure that the stlyesheet and images are injected properly.
See here for more information.
Related
I have one default image and I want to replace the image when the user or the program already selected an image. I have only the basic image reader for displaying the default image.
private static void loadImage()throws Exception{
File image2 = new File("...Example\\blackimage.jpg");
bi = ImageIO.read(image2);
}
You could override methods so
private static void loadImage(String imagePath) throws Exception {
File image2 = new File(imagePath);
bi = ImageIO.read(image2);
}
private static void loadImage() throws Exception {
loadImage("...Example\\blackimage.jpg");
}
This would give you two methods, one to call if you have a image in mind and one for the default image.
If your program already has one selected for a particular user, for example stored in some sort of local storage / database, it can call the first method, however if an image is not found it can call the default no parameter method.
I have a program which when runs displays an icon in system tray. i am using the below code to display an icon in system tray area:
public static void showTrayIcon() {
if (java.awt.SystemTray.isSupported()) {
st = java.awt.SystemTray.getSystemTray();
image = Toolkit.getDefaultToolkit().getImage(PongeeUtil.class.getClass().getResource("export.png"));
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Hello");
}
};
PopupMenu popup = new PopupMenu();
MenuItem defaultItem = new MenuItem("sdf");
defaultItem.addActionListener(listener);
popup.add(defaultItem);
trayIcon = new TrayIcon(image, "Tray Demo", popup);
trayIcon.addActionListener(listener);
try {
st.add(trayIcon);
} catch (AWTException e) {
System.err.println(e);
}
}
}
When i call this method in my main() i got something in my system tray but icon is missing. i think image is not able to load. image is in the same package where my java files resides.
What am i doing wrong here ?
image is in the same package where my java files are
If you take a look at the JavaDocs for Toolkit#getImage you will find that it says...
Returns an image which gets pixel data from the specified file
This is important. You should also know that getImage loads the physical image in a background thread, which means if it fails to load the image, it will do so silently...
Okay. The core problem is, once the image is placed within the context of the application (with the class files), it becomes, whats commonly known as, an embedded resource.
These resources can not be loaded via any means that requires access to a file on the file system.
Instead, you need to use Class#getResource or Class#getResourceAsStream to load them, for example
image = Toolkit.getDefaultToolkit().getImage(YourClass.class.getResource("/package/path/to/classes/export.png"));
Or more preferabbly...
BufferedImage img = ImageIO.read(YourClass.class.getResource("/package/path/to/classes/export.png"));
image = new ImageIcon(img);
ImageIO will throw an IOException when it can't load the image for some reason, which gives you more diagnostic information to fix problems
nb:
YourClass is you class which contains the showTrayIcon method...
/package/path/to/classes is the package name under which the image is stored...
i use a bufferedImage to load textures inside my resource folder like this:
i use ImageLoader class to load images
...
public static final BufferedImage images = loadImages("/images/images.jpg");
private static BufferedImage loadImages(String string) {
BufferedImage image = null;
try {
image = ImageIO.read(ImageLoader.class.getResourceAsStream(string));
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
but when i add this to one of my objects like:
...
graphic.drawImage(ImageLoader.images.getScaledInstance(200,200.java.awt.Image.SCALE_SMOOTH), (int) objects.get(i).getX() - objects.get(i).getWidth() / 2, (int) objects.get(i).getY()
- objects.get(i).getHeight() / 2, objects.get(i).getWidth(),objects.get(i).getHeight(), null);
it slows down a lot my app , there is a way more efficent to load images, and more imporant,
is there a way to prevent slowdown of the application?
Make a list of the scaled images as field. And of course it would be nicer to use a variable:
// Field
List<Image> images = new ArrayList<>();
// Once, maybe in the constructor
... object = objects.get(i);
images.add(...);
Then in the painting method only
graphic.drawImage(images.get(i), ...);
I am looking at a code sample that explains the proxy pattern. Here is the code:
/**
* Proxy
*/
public class ImageProxy implements Image {
/**
* Private Proxy data
*/
private String imageFilePath;
/**
* Reference to RealSubject
*/
private Image proxifiedImage;
public ImageProxy(String imageFilePath) {
this.imageFilePath= imageFilePath;
}
#Override
public void showImage() {
// create the Image Object only when the image is required to be shown
proxifiedImage = new HighResolutionImage(imageFilePath);
// now call showImage on realSubject
proxifiedImage.showImage();
}
}
/**
* RealSubject
*/
public class HighResolutionImage implements Image {
public HighResolutionImage(String imageFilePath) {
loadImage(imageFilePath);
}
private void loadImage(String imageFilePath) {
// load Image from disk into memory
// this is heavy and costly operation
}
#Override
public void showImage() {
// Actual Image rendering logic
}
}
/**
* Image Viewer program
*/
public class ImageViewer {
public static void main(String[] args) {
// assuming that the user selects a folder that has 3 images
//create the 3 images
Image highResolutionImage1 = new ImageProxy("sample/veryHighResPhoto1.jpeg");
Image highResolutionImage2 = new ImageProxy("sample/veryHighResPhoto2.jpeg");
Image highResolutionImage3 = new ImageProxy("sample/veryHighResPhoto3.jpeg");
// assume that the user clicks on Image one item in a list
// this would cause the program to call showImage() for that image only
// note that in this case only image one was loaded into memory
highResolutionImage1.showImage();
// consider using the high resolution image object directly
Image highResolutionImageNoProxy1 = new HighResolutionImage("sample/veryHighResPhoto1.jpeg");
Image highResolutionImageNoProxy2 = new HighResolutionImage("sample/veryHighResPhoto2.jpeg");
Image highResolutionImageBoProxy3 = new HighResolutionImage("sample/veryHighResPhoto3.jpeg");
// assume that the user selects image two item from images list
highResolutionImageNoProxy2.showImage();
// note that in this case all images have been loaded into memory
// and not all have been actually displayed
// this is a waste of memory resources
}
}
Assume proxy pattern is implemented correctly, and this is the main method of the program. Here is what i wonder: The comments in the code say that when we use proxy image objects, if we load a picture into memory, just that image is loaded. But if we do not use proxy and directly create real images, when we load an instance of this class, we load all instances of the class into memory. I do not understand why this is the case. Yes, the whole point of proxy pattern is to do this, but i do not understand why all 3 of the highResolutionImageNoProxy objects are loaded into memory when we call highResolutionImageNoProxy2.showImage(); . Can anyonbody explain it?
Thanks
Edit: I think i figured out why. Because the ImageProxy class calls the constructor of HighResolutionImage class only when it tries to do an operation on the object, but if we create a HighResolutionImage directly, then since its constructor creates the object, all of them are loaded into memory.
The code assumes that when you create an instance of HighResolutionImage, the image is loaded to the memory, even if showImage() isn't called.
The proxy will assure that the image is loaded to the memory only when showImage() is called.
//load veryHighResPhoto1 to memory
Image highResolutionImageNoProxy1 = new HighResolutionImage("sample/veryHighResPhoto1.jpeg");
//load veryHighResPhoto2 to memory
Image highResolutionImageNoProxy2 = new HighResolutionImage("sample/veryHighResPhoto2.jpeg");
//load veryHighResPhoto3 to memory
Image highResolutionImageBoProxy3 = new HighResolutionImage("sample/veryHighResPhoto3.jpeg");
//load just the proxys (image not loaded yet)
Image highResolutionImage1 = new ImageProxy("sample/veryHighResPhoto1.jpeg");
Image highResolutionImage2 = new ImageProxy("sample/veryHighResPhoto2.jpeg");
Image highResolutionImage3 = new ImageProxy("sample/veryHighResPhoto3.jpeg");
//trigger the load of the image into memory
highResolutionImage1.showImage();
I am using Flyingsaucer to generate PDF. I am trying to embed image in the pdf by implementing ReplacedElementFactory. I can generate pdf replaced with the image. No problem.
But what I wanted was to set the image height and width dynamically from within the class. I need to scale the image to a definite size. I will find the new scaled height and width of the image and want these scales to be set for the image embedded.
Can I add the style attribute in the Element fetched from BlockBox and update this element? Will this work? I tried using blackBox.setElement, but it does not work.
Could anyone help?
EDIT:
Peter Brant from flying saucer google group suggested the following
Override getIntrinsicHeight / getIntrinsicWidth in your ReplacedElement implementation. Note those values will be in render "dots" not pixels so you may have to scale appropriately.
But unfortunately it did not work for me. I overrode ReplaceElement of flying saucer and returned height and width. It did not work for me. The sample code I tried was here
public class MyITextImageElement implements ITextReplacedElement
{
private final FSImage fsImage;
private float[] scaledWidthAndHeight = null;
public MyITextImageElement(FSImage image)
{
fsImage = image;
try
{
ITextFSImage itextFSImage = (ITextFSImage) image;
Image itextImage = itextFSImage.getImage();
byte[] imageByteArr = itextImage.getOriginalData();
//Getting scaled image height and width
scaledWidthAndHeight = getScaledWidthAndHeight(imageByteArr);
}
catch (Exception e)
{
//Exception Handling
}
}
#Override
public int getIntrinsicWidth()
{
if (scaledWidthAndHeight != null)
{
return Math.round(scaledWidthAndHeight[0]);
}
return fsImage.getWidth();
}
#Override
public int getIntrinsicHeight()
{
if (scaledWidthAndHeight != null)
{
return Math.round(scaledWidthAndHeight[1]);
}
return fsImage.getHeight();
}
...........
...........
}