I am well aware of the several other posts of similar nature. I've been trying to use them to help me, however either I am simply overlooking something or my code is missing something essential to properly work. I have a main JPanel that I am trying to have the image change every time a button is pressed (and I am starting to thing that my plan to change the layout when a different button is pressed will be a lot harder), but when it comes to the @Override section, I find that the icon cannot be changed, or when I try to implement something that I find from Stack Overflow or from suggested in VSCode, it leads to lots of red lines.
What I want is to have an array of images available so that when the button is pressed, it runs through a random number generator and outputs a number that grabs a picture from the array at random. Fret not, I am well educated in the random number generation department, I hope.
And yes, I am aware this is a hot mess. I've tried several times over the past couple of weeks to figure this out (started with only a couple hours a day to stay sane, ending with non-stop 72 hours sessions, waking from sleep with different ideas to try).
Here are some sections of my code, I am including that which I think is necessary as I have written a lot and navigating is a nightmare.
private JPanel topRow, leftPane, mainPane, bottomRow, mPane1;
private JButton btnOne, btnTen, btnHun, btnTho;
private JTextArea mPane2, test;
private String imagePath, name;
private ImageIcon image;
public WSgui() {
super("Character Wish Simulator");
this.setSize(900, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.mainPane = new JPanel();
this.mainPane.setBackground(Color.ORANGE);
this.mainPane.setMinimumSize(new Dimension(650, 400));
this.mainPane.setBorder(new EmptyBorder(40,40,40,40));
this.mainPane.setLayout(new BorderLayout());
//buttons
this.btnOne = new JButton("x1 wish");
this.btnOne.setSize(200, 100);
//setting panes for main
this.mPane1 = new JPanel();
int xSize = ((int) mainPane.getSize().getWidth());
int ySize = ((int) mainPane.getSize().getHeight());
int height = (int)(Math.round(ySize * 0.80));
int width = (int)(Math.round(xSize * 0.80));
this.mPane1.setPreferredSize(new Dimension(width, height));
this.mPane1.setMinimumSize(new Dimension(xSize, ySize));
this.mPane1.setMaximumSize(new Dimension(1000, 1000));
this.mPane2 = new JTextArea();
this.mPane2.setText("This should be below the picture");
this.mPane2.setFont(new Font("Dialog", Font.PLAIN, 15));
this.mPane2.setMaximumSize(new Dimension(width, 50));
this.mPane2.setWrapStyleWord(true);
this.mPane2.setLineWrap(true);
this.mPane2.setEditable(false);
this.btnTen = new JButton("x10 wish");
this.btnTen.setSize(200, 50);
this.btnTen.addActionListener(this);
//This idea (action listener) came from StackOverflow, but sadly is not working
this.btnHun = new JButton("x100 wish");
this.btnHun.setSize(200, 50);
this.btnHun.addActionListener(this);
this.btnTho = new JButton("x1000 wish");
this.btnTho.setSize(200, 50);
this.btnTho.addActionListener(this);
//Test image for Main Pane
image = new ImageIcon(bnr);//some more ideas I found
JLabel image5 = new JLabel(image);
JLabel image2 = new JLabel(new ImageIcon(lpImage));
JLabel image3 = new JLabel(new ImageIcon(mImage));
JLabel image4 = new JLabel(new ImageIcon(xtra));
this.mPane1.add(image3);
this.leftPane.add(image2);
this.topRow.add(image5);
this.bottomRow.add(image4);
this.mainPane.add(this.mPane1, BorderLayout.CENTER);
this.mainPane.add(this.mPane2, BorderLayout.SOUTH);
this.btnOne.addActionListener(e -> image5.setIcon(images[3]));
ImageIcon[] images = new ImageIcon[] {//my pathetic attempt at an array
new ImageIcon("img/t1.png"), new ImageIcon("img/t2.png"), new ImageIcon("img/t3.jpg"),
new ImageIcon("img/t4.jpg"), new ImageIcon("img/t5.png")
};
String[] image8 = new String[] {
"img/t1.png"//idk how to explain this one
};
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnOne) {
String image9 = image8[0];//and this is what I struggle with
ImageIcon icon9 = new ImageIcon(image9);
icon9.getImage().flush();
image.setIcon(icon9);
}
}
}
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section.
I tried to copy your code into my IDE and run it. I could not. I started over and created this GUI.
I used two images from the Internet so anyone could run this code. I read the images once during the GUI initiation.
I broke up my code into separate classes and methods. This enabled me to test each piece separately.
I created an ImageCollection
class to read the images from the Internet. You can modify this class to read from your resources directory.
I created a JFrame
and two JPanels
. I used Swing layout managers to manage the two JPanel
layout.
I created one JLabel
to display the images.
Generally, you create and initialize the Swing components once. You reuse Swing components by changing the text or images.
Here's the complete runnable code. I made the ImageCollection class an inner class so I could post the code as one block.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MultipleImageDisplay implements ActionListener, Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MultipleImageDisplay());
}
private int imageIndex;
private final ImageCollection imageCollection;
private JLabel imageLabel;
public MultipleImageDisplay() {
this.imageCollection = new ImageCollection();
this.imageIndex = 0;
}
@Override
public void run() {
JFrame frame = new JFrame("Character Wish Simulator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.EAST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
imageLabel = new JLabel();
imageLabel.setIcon(
new ImageIcon(imageCollection.getImages()[imageIndex]));
panel.add(imageLabel);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel innerPanel = new JPanel(new GridLayout(0, 1, 5, 5));
JButton btnTen = new JButton("x10 wish");
btnTen.addActionListener(this);
innerPanel.add(btnTen);
JButton btnHun = new JButton("x100 wish");
btnHun.addActionListener(this);
innerPanel.add(btnHun);
JButton btnTho = new JButton("x1000 wish");
btnTho.addActionListener(this);
innerPanel.add(btnTho);
panel.add(innerPanel);
return panel;
}
@Override
public void actionPerformed(ActionEvent event) {
imageIndex = ++imageIndex % imageCollection.getImagesLength();
imageLabel.setIcon(
new ImageIcon(imageCollection.getImages()[imageIndex]));
}
public class ImageCollection {
private Image[] images;
public ImageCollection() {
this.images = new Image[2];
this.images[0] = readImage("https://www.goodfreephotos.com/"
+ "albums/other-landscapes/mountains-and-pond-landscape"
+ "-with-majestic-scenery.jpg");
this.images[1] = readImage("https://cdn1.epicgames.com/ue/"
+ "product/Screenshot/RealisticLandscapes"
+ "%20125-1920x1080-a125dbb0885e785c4"
+ "fdafbf130b056b8.png?resize=1&w=1920");
}
@SuppressWarnings("deprecation")
private Image readImage(String urlString) {
URL url;
try {
url = new URL(urlString);
Image image = ImageIO.read(url);
return image.getScaledInstance(960, 540, Image.SCALE_SMOOTH);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public Image[] getImages() {
return images;
}
public int getImagesLength() {
return images.length;
}
}
}