I have a problem. I don't know how to display an image by clicking a JButton.
I have a class which can show and hide an image:
/**
*
*/
package com.samples;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
* @author
*
*/
public class New2 extends JFrame implements ActionListener {
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
private Image image = null;
private boolean showImage = false;
public New2(String filename) {
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
this.image = new ImageIcon("..//src/img/Ster.png").getImage();
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.SOUTH);
}
private JPanel createControls() {
JButton showButton = new JButton("Show");
showButton.addActionListener(this);
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.addActionListener(this);
hideButton.setActionCommand(HIDE_ACTION);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(showButton);
panel.add(hideButton);
return panel;
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (showImage) {
g.drawImage(image, 100, 200, image.getWidth(null), image.getHeight(null), null);
}
}
@Override
public void actionPerformed(ActionEvent event) {
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand)) {
showImage = true;
} else if (HIDE_ACTION.equals(actionCommand)) {
showImage = false;
}
repaint();
}
/**
* @param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
New2 frame = new New2("resources/image.jpg");
frame.setVisible(true);
}
});
}
}
I'm working with MVC so I want the code for the JButton in my map for controllers but I don't know how to do this.
package View;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import Controller.HomeController;
import Controller.KeeperController;
public class Selectie extends JFrame{
private JLabel label, label1, label2;
private JButton keeper;
private JPanel panel;
private Container window = getContentPane();
private KeeperController controller;
public Selectie()
{
initGUI();
}
public void initGUI()
{
setLayout(null);
setTitle();
setSize(800,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel();
label.setBounds(0, 0, 266, 800);
label.setBackground(Color.RED);
label.setOpaque(true);
window.add(label);
label1 = new JLabel();
label1.setBounds(266, 0, 266, 800);
label1.setBackground(Color.BLACK);
label1.setOpaque(true);
window.add(label1);
label2 = new JLabel();
label2.setBounds(532, 0, 266, 800);
label2.setBackground(Color.RED);
label2.setOpaque(true);
window.add(label2);
keeper = new JButton("1. "+""+" Kenneth Vermeer");
keeper.setBounds(60, 500, 200, 25);
keeper.setFocusable(false);
keeper.setBorderPainted(false);
keeper.setContentAreaFilled(false);
keeper.setFont(new Font("Arial",Font.PLAIN,17));
label.add(keeper);
}
}
The button keeper needs to show the image when it is clicked.
As said likewise, by others, always use JLabel
to display images. That way it's easy to add/remove them as an when needed, instead of painting. Moreover, in your code you are overriding paint(...)
, for Swing
we prefer to override paintComponent(...)
method of the respective JComponent
if the said component in question has one.
Here try this code, I had separated the Controller part, you might get some idea, as to how to do things :
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
/**
* @author
*
*/
public class New2 extends JFrame
{
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
public New2(String filename)
{
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.CENTER);
}
private JPanel createControls()
{
JButton showButton = new JButton("Show");
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.setActionCommand(HIDE_ACTION);
JLabel imageLabel = new JLabel();
New2Controller n2c = new New2Controller(showButton
, hideButton, imageLabel);
showButton.addActionListener(n2c);
hideButton.addActionListener(n2c);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(imageLabel);
panel.add(showButton);
panel.add(hideButton);
return panel;
}
/**
* @param args
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
New2 frame = new New2("/img/image.jpg");
frame.setVisible(true);
}
});
}
}
class New2Controller implements ActionListener
{
private JButton showButton;
private JButton hideButton;
private JLabel imageLabel;
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
public New2Controller(JButton show, JButton hide, JLabel label)
{
showButton = show;
hideButton = hide;
imageLabel = label;
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand))
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
imageLabel.setIcon(infoIcon);
}
});
}
else if (HIDE_ACTION.equals(actionCommand))
{
imageLabel.setIcon(null);
}
}
}
This code represents how you read using ImageIO
and URL
,
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.imageio.ImageIO;
/**
* @author
*
*/
public class New2 extends JFrame
{
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
public New2(String filename)
{
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.CENTER);
}
private JPanel createControls()
{
JButton showButton = new JButton("Show");
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.setActionCommand(HIDE_ACTION);
JLabel imageLabel = new JLabel();
New2Controller n2c = new New2Controller(showButton
, hideButton, imageLabel);
showButton.addActionListener(n2c);
hideButton.addActionListener(n2c);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(imageLabel);
panel.add(showButton);
panel.add(hideButton);
return panel;
}
/**
* @param args
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
New2 frame = new New2("/img/image.jpg");
frame.setVisible(true);
}
});
}
}
class New2Controller implements ActionListener
{
private JButton showButton;
private JButton hideButton;
private JLabel imageLabel;
private Image image;
private ImageIcon imageIcon;
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
public New2Controller(JButton show, JButton hide, JLabel label)
{
showButton = show;
hideButton = hide;
imageLabel = label;
try
{
image = ImageIO.read(getClass().getResource("/img/caIcon.png"));
}
catch(Exception e)
{
e.printStackTrace();
}
imageIcon = new ImageIcon(image);
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand))
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
imageLabel.setIcon(imageIcon );
}
});
}
else if (HIDE_ACTION.equals(actionCommand))
{
imageLabel.setIcon(null);
}
}
}
Moreover, when you are using BorderLayout
never use NORTH
, EAST
, WEST
and SOUTH
for BorderLayout. They have been replaced with PAGE_START
, LINE_START
, LINE_END
and PAGE_END
respectively.
A BorderLayout object has five areas. These areas are specified by the BorderLayout constants:
- PAGE_START
- PAGE_END
- LINESTART
- LINE_END
- CENTER
Version note: Before JDK release 1.4, the preferred names for the various areas were different, ranging from points of the compass (for example, BorderLayout.NORTH for the top area) to wordier versions of the constants we use in our examples. The constants our examples use are preferred because they are standard and enable programs to adjust to languages that have different orientations.
Directory Structure :
Your Project
| |
classes src
| |
img *.class(or package Folder)
Now use getClass().getResource("/img/star.png");
1) use JLabel#setIcon() instead of painting image as background to the JFrame
2) create methods into class Selectie
private void setIconToLabel (Icon icon){
myDesiredLabel.setIcon(icon);
}
3) don't create a new JFrame for another image use CardLayout instaed
You can simply add a JLable to show image on it. After this, you can setVisible JLabel depending on condition.