Image change when button is pressed Java - java

Okay I want my background image to change when helpButton is pressed. I can make the button image change when the mouse hovers over it with a Mouse Listener. I did the same steps except with the Action Listener but with no success. Any help would be great!
public class test extends JFrame{
private JLabel label;
private JButton button;
private ImageIcon bgi;
private JLabel bgl;
public static Rectangle gameSquare;
private JButton startButton;
private JButton helpButton;
private final Action action = new SwingAction();
public static void main(String[] args) throws MalformedURLException, IOException {
test gui = new test ();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when click x close program
gui.setSize(902, 305);
gui.setVisible(true);
gui.setTitle("Solid Cloud Inc - Twitter Unfolower");
}
public test() throws MalformedURLException, IOException{
bgi = new ImageIcon(getClass().getResource("tu.png"));
getContentPane().setLayout(null);
BufferedImage img = ImageIO.read(new URL("http://i1344.photobucket.com/albums/p656/SolidCloudInc/start_zpsf3781681.png"));
//ImageIcon start = new ImageIcon(getClass().getResource("start.png"));
startButton = new JButton("");
startButton.setIcon(new ImageIcon(img));
startButton.setBounds(22, 186, 114, 50);
getContentPane().add(startButton);
BufferedImage img2 = ImageIO.read(new URL("http://i1344.photobucket.com/albums/p656/SolidCloudInc/help_zpsc4fad867.png"));
final JButton helpButton = new JButton("");
helpButton.setIcon(new ImageIcon(img2));
helpButton.setBounds(192, 186, 114, 50);
getContentPane().add(helpButton);
bgl = new JLabel (bgi);
bgl.setBounds(0, 0, 886, 272);
getContentPane().add(bgl);
Events e = new Events();
startButton.addActionListener(e);
helpButton.addActionListener(e);
}
public class Events implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == startButton) {
label.setText("Searching");
try {
Unfollow();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else if (e.getSource() == helpButton){
System.out.println("gottem");
bgi = new ImageIcon(getClass().getResource("tu2.png"));
bgl = new JLabel (bgi);
}
}
}

bgl = new JLabel (bgi);
Here you're creating a new JLabel, and putting it into the bgl variable but are doing anything with it and make no change to the JLabel object that continues to be shown in the GUI. It's a common newbie trap to think that by changing the reference of a variable you change the state of the original object that the variable previously referred to. That's not how it works. In other words, the original JLabel that was held by the bgl variable still exists and still displays its original content in the GUI despite this code above. What you should do instead is to change the icon shown by the original JLabel, or in other words, change the state of the current JLabel object, not change references held by the bgl variable. i.e.,
bgl.setIcon(bgi);
Also, you'll want to get rid of any and all use of null layout and calls to setBounds(...) as this will lead to buggy hard to maintain and upgrade code. Let the layout managers do the heavy lifting with regards to laying out the GUI.

Related

a button that takes to a new panel

I created a button that is in the main page which when a user clicks on it، it changes the panal ( the main idea is that it changes the background and all whats on the panel and adds new stuff to it ) however i failed!, i also failed in adjusting the location of the button although i tried button.setBounse(..)
anyhow can someone help me in those two things?
public class mainClass {
private static JButton start;
static BackgroundPanel bp = null;
static JFrame mainf = null;
public static void main(String[] args) throws IOException {
mainf = new JFrame ("سين جيم");
// background
BufferedImage mFrame = ImageIO.read(new File("B1.png"));
bp = new BackgroundPanel(mFrame);
mainf.add(bp);
bp.setLayout(new GridBagLayout());
// Hi string
JLabel hi = new JLabel ("أهلا وسهلا");
Font fs = hi.getFont();
hi.setFont(fs.deriveFont(50f));
bp.add(hi);
// button
JPanel another = new JPanel();
start = new JButton ( " لنبدأ");
bp.add(start);
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
bp.removeAll();
BufferedImage mFrame2= null;
try {
mFrame2 = ImageIO.read(new File("B2.png"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
bp = new BackgroundPanel(mFrame2);
bp.setLayout(new GridBagLayout());
JLabel hi1= new JLabel ("worked");
bp.add(hi1);
}
} );
// end of frame
mainf.pack();
mainf.setVisible(true);
}
}
Well, to change your main panel you don't have to create a new Frame object and set it's main panel. E.g., you could write a setter for bp and invoke this method in your action listener method. If your panel has a different size, you can easily change the frame's size...

hiding and showing images with setVisible method

