How to test if BufferedImage using ImageIO picks up a 'null' - java

I am trying to set my program (java using netbeans) to do one thing if it finds the image its looking for, and another thing if it doesn't...
this is what I have got so far however it never completes the else statement. I believe this is because "image" is not technically null, as it still has corresponds to the filename entered, however I am not sure how to set java to do something based on if the filename is not found within the directory.
public void displayImage(String strfilename, JLabel JLlabel) {
try {
JLabel label = JLlabel;
String FileName = strfilename;
BufferedImage image = ImageIO.read(new File(FileName + ".jpg"));
if(image!=null){
ImageIcon icon = new ImageIcon(image);
label.setIcon(icon);}
else{
BufferedImage image2 = ImageIO.read(new File("NOIMAGE.jpg"));
ImageIcon icon2 = new ImageIcon(image2);
label.setIcon(icon2);
}
} catch (IOException ioe) {
}
}
If anyone could help me with this I would be very grateful

You're swallowing the exception. You don't need an if{}else{} loop since you already have a try{}catch{}.
String FileName = file;
try {
BufferedImage image = ImageIO.read(new File(FileName + ".jpg"));
// Code for when the image is found
} catch (IOException ex) {
// Code for when the image is not found
}
EDIT:
As #haraldK pointed out, you can have a file that exists but is unreadable, in which case a NullPointerException will be thrown.
You can handle them both in the catch clause.
public void displayImage(String strfilename, JLabel label) {
try {
BufferedImage image = ImageIO.read(new File(strfilename + ".jpg"));
ImageIcon icon = new ImageIcon(image); // Can throw NullPointerException if the file is found but is unreadable
label.setIcon(icon);
} catch (IOException | NullPointerException ex) {
ImageIcon icon = new ImageIcon("NOIMAGE.jpg");
label.setIcon(icon);
}
// You're probably going to have to pack or validate your container here
}
One thing worth noting is that this does not check exceptions for the NOIMAGE, you might want to add that.
This is better than just calling File.exists() as it also handles files that exist but are unreadable (text file and whatnot).

