Im trying to display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import java.awt.*;
public class new2 extends JFrame implements ActionListener
{
private boolean b1,b2;
Container contentPane= getContentPane();
JButton awar=new JButton("#war");
JButton arrow=new JButton("arrow");
private Image image1,image2;
public new2()
{
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setLayout(new FlowLayout());
awar.addActionListener(this);
contentPane.add(awar).setVisible(true);
arrow.addActionListener(this);
contentPane.add(arrow).setVisible(true);
}
public void init()
{
image1=Toolkit.getDefaultToolkit().getImage("#war.jpeg");
image2=Toolkit.getDefaultToolkit().getImage("arrow.gif");
}
public void paint(Graphics g)
{
if(b1==true)
{
g.drawImage(image1,0,0,this);
}
else if(b2==true)
{
g.drawImage(image2,0,0,this);
}
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if(actionCommand.equals("#war"))
{
b1=true;
}
else if(actionCommand.equals("arrow"))
{
b2=true;
}
}
public static void main(String args[])
{
new2 m=new new2();
m.setVisible(true);
}
}
..display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
Use a JToggleButton as shown here.
The buttons should set the boolean variables, but your paint2 is never called after the action preformed method. Secondly, it doesn't really even paint anything, it never gets graphics and will cause NPEs.
You should override the JFrame.paint(Graphics g) method.
Whenever you want to refresh the content of the JFrame instance call the JFrame.repaint() method.
/**
*
*/
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 MyFrame 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 MyFrame(String filename) {
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
this.image = new ImageIcon(filename).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, 0, 0, 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() {
MyFrame frame = new MyFrame("resources/image.jpg");
frame.setVisible(true);
}
});
}
}
Related
I'd like to create a Java Swing Photo Album but I can't manage to find the right way to do it. I think it should be to create two ArrayList, one to stock the photo objects and another one to stock the buttons.
After that I should find a way to assign each images to the buttons and add them into the panel.
My question is : Do you think it is the right way to do it and if so, could you give me a hint? (For the last class at the bottom)
Here's my code at the moment :
Main :
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AlbumFrame();
}
});
}
}
AlbumFrame :
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AlbumFrame extends JFrame {
private JPanel MenuPanel;
private JPanel PhotoPanel;
public AlbumFrame(){
super("JPhone");
setLayout(new BorderLayout());
PhotoPanel = new PhotoPanel();
add(PhotoPanel,BorderLayout.CENTER);
MenuPanel = new MenuPanel();
add(MenuPanel,BorderLayout.SOUTH);
setSize(480,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MenuPanel
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MenuPanel extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton backButton;
private JButton homeButton;
private JButton turnButton;
private JButton addButton;
final private JFileChooser fc;
public MenuPanel(){
fc = new JFileChooser();
backButton = new JButton(new ImageIcon(getClass().getResource("/Images/back.png")));
homeButton = new JButton(new ImageIcon(getClass().getResource("/Images/home.png")));
turnButton = new JButton(new ImageIcon(getClass().getResource("/Images/turn.png")));
addButton = new JButton(new ImageIcon(getClass().getResource("/Images/add.png")));
backButton.setPreferredSize(new Dimension(55,55));
homeButton.setPreferredSize(new Dimension(55,55));
turnButton.setPreferredSize(new Dimension(55,55));
addButton.setPreferredSize(new Dimension(55,55));
backButton.addActionListener(this);
homeButton.addActionListener(this);
turnButton.addActionListener(this);
addButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.CENTER));
add(backButton);
add(homeButton);
add(turnButton);
add(addButton);
}
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
//Test for the moment
if(clicked == backButton){
System.out.println("back");
}else if(clicked == homeButton){
System.out.println("home");
}else if(clicked == turnButton){
System.out.println("turn");
}else if(clicked == addButton){
int returnVal = fc.showOpenDialog(MenuPanel.this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
}
}
}
}
PhotoPanel
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PhotoPanel extends JPanel implements ActionListener {
ArrayList<Photo> Album = new ArrayList<Photo>();
ArrayList<JButton> Buttons = new ArrayList<JButton>();
public PhotoPanel(){
setLayout(new FlowLayout(FlowLayout.CENTER));
}
public void actionPerformed(ActionEvent e) {
}
}
I would use separate class like PhotoCard to avoid lists:
class PhotoCard {
public PhotoCard(Photo photo) {
add(photo);
// also add buttons, listeners, etc.
}
}
that holds necessary data and initializes listeners.
And then class can be added to to your PhotoPanel:
PhotoPanel.add(new PhotoCard(...));
The below code is not my actual code but a concise, runnable remake of what I am trying to achieve. I want the JPanel CP, an instance of clickPanel, to appear when the user clicks on the image in JPanel hasAnImage. I can see in the Netbeans console that the is executing because of the Sys.out.print, but nothing appears on the screen. I have tried setting visible to false then true again and revalidate() in the mousePressed event; the image moves to the left, but nothing appears on the screen. The goal is for CP to appear. What am I missing? Hope my question is clear.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Testo extends JFrame{
public Testo(){
BufferedImage image = null;
try {
image = ImageIO.read(new File("C:\\Users\\someimage.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
;
final JLabel label = new JLabel(new ImageIcon(image));
JPanel hasAnImage = new JPanel();
hasAnImage.addMouseListener(new MouseAdapter(){
#Override //I override only one method for presentation
public void mousePressed(MouseEvent e) {
clickPanel CP = new clickPanel();
hasAnImage.add(CP);
revalidate();
//setVisible(false);
//setVisible(true);
}
});
hasAnImage.add(label);
add(hasAnImage);
setVisible(true);
}
public static void main(String[] args) {
Testo frame = new Testo();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.getContentPane().setBackground(Color.WHITE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class clickPanel extends JPanel{
public clickPanel() {
setPreferredSize(new Dimension(100,60));
setMaximumSize(new Dimension(100,60));
setBackground(new Color(1.0f,1.0f,1.0f,0.1f));
setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.GREEN));
System.out.println("This is being executed...");
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Arial", Font.PLAIN, 12));
g.setColor(Color.GREEN);
g.drawString("CLICK", 2, 2);
}
}
}
Beyond revalidate();ing the pane, you also need to repaint(); it. Thus your mousePressed method should become:
public void mousePressed(MouseEvent e) {
clickPanel CP = new clickPanel();
hasAnImage.add(CP);
revalidate();
repaint();
}
For further reading: http://docs.oracle.com/javase/7/docs/api/java/awt/Component.html#repaint()
I am trying to create a form. there is a button that when clicking the button, a photo which is specified would appear. my problem is, when I click the button, the picture pops up and if the cursor passes the form boundary, the image disappears. here is my code:
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SeamCarving extends JFrame
{
public static void main(String[] args) throws IOException {
final BufferedImage input = ImageIO.read(new File("path"));
final BufferedImage[] toPaint = new BufferedImage[]{input};
final Frame frame = new Frame("Seams") {
#Override
public void update(Graphics g) {
final BufferedImage im = toPaint[0];
if (im != null) {
g.clearRect(0, 0, getWidth(), getHeight());
g.drawImage(im, 0, 0, this);
}
}
};
frame.setSize(input.getWidth(), input.getHeight());
frame.setVisible(true);
frame.add(startButton);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
BufferedImage out = input;
out = deleteVerticalSeam(out);
toPaint[0] = out;
frame.repaint();
System.out.println("Do Something Clicked");
}
});
}
}
Don't override update, this isn't how painting is achieved in Swing. Attempting to paint directly to a top level container like JFrame is problematic at best.
Instead, start with a JPanel and use it's paintComponent method instead. Make sure you call super.paintComponent as well.
In fact, you could probably just use a JLabel to display the image instead.
Take a look at;
Performing Custom Painting
How to use labels
For more details
Updated with example
I still think a JLabel would be simpler solution, but what do I know.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SeamCarving {
public static void main(String[] args) {
new SeamCarving();
}
public SeamCarving() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage input;
private BufferedImage[] toPaint;
public TestPane() {
try {
input = ImageIO.read(new File("C:\\hold\\thumbnails\\2005-09-29-3957.jpeg"));
toPaint = new BufferedImage[1];
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
BufferedImage out = input;
out = input; //deleteVerticalSeam(out);
toPaint[0] = out;
repaint();
System.out.println("Do Something Clicked");
}
});
add(startButton);
}
#Override
public Dimension getPreferredSize() {
return input == null ? new Dimension(400, 400) : new Dimension(input.getWidth(), input.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (toPaint[0] != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(input, 0, 0, this);
g2d.dispose();
}
}
}
}
The problem with overriding update is the paint subsystem can choose to avoid calling and end up calling paint directly, circumventing your painting.
Painting also involves painting child components (like your button) and borders, which you've conveniently discarded by not calling super.update.
I have a subclass of JPanel which contains an array of JComponent objects. I then use the paint(Graphics g) method to position the JComponent objects next to each other in the panel. All these JComponent Objects implement MouseMostionListener and I initialise the listener using addMouseMotionListener(this);, I also have the methods mouseMoved(MouseEvent m) and mouseDragged(MouseEvent m). All the components are being drawn correctly but the mouseMoved(MouseEvent m) and mouseDragged(MouseEvent m)are never called. Any ideas why?
Here is my code:
JPanel Subclass
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.Graphics;
import java.util.ArrayList;
public class ExamplePanel extends JPanel
{
ArrayList<ExampleComponent> components;
public ExamplePanel()
{
components = new ArrayList<ExampleComponent>();
}
public void paint(Graphics g)
{
for(ExampleComponent c : components)
g.drawImage(c.getImage(), 0, 30, 50, 75, null);
}
public void addComponent(ExampleComponent j)
{
components.add(j);
repaint();
}
public static void main(String[] args)
{
JFrame app = new JFrame("Staff Prototype");
app.setSize(700,200);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setResizable(false);
ExamplePanel s = new ExamplePanel();
app.getContentPane().add(s);
s.addComponent(new ExampleComponent());
app.setVisible(true);
}
}
JComponent Subclass:
import java.awt.Image;
import javax.swing.JComponent;
import javax.swing.ImageIcon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class ExampleComponent extends JComponent implements MouseMotionListener
{
Image image;
public ExampleComponent()
{
ImageIcon icon = new ImageIcon("image.png");
image = icon.getImage();
addMouseMotionListener(this);
}
public Image getImage()
{
return image;
}
public void mouseMoved(MouseEvent m)
{
System.out.println("Mouse Moved");
}
public void mouseDragged(MouseEvent m)
{
System.out.println("Mouse Dragged");
}
}
1)Add components like you do isn't proper way.
2)Instead of drawing Image use JLabel with icon, you get a lot of advantages with it from 'box'.
I have fixed your code, examine that:
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Example extends JPanel {
ArrayList<ExampleComponent> components;
public Example() {
components = new ArrayList<ExampleComponent>();
}
public void addComponent(ExampleComponent j) {
components.add(j);
add(j);
}
public static void main(String[] args) {
JFrame app = new JFrame("Staff Prototype");
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Example s = new Example();
s.setLayout(null);
app.getContentPane().add(s);
s.addComponent(s.new ExampleComponent(new Rectangle(0,0,25,25)));
s.addComponent(s.new ExampleComponent(new Rectangle(45,45,25,25)));
app.pack();
app.setVisible(true);
}
class ExampleComponent extends JPanel implements MouseMotionListener {
public ExampleComponent(Rectangle bounds) {
URL resource = getClass().getResource("3_disc.png");
ImageIcon icon = new ImageIcon(resource);
add(new JLabel(icon));
addMouseMotionListener(this);
setBounds(bounds);
}
public void mouseMoved(MouseEvent m) {
System.out.println("Mouse Moved");
}
public void mouseDragged(MouseEvent m) {
System.out.println("Mouse Dragged");
}
}
}
I minimized my program to include only the problem and I tried to code exactly as I understood from many examples. When I used the ActionListener, I get problem solved. But I wonder why using ItemListener, checkbox does not operate correctly.
If I run my program without ItemListener, it works correctly. With this ItemListener, checkBox doesn't change state.
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class omaJFrame extends JFrame{
private JCheckBox checkBox1;
public omaJFrame() {
super("Window Title");
TheHandler handler = new TheHandler();
setLayout(new FlowLayout());
checkBox1 = new JCheckBox("Checkbox 1");
add(checkBox1);
checkBox1.addItemListener(handler);
}
private class TheHandler implements ItemListener {
String output = "";
public void itemStateChanged(ItemEvent event) {
if (event.getItem()==checkBox1)
output = String.format("%s", checkBox1.isSelected());
JOptionPane.showMessageDialog(null, output);
}
}
}
import javax.swing.JFrame;
public class EventHandlerMain {
public static void main(String[] args) {
omaJFrame window = new omaJFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(350,200);
window.setVisible(true);
}
}
Works for me. Note also that Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class OmaJFrame extends JFrame {
private JCheckBox checkBox1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
OmaJFrame f = new OmaJFrame();
}
});
}
public OmaJFrame() {
super("Window Title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
TheHandler handler = new TheHandler();
setLayout(new FlowLayout());
checkBox1 = new JCheckBox("Checkbox 1");
add(checkBox1);
checkBox1.addItemListener(handler);
pack();
setLocationByPlatform(true);
setVisible(true);
}
private class TheHandler implements ItemListener {
String output = "";
#Override
public void itemStateChanged(ItemEvent event) {
if (event.getItem() == checkBox1) {
output = String.format("%s", checkBox1.isSelected());
}
JOptionPane.showMessageDialog(null, output);
}
}
}