I wrote a class that uses buttons to play radio stations broadcast to the internet.
When the buttons are pressed, I also wanted to have a series of images in the Frame selectively hidden and shown.
I am trying to do this by adding Images, setting "setVisible(false);" and then overriding the setVisible method when the button is clicked.
It isn't viable in it's current state. Is there a way to do this?
I'm pretty new to writing code.
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
String text = button.getText();
JLabel img = new JLabel(new ImageIcon("resources/1920.png"));
img.setBounds(642, 230, 100, 100); // x, y, width, height
add(img);
img.setVisible(false);
if (text.equals("1920a"))
{
try
{
getMediaPlayer().setURI(mediaPaths[0]);
img.setVisible(true);
}
catch (URISyntaxException e1)
{
e1.printStackTrace();
}
Each time you press the button, you are creating a new instance of a JLabel and adding it to the screen, but you're not keeping track of them...
// Yet ANOTHER label...which one it is, nobody knows...
JLabel img = new JLabel(new ImageIcon("resources/1920.png"));
img.setBounds(642, 230, 100, 100); // x, y, width, height
add(img);
img.setVisible(false);
If you only want a single image on the screen at a time, then simply change the icon label of a single label...
Start by declaring an instance field for the pictures...
public class ... {
//...
private JLabel pictureLabel;
Add the label to the screen...
public ... { // Public constructor
//...
pictureLabel = new JLabel();
add(pictureLabel);
Now, when you want to change the picture, simply change the icon property of the label...
pictureLabel.setIcon(new ImageIcon("resources/1920.png"));

How to change image of a JLabel in another thread

I want to make a Swing version TimeBomber, which means when time is counted down to 1 the Bomb will blow up! I have two images, images.png for a bomb in normal state, bomber.jpg for a bomb that has blown up. Apparently I need to change the images.png(which is already in an JLabel) to bomber.jpg when i==1; But I have no idea of how to change the pic location content in ImageIcon and as the change happens in anonymous inner class, so change value became difficult as final type var is not modifiable unless you call function.
public class TimeBomber {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
//create Jframe
JFrame app = new JFrame("Time Bomber");
//create JPanel
final JPanel panel = new JPanel();
//JLabel with first Picture
JLabel pic = new JLabel(new ImageIcon("images.png"));
pic.setSize(100, 100);
//Label for displaying time digit
final JLabel label = new JLabel("");
label.setLocation(200, 250);
//create another thread
Thread time = new Thread(){
public void run(){
for(int i=10; i>0; i--){
if(i==1){
JLabel picSecond = new JLabel(new ImageIcon("Bomber.jpg"));
//<--Fact is I dont want to create another JLabel, I want to modify the pic location content in JLabel pic.
picSecond.setSize(100, 100);
panel.add(picSecond);
}
label.setText("Time: "+i);
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
//add every component to where it belongs
panel.add(pic);
panel.add(label);
app.add(panel);
app.setSize(300, 400);
app.setVisible(true);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
time.start();
}
}
Wrap the code in SwingUtilities.invokeAndWait() (or SwingUtilities.invokeLater())
if(i==1){
JLabel picSecond = new JLabel(new ImageIcon("Bomber.jpg"));//<--Fact is I dont want to create another JLabel, I want to modify the pic location content in JLabel pic.
picSecond.setSize(100, 100);
panel.add(picSecond);
}
label.setText("Time: "+i);
TO avoid recreation of the JLabel make it the class' field and add to panel just once. Then use picSecond.setIcon() to update the image.
BTW it's better to have kind of images cache to avoid image recreation on each step.

How does this update a component without using an actionListener?

Code in Question
There isn't an actionListener for the image thumbnails, yet when clicked they update the image.
From this webpage.
Edit: I am currently importing images using JFileChooser and then creating a thumbnail and displaying the full image in a similar way to this, although not using ImageIcons. But would like to use this method so when I add an image it adds to the list and allows me to click the thumbnail to show that image.
However mine using actionListeners to change when something is pressed but this doesn't and can't understand the code where it does.
Thanks
Edit2:
Regarding the repaint option:
I have a class which extends component which then calls a repaint function.
public class Image extends Component {
private BufferedImage img;
//Print Image
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
I then have a class with all my Swing components which call methods from other classes.
Image importedImage = new Image(loadimageone.openFile());
Image scaledImage = new Image();
// Save image in Buffered Image array
images.add(importedImage.getImg());
// Display image
imagePanel.removeAll();
imagePanel.add(importedImage);
imagePanel.revalidate();
imagePanel.repaint();
previewPanel.add(scaledImage);
previewPanel.revalidate();
previewPanel.repaint();
If I remove the revalidate or repaint it wont' update the image on the screen.
Edit 3:
This is the code on how I implemented the dynamic buttons:
//Create thumbnail
private void createThumbnail(ImpImage image){
Algorithms a = new Algorithms();
ImpImage thumb = new ImpImage();
//Create Thumbnail
thumb.setImg(a.shrinkImage(image.getImg(), 75, 75));
//Create ImageIcon
ImageIcon icon = new ImageIcon(thumb.getImg());
//Create JButton
JButton iconButton = new JButton(icon);
//Create ActionListener
iconButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bottomBarLabel.setText("Clicked");
imagePanel.removeAll();
imagePanel.add(images.get(position)); //Needs Fixing
imagePanel.revalidate();
}
});
//Add to previewPanel
previewPanel.add(iconButton);
previewPanel.revalidate();
previewPanel.repaint();
}
It looks like it uses ThumbnailAction instead which extends AbstractAction (at the very bottom of the code). Swing components can use Actions instead of ActionListeners. The advantage of Actions is that buttons can share an Action and they will automatically use the same key-bindings etc.
http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
EDIT: I have added some code demonstrating that you do not need to explicitly repaint(). Give it a try.
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(2, 1));
final JLabel iconLabel = new JLabel();
JButton button = new JButton("Put Image");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
iconLabel.setIcon(new ImageIcon(ImageIO.read(fc.getSelectedFile())));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
panel.add(iconLabel);
panel.add(button);
frame.add(panel);
frame.setVisible(true);
}
EDIT 2 (There is no Edit 2)
EDIT 3: Try this
public class MyActionListener implements ActionListener {
private JPanel imagePanel;
private Image image;
public MyActionListener(JPanel imagePanel, Image image) {
this.imagePanel = imagePanel;
this.image = image;
}
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Clicked");
imagePanel.removeAll();
imagePanel.add(image); //Needs Fixing
imagePanel.revalidate();
}
}