you can check the file if exist before you process this method also i removed some unnecessary code.
public void displayImage(String strfilename, JLabel JLlabel) {
// declare only one reference you don't need two references
BufferedImage image=null;
if(!isImageExist(strfilename)){
// assign the NOIMAGE if image not found
image = ImageIO.read(new File("NOIMAGE.jpg"));
} else {
try {
// assign the image if found
image = ImageIO.read(new File(strfilename + ".jpg"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
ImageIcon icon = new ImageIcon(image);
//setting the image once instead of repeating the code in if and else blocks also you don't need to add another reference to JLlabel because you are already got it from a parameter
JLlabel.setIcon(icon);
}
private boolean isImageExist(String imageName) {
return new File(imageName.jpg).exist();
}

Related

Creating new Thread to update JLabel and setIcon() in said separate Thread

Trying to get an image from another application sending an array of bytes through socket, translating it to a BufferedImage and setting a JLabel in the GUI that updates every 3 seconds.
I tried looking it up on forums but questions regarding graphical update are recurrent to me and I never seem to get it right -- there's at least 6 update methods in java for graphical interface and every one I tried won't work.
I know the problem isn't in the connection to the client because I can easily save the image I receive with ImageIO.write() and it updates every 3 seconds to the image I was expecting to receive. I just can't have Java updating the JLabel correctly without having to go to forums and ask people. Such a complex task I guess. Here is the code: http://pastebin.com/95nMGLvZ. I am doing this project in Netbeans so there's a lot of stuff in there that is unnecessary to read as it does not directly relate to the problem.
I think the answer lies in creating a separate thread to update my JLabel from the ever-changing BufferedImage that is received from the ObjectInputStream. Anyone mind giving me a hand at this? What is better for my code? SwingWorker, Threading (wtf is setDaemon(flag)?), Runnable, Timer, invokeLater? Tried all of this. Not correctly apparently.
EDIT1:
Tried your answer immibis:
public void startRunning() {
try {
server = new ServerSocket(666, 10);
connection = server.accept();
networkStatus("Connected to " + connection.getInetAddress().getHostName());
Thread thr = new Thread(new Runnable() {
#Override
public void run() {
try {
input = new ObjectInputStream(connection.getInputStream());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.toString());
}
}
});
thr.start();
System.out.println(!connection.isInputShutdown());
while (connection.isConnected()) {
try {
byte[] byteImage = (byte[]) input.readObject();
InputStream in = new ByteArrayInputStream(byteImage);
final BufferedImage bi = ImageIO.read(in);
jLabel_screen.setIcon(new ImageIcon(bi));
ImageIO.write(bi, "jpg", new File("C:\\Users\\User\\Desktop\\test.jpg"));
System.out.println("i'm working");
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.toString());
} catch (ClassNotFoundException ex) {
Logger.getLogger(SpyxServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.toString());
}
}
It does not work. It says byte[] byteImage = (byte[]) input.readObject(); line has a NullPointerException. The only value that can be null is the return from readObject(), meaning either the input was not initialized correctly or the connection is not synchronized. I hope it's the first option because I wouldn't know how to handle the last.
EDIT2:
Tried your answer blazetopher:
public void startRunning() throws IOException {
server = new ServerSocket(666, 10);
try {
connection = server.accept();
networkStatus("Connected to " + connection.getInetAddress().getHostName());
input = new ObjectInputStream(connection.getInputStream());
while (true) {
try {
byte[] byteImage = (byte[]) input.readObject();
InputStream in = new ByteArrayInputStream(byteImage);
final BufferedImage bi = ImageIO.read(in);
SwingUtilities.invokeLater(new Runnable() {//<-----------
#Override
public void run() {
jLabel_screen.setIcon(new ImageIcon(bi));
}
});
ImageIO.write(bi, "jpg", new File("C:\\Users\\User\\Desktop\\test.jpg"));
System.out.println("i'm working");
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.toString());
} catch (ClassNotFoundException ex) {
Logger.getLogger(SpyxServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (EOFException eofException) {
networkStatus("Connection Closed. :(");
} finally {
input.close();
connection.close();
}
}
Using SwingUtilities.invokeLater didn't work either. At least the program runs and can even save the image but still can't update the JLabel. Am I running out of options here?
EDIT3:
Tried Jordan's code:
#Override
public void paint(Graphics g) {
g.drawImage(biGlobal, 0, 0, null);
}
The GUI kind of crashed and was "drawing" the components just when I had my mouse cursor hovering it. When I started the code, it did not crashed (+1) but it did not draw anything, even when I try to hover the cursor into where the BufferedImage should be painted. Maybe I should add revalidate() or repaint after calling the Overwritten paint(getGraphics()) inside the startRunning() method?
EDIT4: the while(true) that the code is actually in may be the problem but when I use a SwingTimer it gets out of sync with the client and crashes after first cycle. Any alternatives to this?
Generally speaking you have a producer/consumer pattern. Something is producing images and something wants to consume images. Normally, the consumer would wait on the producer to tell it something has been produced, but in this case, we can use a observer pattern instead, having the producer notify the consumer that something was been produced (instead of waiting for it)
We need someway for the producer to communicate with the consumer...
public interface PictureConsumer {
public void newPicture(BufferedImage img);
}
You would create an implementation of this in your UI code, this would then set the icon property of the JLabel
Now, we need something to produce the images...
public class PictureProducer extends SwingWorker<Object, BufferedImage> {
private PictureConsumer consumer;
public PictureProducer(PictureConsumer consumer) {
this.consumer = consumer;
}
#Override
protected void process(List<BufferedImage> chunks) {
// Really only interested in the last image
BufferedImage img = chunks.get(chunks.size() - 1);
consumer.newPicture(img);
}
#Override
protected Object doInBackground() throws Exception {
/*
This whole setup worries me. Why is this program acting as the
server? Why aren't we pooling the image producer?
*/
try (ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(666, 10)) {
try (Socket socket = server.accept()) {
try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
// Using `while (true)` is a bad idea, relying on the fact
// that an exception would be thrown when the connection is closed is
// a bad idea.
while (!socket.isClosed()) {
// Generally, I'd discourage using an ObjectInputStream, this
// is just me, but you could just as easily read directly from
// the ByteArrayInputStream...assuming the sender was sending
// the data as a byte stream ;)
byte[] bytes = (byte[]) ois.readObject();
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes)) {
BufferedImage img = ImageIO.read(bis);
publish(img);
}
}
}
}
}
return null;
}
#Override
protected void done() {
try {
get();
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "Image Producer has failed: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
See Worker Threads and SwingWorker for more details
You can a reverse example of this (where some server is producing images and a client is consuming them) here
To update your label, you want to ensure you're using the EDT thread, so use SwingUtilities.invokeLater from the code where you're receiving the BufferedImage (which would ideally be in a separate "worker" thread:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Update your label here
}
});
What is it you are attempting to accomplish.there might be a better way all together.
For example replace the JLabel with a JPanel then use that JPanel paint method
#Override
public void paint(Graphics g) {
g.drawImage(Img, xcord, ycord, null);
}
Then make that JPanel implement runnable and do your updates in that run method.
JPanel class
public class GraphicsPanel extends JPanel{
private BufferedImage img;
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D G2D = (Graphics2D) g;
G2D.drawImage(img, 0, 0, null);
}
public void setImg(BufferedImage img) {
this.img = img;
}
}
then make sure this panel is visible from wherever you wish to call its methods.
this will look something like this
GraphicsPanel graphicsPanel = new GraphicsPanel();
boolean running;
BufferedImage srcImage;
public void run(){
while(running){
graphicsPanel.setImg(srcImage);
graphicsPanel.repaint();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Java: show GIF image doesn't work

I'm trying to show a GIF image inside a JLabel using the following code
Image waitImage = null;
JLabel l1;
try {
waitImage = ImageIO.read(IndexesPanel.class.getResource("/images/error.gif"));
l1 = new JLabel(new ImageIcon(waitImage));
l1.setBounds(20, 20, 100, 100);
waitPanel.add(l1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The image is shown, but it's not animated. I'm using the following Gif:
Any idea?
ImageIO returns BufferedImage
Use new ImageIcon(new URL("path to resource"));
Guess you can use new ImageIcon(IndexesPanel.class.getResource("/images/error.gif"));

Capture a specified area of screen using java

I am implementing a screenshot capture in my Java web Application Which Is Already Working. I however have an issue with the screenshot because the Image is Taken for the entire Screen:
As you can see this is the entire screen, I just want to capture the area with the graphs(the White area). The Code I am using to capture this screen is:
public void captureGraphs() {
try {
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
Robot robot = new Robot();
BufferedImage img = robot.createScreenCapture(new Rectangle(size));
File f = new File("C:/capture");
if (!f.exists()) {
f.mkdir();
}
File[] flist = f.listFiles();
for (File flist1 : flist) {
flist1.delete();
}
ImageIO.write(img, "JPG", new File("C:/capture/screenShot.jpg"));
System.out.println("Capture Successfull");
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_INFO,
"Successful!",
"You have successfully taken a snapshot. Thank You"));
} catch (HeadlessException e) {
System.out.println(e.getMessage());
} catch (AWTException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Is there any way I can change this code to capture the Mid Part only holding the graphs??

BufferedImage goes black when used as method parmeter

I've got what seems like a very simple section of code, and I can't work out for the life of me why it's not working.
I have a method that listens for image updates from a camera and when it recieves them it calls another segment of code.
My listener is:
public void imageUpdated(BufferedImage image) {
if (null != video) {
video.setImage(image);
}
File outputfile = new File("savedingui.jpg");
try {
ImageIO.write(image, "jpg", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
Which happily saves the correct image to disc. However when I save the image again from the setImage method (called on line 3 of the listener code)
public void setImage(BufferedImage image) {
File outputfile = new File("savedorig.jpg");
try {
ImageIO.write(image, "jpg", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
It now just saves a jpeg of black. But the right sized square of black.
Any clues as to whats going on?
I can not reproduce your issue with the following source (which is basically copied from your question):
public static void imageUpdated(BufferedImage image) {
setImage(image);
File outputfile = new File("savedingui.jpg");
try {
ImageIO.write(image, "jpg", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void setImage(BufferedImage image) {
File outputfile = new File("savedorig.jpg");
try {
ImageIO.write(image, "jpg", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File("test.jpg"));
imageUpdated(image);
}
Is the same instance used somewhere else, e.g. camera writing updated data in it?

Using Custom Font

I am trying to set font of a JLabel to a custom font. No exceptions are thrown reading the file, but nothing appears when I call label.setText("string"). Text appears when I comment out the line label.setFont(f). Anyone know what I'm doing wrong? This code is inside a JPanel class.
_mineLabel = new JLabel();
_timeLabel = new JLabel();
try {
Font f = Font.createFont(Font.TRUETYPE_FONT,new File("/Users/simon/Documents/workspace/Minesweeper/bin/minesweeper/DS-DIGI.TTF"));
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(f);
f.deriveFont(12f);
_mineLabel.setFont(f);
_timeLabel.setFont(f);
} catch(IOException e) {
e.printStackTrace();
} catch(FontFormatException e) {
e.printStackTrace();
}
this.add(_mineLabel);
this.add(_timeLabel);
_timeLabel.setText("test");
Change this line
f.deriveFont(12f);
to
f=f.deriveFont(12f);

Categories