redi ramaj
redi ramaj

Reputation: 117

Java : using graphics component within an action listener

I've made a JFrame with Diferent JButtons and i'd like to get an image from another class. Any ideas? Or how draw on the same class but on the action performed? Because it doesnt let me to do any drawings...my complier always gives me error messages

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.*;

public class red extends JFrame {

    public JButton b;
    public JButton b1;
    public JButton b2;
    public JButton b3;
    public JButton b4;

    public static Image p;
    public static Graphics g;
    public red() throws IOException {
        gui1 x = new gui1();
        setTitle(" ");
        setSize(1200,700);
        setLayout(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        b= new JButton("click");
        b1= new JButton();
        b.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e0){    
                b1.setBounds(0, 0, 200, 200);
                b.show(false);
                add(x);
            }       
        });
        b.setBounds(0, 0, 100, 100);
        add(b1);
        add(b);

        setVisible(true);
    }

    public static void main(String[] args) throws IOException  {
        red k = new red();
    }
}

import java.awt.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class gui1 extends Canvas {

    public static Image p;

    public void paint(Graphics g){
        g.drawImage(p, 700, 200, 100, 100, this);
    }

    {
        try {
            p= ImageIO.read(new File("Lighthouse.jpg"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Upvotes: 0

Views: 1757

Answers (1)

Frakcool
Frakcool

Reputation: 11153

Phew! I see A LOT of errors in your code (even after I corrected the compilation errors):

  1. You're not following the Java naming conventions:

    Class names should be nouns, in mixed case with the first letter of each internal word capitalized

    while red is a noun it should be more descriptive and be capitalized. The same goes for gui1

  2. You're extending JFrame which in plain english would say: red is a JFrame, you should really avoid this and create your GUI based on JPanels instead... see Java Swing using extends JFrame vs callint it inside of class

  3. You're setting size (a REAAAAAAALLY big one window for the JButton sizes you're using), instead use pack()

  4. You're using null-layout, while pixel-perfect GUIs might seem like the easiest way to create complex GUIs for Swing newbies, the more you use them the more problems related to this you'll find in the future, they are hard to maintain and cause random problems, they don't resize, etc. Please read Null layout is evil and Why is it frowned upon to use a null layout in Swing? for more information about why you should avoid its use and why you should change your GUI to work with Layout Managers along with Empty Borders for extra spacing between components.

  5. You're making use of a deprecated method JFrame#show() you should be using JFrame#setVisible(...) instead.

  6. Related to point #4, you shouldn't be calling setBounds(...) method, but let that calculations to the layout managers.

  7. You're not placing your program on the Event Dispatch Thread (EDT), Swing is not thread safe, you can fix this by changing your main() method as follows:

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Your constructor here
            }
        });
    }
    
  8. You're mixing AWT and Swing components, instead of using AWT's Canvas use Swing's JPanel which has more functionality and support.

  9. Images will become embedded resources once they're packaged in a JAR file, so it's wise to start treating them as if they already were, not as external files as shown in the embedded-resource tag.

  10. Once you change from Canvas to JPanel you should override its paintComponent(...) method and not paint(...) and call it's super.paintComponent(g) method as the first line, also don't forget to add the @Overrides annotation. See the tutorial on Swing custom painting.

  11. You're abusing the use of static keyword, see how does the static keyword works?

After seeing all the above errors I recommend you to go back and Learn the basics of the language before starting with a graphical environment which will only add more difficulty to your learning.


From what I understand you want to draw an image on a button click, if that's the case then you can wrap your image in a JLabel and add that JLabel to a JPanel which then is added to a parent JPanel which is later added to the JFrame:

enter image description here

As you can see in the GIF above, the icon is displayed after user presses the button.

Obviously this can be improved for the GUI to be more "attractive" with combinations of layout managers and empty borders as stated before.

This was done with the following code:

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
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 ImageDrawingFromOneClassToAnother {

    private JFrame frame;

    private JPanel pane;
    private JPanel leftPane;
    private JPanel rightPane;

    private ImageIcon icon;

    private JButton button;

    private JLabel label;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ImageDrawingFromOneClassToAnother().createAndShowGui();
            }
        });
    }

    public void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());

        icon = new ImageIcon(this.getClass().getResource("king.png")); //Read images as if they were already embedded resources

        button = new JButton("Draw image");

        label = new JLabel(""); //Create an empty label

        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setIcon(icon); //On button click, we set the icon for the empty label
            }
        });

        pane = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 200); //Set a size for the main panel
            }
        };

        pane.setLayout(new GridLayout(1, 2)); //The main panel

        leftPane = new JPanel(); //The button panel
        leftPane.setLayout(new BoxLayout(leftPane, BoxLayout.PAGE_AXIS));

        leftPane.add(button);

        rightPane = new JPanel(); //The panel where the image will be drawn
        rightPane.add(label);

        //We add both (button and image) panels to the main panel
        pane.add(leftPane);
        pane.add(rightPane);

        frame.add(pane); //Add the main panel to the frame
        frame.pack(); //Calculate its preferred size
        frame.setVisible(true); //Set it to be visible
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Upvotes: 5

Related Questions