I cant seem to add an image to the JFRAME when run, it opens the Splash screen and displays the loading bar and the text, but no image, the image is in the same location as the code. The image path is fine as none needed and when hovered over, it displays the image in my IDE, Any assistance would be amazing.
import javax.swing.*;
import java.awt.*;
public class SplashScreen {
public static void main(String[] args) {
new SplashScreen();
new MenuGui();
}
JFrame f;
JLabel image = new JLabel(new ImageIcon("Calc.png"));
JLabel text = new JLabel("Loading...");
JProgressBar progressBar = new JProgressBar();
JLabel message = new JLabel();
SplashScreen() {
CreateGui();
addImage();
addText();
addProgressBar();
addMessage();
runningPBar();
f.add(image);
f.add(progressBar);
f.add(message);
f.add(text);
}
public void CreateGui() {
f = new JFrame();
f.getContentPane().setLayout(null);
f.setUndecorated(true);
f.setSize(600, 600);
f.setLocationRelativeTo(null);
f.getContentPane().setBackground(Color.CYAN);
f.setVisible(true);
}
public void addText(){
text.setFont(new Font("arial",Font.BOLD,30));
text.setBounds(170,220,600,40);
text.setForeground(Color.black);
f.add(text);
}
public void addImage(){
image.setBounds(20,30,200,300);
image.setSize(600,200);
}
public void addMessage(){
message.setBounds(100, 280, 400, 30);
message.setForeground(Color.BLACK);
message.setFont(new Font("arial", Font.BOLD, 15));
f.add(message);
}
public void addProgressBar(){
progressBar.setBounds(100,280,400,30);
progressBar.setBorderPainted(true);
progressBar.setStringPainted(true);
progressBar.setForeground(Color.black);
progressBar.setBackground(Color.WHITE);
progressBar.setValue(0);
f.add(progressBar);
}
public void runningPBar(){
int i = 0;
while (i <=100){
try {
Thread.sleep(50);
progressBar.setValue(i);
message.setText("LOADING" + Integer.toString(i) + "%");
i++;
if(i == 100)
f.dispose();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
So, the immediate issue I can see is the fact that you don't actually add image
to your frame.
You also need to beware of the limitations of ImageIcon
. In your case, it's expecting to find a image named Calc.png
within the current working directory, the problem with that is, the working directory can change.
A better solution is to "embed" these resources. How this is done typically comes down to the IDE and build system your are using, but the intention is that the image will end up within the class path of the running app, typically included in the JAR.
But there are a litany of other issues which aren't going to help you.
Swing is not thread safe and is single threaded. This means you shouldn't update the UI (or any state the UI relies on) from outside the context of the Event Dispatching Thread and you shouldn't perform any long running operations from within the context of the Event Dispatching Thread either.
See Concurrency in Swing for more details.
This leaves you with a problem. How do you do work, without blocking the UI, and keep the the UI up-to-date? Well, see Worker Threads and SwingWorker for the most common solution.
While you can use Java's inbuilt splash screen support, see How to Create a Splash Screen for more details, I tend to avoid it (personally). While it is most certainly faster, it's also ... clunky (IMHO)
Personally, I like to make use of undecorated window and just do what I need to do, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setUndecorated(true);
SplashPane splashPane = new SplashPane();
splashPane.setSplashListener(new SplashListener() {
@Override
public void didCompleteLoading(SplashPane source) {
frame.dispose();
}
});
frame.add(splashPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public interface SplashListener {
public void didCompleteLoading(SplashPane source);
}
public class SplashPane extends JPanel {
private BufferedImage coloredImage;
private BufferedImage grayscaleImage;
private JLabel loadingLabel;
private JLabel tagLine;
private LoadingWorker loadingWorker;
private double progress = 0;
private SplashListener splashListener;
public SplashPane() throws IOException {
coloredImage = ImageIO.read(getClass().getResource("/images/SplashScreen.jpeg"));
ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
grayscaleImage = op.filter(coloredImage, null);
loadingLabel = new JLabel("Loading Sith OS");
tagLine = new JLabel("Your lack of faith is disturbing");
Font font = loadingLabel.getFont();
Font extraLargeFont = font.deriveFont(Font.BOLD, font.getSize() * 4);
Font largeFont = font.deriveFont(Font.BOLD, font.getSize() * 2);
loadingLabel.setFont(extraLargeFont);
loadingLabel.setForeground(Color.WHITE);
tagLine.setFont(largeFont);
tagLine.setForeground(Color.WHITE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(20, 20, 20, 20);
gbc.anchor = GridBagConstraints.NORTH;
gbc.weightx = 1;
gbc.weighty = 0.5;
add(loadingLabel, gbc);
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.SOUTH;
add(tagLine, gbc);
configureLoadingWorker();
}
public void setSplashListener(SplashListener listener) {
splashListener = listener;
}
protected void configureLoadingWorker() {
loadingWorker = new LoadingWorker();
loadingWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (loadingWorker.getState() == SwingWorker.StateValue.DONE) {
progress = 1.0;
repaint();
// Because it's nice to see that last little bit of progress
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (splashListener != null) {
splashListener.didCompleteLoading(SplashPane.this);
}
}
});
timer.setRepeats(false);
timer.start();
} else if ("progress".equals(evt.getPropertyName())) {
progress = loadingWorker.getProgress() / 100.0;
repaint();
}
}
});
}
@Override
public void addNotify() {
super.addNotify();
loadingWorker.execute();
}
@Override
public void removeNotify() {
super.removeNotify();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(coloredImage.getWidth(), coloredImage.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xPos = (getWidth() - coloredImage.getWidth()) / 2;
int yPos = (getHeight() - coloredImage.getHeight()) / 2;
g2d.drawImage(grayscaleImage, xPos, yPos, this);
int targetHeight = (int) (coloredImage.getHeight() * progress);
if (targetHeight > 0) {
BufferedImage subimage = coloredImage.getSubimage(0, coloredImage.getHeight() - targetHeight, coloredImage.getWidth(), targetHeight);
xPos = (getWidth() - coloredImage.getWidth()) / 2;
yPos = ((getHeight() - coloredImage.getHeight()) / 2) + (coloredImage.getHeight() - targetHeight);
g2d.drawImage(subimage, xPos, yPos, this);
}
g2d.dispose();
}
protected class LoadingWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
Random rnd = new Random();
int progress = 0;
Thread.sleep(2);
do {
int delta = rnd.nextInt(9) + 1;
progress += delta;
setProgress(progress);
Thread.sleep(500);
} while (progress < 100);
setProgress(100);
return null;
}
}
}
}