I have to be able to load and draw X amount of images located on a network based drive.
I need help finding a way to load the images asynchronously.
java.net.URL Loc = new URL("http://auroragm.sourceforge.net/GameCover/GameCases/Mass-Effect.png");
JLabel lbl = new JLabel();
lbl.setIcon((anotherIcon = new ImageIcon(Loc)));
The above is one image which loads on the GUI thread and thus would freeze if 20 more were to be loaded. Any help would be appreciated
Load the images in separate thread. Please treat below code as pseudo-code:
final java.net.URL Loc = new URL("http://.../Mass-Effect.png");
Thread t = new Thread(new Runnable() {
public void run() {
Object content = Loc.getContent();
// content would be probably some Image class or byte[]
// or:
// InputStream in = Loc.openStream();
// read image from in
}
);
Short answer: you should load the images on another thread.
Swing does provide a nice set of classes & patterns for this:
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
Related
I'm making a java game using Eclipse. When I export to a runnable jar and try to run the game on different computer the images aren't visible. After checking the web and stack overflow for similar problems I think it has something to do with my using ImageIcon instead of ImageIO. However, I'm not sure how to change my code so that I'm uploading the images with ImageIO instead of ImageIcon.
Here is the method that uses ImageIcon to load the images
void loadImage() {
ImageIcon earth_image_icon = new ImageIcon("earth2.png");
earth = earth_image_icon.getImage();
ImageIcon sun_image_icon = new ImageIcon("sun2.png");
sun = sun_image_icon.getImage();
ImageIcon asteroid_image_icon = new ImageIcon("asteroid.png");
asteroid = asteroid_image_icon.getImage();
ImageIcon bg_image_icon = new ImageIcon("bg_pr.png");
background = bg_image_icon.getImage();
ImageIcon shipA_image_icon = new ImageIcon("ship_alpha.png");
ship_on_asteroid = shipA_image_icon.getImage();
ImageIcon ship_image_icon = new ImageIcon("ship_beta.png");
ship_no_thrust = ship_image_icon.getImage();
ImageIcon shipL_image_icon = new ImageIcon("ship_betaL.png");
ship_left_thrust = shipL_image_icon.getImage();
ImageIcon shipR_image_icon = new ImageIcon("ship_betaR.png");
ship_right_thrust = shipR_image_icon.getImage();
ImageIcon shipU_image_icon = new ImageIcon("ship_betaU.png");
ship_up_thrust = shipU_image_icon.getImage();
ImageIcon shipD_image_icon = new ImageIcon("ship_betaD.png");
ship_down_thrust = shipD_image_icon.getImage();
ImageIcon leftarrow_image_icon = new ImageIcon("leftarrow.png");
leftarrow = leftarrow_image_icon.getImage();
ImageIcon rightarrow_image_icon = new ImageIcon("rightarrow.png");
rightarrow = rightarrow_image_icon.getImage();
ImageIcon downarrow_image_icon = new ImageIcon("downarrow.png");
downarrow = downarrow_image_icon.getImage();
ImageIcon uparrow_image_icon = new ImageIcon("uparrow.png");
uparrow = uparrow_image_icon.getImage();
}
And here is one of the methods that draws the image onto the JPanel as an example
void drawEarth(Graphics g) {
g.drawImage(earth, earth_x_coordinate, earth_y_coordinate, this);
Toolkit.getDefaultToolkit().sync();
}
How do I convert to using ImageIO? I've checked out the Oracle documentation but I'm getting lost trying to sort it out and I'm very new to programming and java at that.
Update It's been suggested that this might be the solution my particular problem but I tried the answers given on this post and they didn't work for my case.
You will need to include the image resources in your compiled jar. An easy way of doing this if you are using an IDE like eclipse is to create a res or img folder and put your files in there. (Use the methods given here.)
In that case, you probably won't need to use ImageIO. However, if you still want to use ImageIO (which is recommended because of its wider support for formats and better exception handling, as mentioned in the comments), you can do the following:
Icon foo = new ImageIcon(ImageIO.read(getClass().getResource("foo.png")))
I created a new project in eclipse and copied the class files into the new projects src folder. I then made a resource folder, added it to the build path, created an images package in that resource folder and copied the images into that images package. For some reason this all worked. Thanks everyone for your help
I want to make some kind of a book(or some kind of a photo gallery) using jpg files of a scanned book.
the user gives the number of the page that he wants to go to , and clicks on the button to
see the page .
I need to know what is the best way to load the pictures.
i'm thinking of doing this for each page:
private ImageIcon image1= new ImageIcon ("1.jpg");
private ImageIcon image2 = new ImageIcon ("2.jpg");
....
and then put the pictures in an array and so on ...
but i got over 500 pictures and it is tedious to load pages like that .
so is there any other way?
Well, I can say the best way would be lazy loading plus pre-caching.
Lazy loading means you load the image only when the user needs it. For example:
img = 56; // suppose the user want to see page 56
if(images[img] != null) { // images is an array with the images
images[img] = new ImageIcon (img + ".jpg");
}
Besides, you can guest that when the user see a page they will see the next ones (pre-caching). So you can also load the following X pages.
PRELOAD = 10; // number of pages to preload
img = 56;
for(int i = 0; i < PRELOAD; i++) {
if(images[img+i] != null) {
images[img+i] = new ImageIcon ((img + i) + ".jpg");
}
}
Besides, it's you may think that in the beginning the user will always look at the firsts pages. So you can pre-load the first X pages in the start of your program.
i have an application that loads an image to create a button with an icon in it. When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Location of images :
+Project
-Source Packages
-Tools
-start.jpg
The code used :
static final String STARTIMAGE = "/Tools/start.JPG";
public static JButton createStartButton() {
Image img = Toolkit.getDefaultToolkit().getImage(GUITools.class.getResource(STARTIMAGE));
JButton b = new JButton("",new ImageIcon(img));
b.setPreferredSize(smallButton);
b.setMaximumSize(smallButton);
b.setMinimumSize(smallButton);
return b;
Now, the weirdest thing is that in another screen, a button is created in the exact same way, and this one works just fine...
Code:
static final String PREVIOUSIMAGE = "/Tools/previous.gif";
public JButton createPreviousButton(){
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
JButton b = new JButton("Previous",new ImageIcon(img));
b.setPreferredSize(dimensionButton);
b.setMaximumSize(dimensionButton);
b.setMinimumSize(dimensionButton);
return b;
}
The only difference is that one is static, but even if make it non-static like the other one, it still won't work.
I tried everything I found on this forum and other sites, including this good topic :
How to bundle images in jar file
(The generated url at the end of the topic is just 'null')
Nothing seems to work... Please help!
Thanks!
When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
This approach above is incorrect, use this instead:
private static BufferedImage readBufferedImage (String imagePath) {
try {
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream(imagePath);
BufferedImage bimage = ImageIO.read(is);
is.close();
return bimage;
} catch (Exception e) {
return null;
}
}
And better load all images at application startup and then use them.
It seems to me that your images are inside a package so the actual link might be "package.name/Tools/start.jpg" or something else when its compiled so the image should be moved.
Instead of having it inside of a package like:
+Project
-Source Packages
-Tools
-start.jpg
Do something like this instead.
+Project Folder
-Source Packages/
-Tools/
-start.jpg
I am using Java function to download file from internet.
public void getLatestRelease()
{
try
{
// Function called
long startTime = System.currentTimeMillis();
// Open connection
System.out.println("Connecting...");
URL url = new URL(latestReleaseUrl);
url.openConnection();
// Download routine
InputStream reader = url.openStream();
FileOutputStream writer = new FileOutputStream("release.zip");
byte[] buffer = new byte[153600];
int totalBytesRead = 0;
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
totalBytesRead += bytesRead;
}
// Download finished
long endTime = System.currentTimeMillis();
// Output download information
System.out.println("Done.");
System.out.println((new Integer(totalBytesRead).toString()) + " bytes read.");
System.out.println("It took " + (new Long(endTime - startTime).toString()) + " milliseconds.");
// Close input and output streams
writer.close();
reader.close();
}
// Here I catch MalformedURLException and IOException :)
}
And I have JProgressBar component in my JPanel, which is supposed to visualize download progress:
private static void createProgressBar(JPanel panel)
{
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
panel.add(progressBar, BorderLayout.SOUTH);
}
I'd like to separate "back-end" functions from "front-end" views, presented to users, by analogy with MVC in web applications.
So, function getLatestRelease() lies in the package framework in class MyFramework.
Everything, connected with Swing interface generation, including event listeners, is in the package frontend.
In the main Controller class I create an instance of MyFramework and an instance of ApplicationFrontend, which is the main class of frontend package.
The questions is how to update progressBar value, depending on download progress?
when you want to do MVC in swing, the SwingWorker class comes to mind.
SwingWorker comes with a property called "progress", that you can listen to using a PropertyChangeListener.
Progress events can be fired from the swingworker using its setProgress(int 0-100) method. So here it is for loading the file in the background with a notion of progress (note that you will need to have an idea of the size of the file to be able to compute a progress percentage).
Showing the progress can be done using two options : a JProgressBar for complete control, or a ProgressMonitor to show an almost self-managed popup with a progress bar in it. See the tutorial to see the differences.
Solution 1
As they say, if you go for a ProgressMonitor and your background task is reading from an InputStream, you can use the ProgressMonitorInputStream class to do the reading and displaying progress without bothering with calling setProgress or listening to the "progress" property.
Solution 2
If you want to do it manually, create your SwingWorker loading task that calls setProgress as it goes, instanciate a ProgressMonitor (or a JProgressBar) as needed, register a PropertyChangeListener on your SwingWorker that checks for "progress" changes and updates the monitor/bar accordingly.
Note: It is important to go through a PropertyChangeListener because it decouples the model (the task) from the view (the swing progress component) and abide by the EDT usage rules.
I want to capture complete browser, I am using below code to take screenshot....
function takeSnapShot($filename)
{
try
{
var robot = new java.awt.Robot();
var toolkit = new java.awt.Toolkit.getDefaultToolkit();
var screenSize = toolkit.getScreenSize();
var screenRect = new java.awt.Rectangle(0, 0, screenSize.width, screenSize.height);
var image = robot.createScreenCapture(screenRect);
var file = new java.io.File("D:/"+$filename+".png");
javax.imageio.ImageIO.write(image, "png", file);
}
catch (e)
{
Packages.java.lang.System.out.println(e);
}
}
But it is capturing only visible part of the browser....so is there any way to capture complete browser screen?
Thanks in advance!!!
If you wanna do that in pure java, you gonna have to take multiple screenshots and merge them. Not a simple job. I dont know any library that can help you.
The simplest way to solve your problem is by using a screenshot application and just call it from you java application. Take a look at CutyCapt http://cutycapt.sourceforge.net/