null pointer exception error using action listener

I'm getting the error message null pointer exception on the line img.setIcon(bg); in the controller class in my action listener and I'm not sure why. I've commented where the error is highlighted. Any ideas on why?
public class Display {
public ImageIcon bg;
public JLabel img;
public void UI() {
Controller listener = new Controller();
bg = new ImageIcon("prophase.png");
img = new JLabel(bg, JLabel.CENTER);
JFrame gameFrame = new JFrame();
JPanel top = new JPanel();
JPanel bottom = new JPanel();
JPanel imgPane = new JPanel();
JPanel panel1 = new JPanel();
imgPane.setLayout(new BorderLayout());
panel1.setLayout(new BorderLayout());
panel1.setOpaque(false);// !!
top.setBorder(BorderFactory.createTitledBorder(""));
bottom.setBorder(BorderFactory.createTitledBorder(""));
JLabel jl = new JLabel("What stage of mitosis is this?", JLabel.CENTER);
imgPane.add(img);// center
top.add(jl);// top center
top.add(listener.wordListener());// top center
bottom.add(listener.answer);// bottom
panel1.add(imgPane, BorderLayout.CENTER);// background image (center)
panel1.add(top, BorderLayout.NORTH);// text field and jlabel (top)
panel1.add(bottom, BorderLayout.SOUTH);// blank spaces and letters used
gameFrame.setJMenuBar(menuBar());
gameFrame.setTitle("Mitosis");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.setIconImage(new ImageIcon("logo.png").getImage());
gameFrame.setResizable(false);
gameFrame.add(panel1);
gameFrame.setSize(400, 300);
gameFrame.setLocationRelativeTo(null);
gameFrame.setVisible(true);
}
}
another class:
public class Controller {
Display display = new Display();
private JFrame dialogFrame = new JFrame();
private ImageIcon logo = new ImageIcon("logo.png");
public String word;
public JLabel answer = new JLabel(" ", JLabel.CENTER);
public JTextField wordListener() {
JTextField tf = new JTextField(10);
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {// right click key
JTextField tf = (JTextField) e.getSource();
word = tf.getText();
if (word.equalsIgnoreCase("Prophase")) {
answer.setText("Correct!");
ImageIcon bg = display.bg;
JLabel img = display.img;
bg = new ImageIcon("interphase.png");
img.setIcon(bg);//error
answer.setText(" ");
} else {
answer.setText("Incorrect, try again.");
}
tf.setText("");
}// end actionPerformed method
});
return tf;
}
}
The default constructor of Display doesn't initialize the attribute img, which is then initialized to null by default. The exception is clearly due to the fact that you are trying to use img without initializing it anywhere. You should define a default constructor for Display that does something like this:
public Display(){
UI();
}
Because in UI() you are initializing img.
Also you have to initialize your display before using img, like this:
Display display = new Display();
Please check if the path for your image is correct
bg = new ImageIcon("interphase.png");
If a resource is not found you will get a NullPointerException when you try to use that imageicon somewhere else.
Try something along the lines
getClass().getResource("interphase.png");
prepend the directory name if needed, in order to get to your image in your resources.
Also, make sure you are initialising the variable in the Display class before using it.

Categories