I made a Java program with Swing libraries that displays text and an image. Both the text string and the image filename are set via a set method, but while the text is displayed correctly, the image is not.
If I set the filename directly in the constructor then it works, but it is not what I want to do.
I cannot find a way to pass the filename to display the image.
The intention is to periodically pass an array of strings and a set of image filenames, to have a GUI with text and image changing over time.
Here is the code simplified:
import javax.swing.*;
import java.net.URL;
class Swing extends JFrame {
private JLabel label = new JLabel();
private String imageFilename = new String();
Swing()
{
super("Swing Test Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000, 700);
setLayout(null);
setLocationRelativeTo(null);
label.setBounds(10, 0, 220, 100);
add(label);
//String imageFilename = "images\\image-1.jpg";
URL imageURL = getClass().getResource(imageFilename);
if (imageURL != null) {
ImageIcon imageIcon = new ImageIcon(imageURL);
JLabel imageLabel = new JLabel(imageIcon);
imageLabel.setBounds(10, 200, 420, 420);
add(imageLabel); // Aggiungi l'etichetta al frame
} else {
System.err.println("Image " + imageFilename + " not found.");
}
setVisible(true);
}
void SetText(String strLabel, String imageFilename)
{
label.setText(strLabel);
this.imageFilename = imageFilename;
return;
}
public static void main(String arg[])
{
Swing swing = new Swing();
swing.SetText("This is string 1", "images\\image-1.jpg");
}
}
2 Answers 2
In the same way that you declared a JLabel field for the text label, you can declare another JLabel field for the image label:
private JLabel label = new JLabel();
private JLabel image = new JLabel(); // <-------
Swing()
{
super("Swing Test Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1000, 700);
setLayout(null);
setLocationRelativeTo(null);
label.setBounds(10, 0, 220, 100);
add(label);
image.setBounds(10, 200, 420, 420);
add(image);
setVisible(true);
}
In SetText, call setIcon on the image label:
void SetText(String strLabel, String imageFilename)
{
label.setText(strLabel);
URL imageURL = getClass().getResource(imageFilename);
if (imageURL != null) {
ImageIcon imageIcon = new ImageIcon(imageURL);
image.setIcon(imageIcon);
} else {
System.err.println("Image " + imageFilename + " not found.");
}
}
4 Comments
With a few modifications, your code will work as expected:
public class Swing extends JFrame {
private JLabel imageLabel;
private JLabel label;
Swing() {
super( "Swing Test Application" );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setLocationRelativeTo(null);
setSize( 1000, 700 );
setLayout( null );
// create both labels
imageLabel = new JLabel();
// we assign the initial text
label = new JLabel( "Default text" );
// we assign the sizes and positions only once
imageLabel.setBounds( 10, 200, 420, 420 );
label.setBounds( 10, 0, 220, 100 );
// set icon with path to default icon
// your IDE will probably complain that "setFrameIcon" is not "private",
// but since it will be invoked later by other sections of the
// code you need it to look like this
setFrameIcon( "images/aa.jpg" );
add( imageLabel );
add( label );
setVisible( true );
}
public void setFrameIcon( String imageFilename ) {
try {
// we create the "ImageIcon" object as a resource, to be able to use
// it from the "Jar".
// you must take into account that absolute routes are not accepted.
ImageIcon icon = new ImageIcon( getClass().getResource( imageFilename ) );
imageLabel.setIcon( icon );
// in one line
imageLabel.setIcon( new ImageIcon( getClass().getResource( imageFilename )));
}
catch( Exception e ) {
System.err.println( "Image " + imageFilename + " not found." );
}
}
public void setText( String strLabel ) {
label.setText( strLabel );
}
public static void main( String arg[] ) {
// we use "InvokeLater" so that the "GUI" is built on the event thread
SwingUtilities.invokeLater( () -> {
Swing swing = new Swing();
} );
}
}
java -jar slides.jarSource inside the jar