import java.awt.*;
import javax.swing.*;
public class O2BIntro extends Open2Beat {
private JLabel screenGraphic;
private ImageIcon introBackground;
private ImageIcon titleImage;
private ImageIcon startButtonImg;
private ImageIcon settingButtonImg;
private ImageIcon buttonSelectedImg;
public O2BIntro() {
introBackground = new ImageIcon(this.getClass().getResource("../img/wp2537453-dj-background-hd.jpg"));
titleImage = new ImageIcon(this.getClass().getResource("src/img/open2BeaTTitle.png"));
startButtonImg = new ImageIcon(this.getClass().getResource("src/img/MenuImg_Gamestart_KR.png"));
settingButtonImg = new ImageIcon(this.getClass().getResource("src/img/MenuImg_Preference_KR.png"));
}
public void paintIntro() {
screenGraphic = new JLabel(introBackground,JLabel.CENTER);
screenGraphic.setBounds(0, 0, DisplayBasic.myScreenWidth, DisplayBasic.myScreenHeight);
add(screenGraphic);
}
}
So, this is my current part of code. I tried to load my images from /src/img/, but it still doesn't display anything. How should I edit my code? Which kind of framework or component should I use to display properly?
Related
I am trying to implement Remote FrameBuffer Protocol using Java socket programming.
I have a server side program that takes screenshot of the entire screen using robot and store it in BufferedImage .Then I converted it into a byte array and sending it to the client .
Objective :
To display the entire screen of the server side machine in a Swing GUI of the client side.
Problem i am facing :
i am able to send the image in bytes from server and receive it from the server by the client (client.java) and convert it into a jpg image (output.jpg) using ImageIO and put that image in a Swing frame.
But i am able to see the first image in the Swing and whenever the image gets updated ,the image in the Swing is not updating or refreshing .
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
client.java
package remoteclient;
import java.lang.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.*;
import java.io.*;
public class client {
public static void main(String args[])throws Exception{
Socket s=new Socket("localhost",5900);
DataInputStream din=new DataInputStream(s.getInputStream());
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int width=0,height=0;
try {
width = din.readInt(); //getting width and height from server thru socket.
height = din.readInt();
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame("Client");
JLabel label = new JLabel();
f.setSize(width, height);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
boolean continueLoop = true;
while(continueLoop)
{
try {
int len = din.readInt();
byte[] imageInByte = new byte[len];
System.out.println(len);
din.readFully(imageInByte);
System.out.println(imageInByte);
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
BufferedImage bImage2 = ImageIO.read(bis);
// Image im1 = bImage2.getScaledInstance(width,height, Image.SCALE_SMOOTH);
ImageIO.write(bImage2, "jpg", new File("output.jpg") );
bImage2 = ImageIO.read(new File("output.jpg"));
label.setIcon(new ImageIcon(im1));
ImageIcon icon = new ImageIcon(bImage2);
icon.getImage().flush();
label.setIcon( icon );
f.getContentPane().add(label, BorderLayout.CENTER);
f.pack();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
Updated code with comments about demo code that should be removed from your working code:
Here's an example, using default UIManager icons, and SwingWorker, as noted in the comments to the original posting. You would instead use images from your server connection.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
public class SwingLabelWithUpdatedImage {
public static void main(String args[]) throws Exception {
final JLabel label = new JLabel("", SwingConstants.CENTER);
final JFrame frame = new JFrame("Client");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(label, BorderLayout.CENTER);
final Dimension preferredSize = new Dimension(200, 100);
frame.setPreferredSize(preferredSize);
frame.setVisible(true);
frame.pack();
final ImageUpdateWorker task = new ImageUpdateWorker(label);
task.execute();
}
public static class ImageUpdateWorker extends SwingWorker<Void, IconInfo> {
// iconInfoList is not need in your code. It's here so I can
// supply a dummy set of icons to demonstrate UI updates.
final List<IconInfo> iconInfoList;
private JLabel label;
ImageUpdateWorker(JLabel label) {
this.label = label;
// Delete this in your code
this.iconInfoList = initIconInfoList();
}
#Override
public Void doInBackground() {
boolean isTrue = true;
while (isTrue) {
// Put your socket code to read the next icon from a server.
// You don't need to do the ImageIO.write(), ImageIO.read() dance,
// unless you must save the icon to disk. In that case, you don't need
// to read it back in.
// Here, I just rotate the iconInfoList to make it
// appear as though a new icon was received.
// Your code will not have any need to do this.
Collections.rotate(iconInfoList, -1);
// Just publish the icon you create from the image
// you receive from your remote server.
publish(iconInfoList.get(0));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void process(List<IconInfo> icons) {
// You might check for an empty list.
// #kleopatra's suggestion to get the last icon is correct.
// See https://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html
IconInfo iconInfo = icons.get(icons.size() - 1);
label.setIcon(iconInfo.icon);
// Your code will not do this
label.setText(iconInfo.name);
// You can get the icon dimensions just from the icon,
// so you don't really need the IconInfo class.
label.setSize(iconInfo.dimension);
}
/** Demo code only. It doesn't belong in your working code.
*/
protected List<IconInfo> initIconInfoList() {
// Just a quick way to get some icons; don't need to
// fetch from a server just to demonstrate how to
// refresh the UI.
List<IconInfo> iconInfoList = UIManager.getDefaults().keySet().stream()
.filter(this::isIconKey)
.map(IconInfo::new)
.filter(iconInfo -> iconInfo.icon != null)
.collect(Collectors.toList());
return iconInfoList;
}
/** Demo code only. It doesn't belong in your working code.
*/
protected boolean isIconKey(Object key) {
return String.class.isAssignableFrom(key.getClass())
&& ((String) key).toLowerCase().contains("icon");
}
}
/** This is just a convenience to convey
* the icon and its UIManager key (i.e., name).
* Your remote server doesn't supply a name,
* so you don't really need this class.
* It's just to make the demo more expressive.
*/
public static class IconInfo {
final private String name;
final private Icon icon;
final private Dimension dimension;
IconInfo(Object name) {
this.name = name.toString();
icon = UIManager.getIcon(name);
dimension = icon == null
? new Dimension(32, 32)
: new Dimension(icon.getIconWidth(), icon.getIconHeight());
}
}
}
I recently started to use multithreading in Java and I've run into a problem I assume is due to missing synchronization.
This is a ImageLoader I wrote:
package util;
import javax.swing.ImageIcon;
public class ImageLoader extends Thread {
private String file;
private ImageIcon icon;
public ImageLoader(String file) {
this.file = file;
}
#Override
public void run() {
ImageIcon icon = new ImageIcon(this.file);
this.icon = icon;
super.run();
}
public synchronized ImageIcon returnIcon() {
return this.icon;
}
}
I use this ImageLoader in my GUI-Class:
package gui;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import util.ImageLoader;
public class HauptGui extends JComponent {
public HauptGui() {
initUI();
}
private void initUI() {
int bilderAnzahl = 3;
this.setLayout(new GridLayout(1, 1));
JPanel bilderPanel = new JPanel(new GridLayout(bilderAnzahl, 1));
for (int i = 0; i < bilderAnzahl; i++) {
JLabel jbl = new JLabel();
ImageLoader loader = new ImageLoader("./Picture.jpg");
loader.start();
jbl.setIcon(loader.returnIcon());
jbl.setBorder(BorderFactory.createEtchedBorder());
jbl.setPreferredSize(new Dimension(200, 50));
bilderPanel.add(jbl);
}
JScrollPane scrPn = new JScrollPane(bilderPanel);
this.add(scrPn);
}
}
The Problem is that the returnIcon-Method of the ImageLoader gets called before the Thread calls the run-Method, therefore the ImageIcon is still null.
How do I synchronize this?
No, your problem has nothing to do with synchronization and all to do with simply requesting the image object before it has been created. The solution is to get the image object in a call-back, after it has completed its loading. A SwingWorker would work well in this situation, where you get the image object from the SwingWorker in the worker's done method by calling .get() on it, or you could use a PropertyChangeListener for your callback. See Lesson: Concurrency in Swing for the details on how to use SwingWorkers.
For example (code not tested)
public class ImageLoader2 extends SwingWorker<BufferedImage, Void> {
private String path = ""; /// String to resource path
public BufferedImage doInBackground() throws Exception {
return ImageIO.read(ImageLoader2.class.getResource(path));
}
}
and then run it like:
ImageLoader2 loader = new ImageLoader2();
loader.addPropertyChangeListener(pce -> {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
try {
BufferedImage img = loader.get();
ImageIcon icon = new ImageIcon(img);
// use icon here...
} catch catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
// handle exception here
}
}
});
loader.execute();
Side notes
you should almost never extend Thread.
Don't get the image as a File as you are doing but rather get it as a resource and use ImageIO.read(...) to do this
The resource path is relative to the class-path, not to the user's directory, and so it will likely be different from the path you use to get the image as a file.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am having trouble displaying an image on a JLabel. I have another class called ControlPanel which saves the image in the project folder. I had the methods which save the image in this class but for some reason, I was getting a NullPointerException. When I moved them in the other class everything started working properly. The actual image is a bufferedImage on which the user draws.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GalleryPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private JLabel[] images;
private static final int MAX_IMAGES = 12;
private int currentImage;
public void init()
{
images = new JLabel[MAX_IMAGES];
setLayout(new GridLayout(3,4));
setBackground(Color.GRAY);
}
public void addImageToGallery(String fileName, String fileExtension)
{
if ( currentImage < images.length - 1)
{
ImageIcon icon = new ImageIcon(fileName + fileExtension);
images[currentImage] = new JLabel(icon, JLabel.CENTER);
add(images[currentImage]);
displayImage(currentImage);
currentImage++;
}
else
{
throw new ArrayIndexOutOfBoundsException("The gallery is full");
}
}
// display the doily image in the gallery
public void displayImage(int index)
{
images[index].setSize(300, 300);
add(images[index]);
}
public final int getMaxImages()
{
return MAX_IMAGES;
}
public Dimension getPreferredSize()
{
return new Dimension(380, 700);
}
}
those are the two methods in my other class which are responsible for saving the actual image
// Shows a dialog box which asks the user to choose a name for the file that he wants to save
public void saveImage(BufferedImage bufImage)
{
String fileName = JOptionPane.showInputDialog("Choose image name");
if (fileName != null)
{
if(fileName.equals(""))
{
fileName = "Untitled";
}
chooseImageFormat(bufImage, fileName);
}
}
//shows a dialog box which asks the user to select the file format of the image he would like to save
public void chooseImageFormat(BufferedImage bufImage, String fileName)
{
Object[] imageFormats = {"PNG", "JPEG"};
String userInput = (String) JOptionPane.showInputDialog(null, "Choose file format", "File Format Settings", JOptionPane.PLAIN_MESSAGE, null, imageFormats, "PNG");
String imageFormat = (userInput.equals("PNG")) ? "PNG" : "JPEG";
String fileExtension = (imageFormat.equals("PNG")) ? ".png" : ".jpg";
File file = new File(fileName + fileExtension );
try
{
ImageIO.write(bufImage, imageFormat, file);
}
catch (IOException e)
{
e.printStackTrace();
}
gallery.addImageToGallery(fileName, fileExtension);
}
I think you declare your gallery like this :
GalleryPanel gallery;
For that you get NullPointerException, so instead use this :
GalleryPanel gallery = new GalleryPanel();
EDIT
It worked but is there a way to not instantiate gallery like this?
You should to declare it and initialize it before you use it, there are another solution but you should to make many changes in your code, you have to make :
public static void addImageToGallery(String fileName, String fileExtension) {
You can call a static method like this
GalleryPanel.addImageToGallery(fileName, fileExtension);
But like i said, you should to make many changes.
Good luck.
I want t have some picture above another one and want to utilize PCamera's addLayer() method.
Is this possible?
The following code throws NullPointerException. What's wrong with it?
package test.piccolo;
import java.awt.Color;
import edu.umd.cs.piccolo.PCamera;
import edu.umd.cs.piccolo.PLayer;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolox.PFrame;
public class Try_Cameras_01 {
#SuppressWarnings("serial")
public static void main(String[] args) {
new PFrame() {
private PLayer layer1 = new PLayer();
private PLayer layer2 = new PLayer();
private PLayer layer3 = new PLayer();
private PCamera camera = new PCamera();
{
camera.addLayer(layer1);
camera.addLayer(layer2);
camera.addLayer(layer3);
}
#Override
public void initialize() {
getCanvas().setCamera(camera);
PPath redRectangle = PPath.createRectangle(0, 0, 100, 100);
redRectangle.setStrokePaint(Color.black);
redRectangle.setPaint(Color.red);
PPath greenRectangle = PPath.createRectangle(20, 20, 100, 100);
greenRectangle.setStrokePaint(Color.black);
greenRectangle.setPaint(Color.green);
PPath blueRectangle = PPath.createRectangle(40, 40, 100, 100);
blueRectangle.setStrokePaint(Color.black);
blueRectangle.setPaint(Color.blue);
layer1.addChild(redRectangle);
layer2.addChild(greenRectangle);
layer3.addChild(blueRectangle);
}
};
}
}
The problem is that when you set up a new camera it has no associated root. As a result, PCanvas.getRoot() returns null and there an NPE in one of the painting methods. Here is a basic Piccolo2D runtime structure:
Read more in Piccolo2D Patterns.
In your case you're missing a link to PRoot from a PCamera. Here is a simple fix:
private PCamera camera = new PCamera(); {
PRoot root = new PRoot();
root.addChild(camera);
camera.addLayer(layer1);
camera.addLayer(layer2);
camera.addLayer(layer3);
}
That results in:
For reference here is a copy from PUtil.createBasicScenegraph() that creates a basic camera.
public static PCamera createBasicScenegraph() {
final PRoot root = new PRoot();
final PLayer layer = new PLayer();
final PCamera camera = new PCamera();
root.addChild(camera);
root.addChild(layer);
camera.addLayer(layer);
return camera;
}
Ok so I got a static ImageIcon and the Image just doesn't show up. In the same program I use other ImagesIcon but they are not static so when I declare them I do it like this:
public ImageIcon blabla = new ImageIcon(getClass().getResource(blabla.png));
But if I declare a ImageIcon Static I cannot use that line since one cannot get acces to getClass() from a static value. Right now those images are not showing up using this:
public static ImageIcon blabla = new ImageIcon(blabla.png);
Thanks for your help!
public static ImageIcon networkOfflineIcon = new ImageIcon("Images/networkOfflineIcon.png");
public static ImageIcon networkIcon = new ImageIcon("Images/networkIcon.png");
protected static JMenuItem jmiRemote = new JMenuItem(" Remote", networkOfflineIcon);
//************************************************************************
public static void changeNetWorkStatus(boolean network_status)
//************************************************************************
{
if(network_status){
Application.jmiRemote.setIcon(networkIcon);
Application.jmiRemote.setText("NetWork Online/Remote is On");
Application.lockScreenRemote();
}else if(!network_status){
Application.jmiRemote.setIcon(networkOfflineIcon);
Application.jmiRemote.setText("NetWork Offline/Remote is Off");
Application.unlockScreenRemote();
}
}//DOESNT CHANGE THE IMAGE
//************************************************************************
In a static context, you can write:
public ImageIcon imageIcon = new ImageIcon(MyClass.class.getResource("icon.png"));
Or, alternatively try ImageIO.read(new File("icon.png"))