2

I am currently trying to create a Java GUI program that generates images based on the arguments given in the terminal. If I get the argument in the command line java Draw Image1 for example, I want to draw my image 1 and etc. for the others. How can one take a command argument and use it in paintComponent? Here's a sample of what I am trying to do below:

import javax.swing.*;
import java.awt.*;

public class Draw extends JPanel
{

    public Draw()
    {
        this.setSize(800,800);
        JPanel drawing = new JPanel();
        this.add(drawing);
        this.setVisible(true);
    }

    protected void paintComponent(Graphics g)
    {
        if (args[0].equals("Image1")) // won't work
        {
            super.paintComponent(g);
            Image myImage = Toolkit.getDefaultToolkit().getImage("image/myimage.jpg");
            g.drawImage(myImage, 0, 0, this);
        }
        else
        {
            // draw image 2
        }
    }

    public static void main(String[] args)
    {       
        // create new Jframe
        JFrame frame = new JFrame("Draw");
        frame.add(new Draw());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setVisible(true);
    }
}
Ampage Grietu
  • 89
  • 1
  • 2
  • 10
  • 1
    `Image myImage = Toolkit.getDefaultToolkit().getImage("image/myimage.jpg");` Never attempt to load a resource in the paint methods. That image could be loaded when the class is constructed and then stored as class attributes (that are accessible in paint). – Andrew Thompson Nov 16 '14 at 17:31

1 Answers1

5

Change this:

frame.add(new Draw());

to this:

frame.add(new Draw(args));

And then have your constructor accept a String array parameter and use it to set a class field.

public class Draw extends JPanel
{
    private String[] params

    public Draw(String params)
    {
        this.params = params;
        this.setSize(800,800);  // this generally should be avoided
        JPanel drawing = new JPanel();
        this.add(drawing);
        this.setVisible(true);
    }

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);  // this should be out of the if block
        if (params != null && params.length > 0 && params[0].equals("Image1")) {
          // ..... etc

Edit: Andrew is right and I did not read your code carefully. Read your image in the constructor and use it in the image in the paintCompnent method


e.g.,

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

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

@SuppressWarnings("serial")
public class Draw extends JPanel {

   private static final int PREF_W = 800;
   private static final int PREF_H = PREF_W;
   private BufferedImage image;

   public Draw(String[] params) throws IOException {
      if (params != null && params.length > 0) {
         image = ImageIO.read(new File(params[0]));
      }
      // this.setSize(800,800);
      JPanel drawing = new JPanel();
      drawing.setOpaque(false); // may need this
      this.add(drawing);
      this.setVisible(true);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (image != null) {
         g.drawImage(image, 0, 0, null);
      } else {

      }

   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }

      // not sure if you want to size it to the image or not
      if (image != null) {
         int w = image.getWidth();
         int h = image.getHeight();
         return new Dimension(w, h);
      } else {
         return new Dimension(PREF_W, PREF_H);
      }
   }

   public static void main(String[] args) {
      // create new Jframe
      JFrame frame = new JFrame("Draw");
      try {
         frame.add(new Draw(args));
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         // frame.setSize(500,500);
         frame.pack();
         frame.setVisible(true);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    And now *I've* read it more carefully, I think the `Draw` panel should accept only `Image[]` on the basis that if it needs an image (or two) give it images rather than strings that represent the path of an image.. But +1 for getting it this far. – Andrew Thompson Nov 16 '14 at 17:35
  • 1
    @AndrewThompson: yes, you're probably right, but it's all part of the larger question of how to pass information from the static world into the instance world. – Hovercraft Full Of Eels Nov 16 '14 at 17:44
  • True. I forgot to add that part was just a personal 'design grievance' of mine, that is not even adhered to in the J2SE. :P – Andrew Thompson Nov 16 '14 at 17:46