Click here to Skip to main content
15,895,011 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
Greetings,

I am trying to do something that should be fairly simple, or so I'm told.
I'm just starting to learn Java, btw.


You're using Eclipse and you created a Java Swing Application window.
You added an ArrayList of rectangles, a button to the left, and a custom JPanel to the right.

Note that the arraylist is not defined in the button or custom jpanel class. The reason is that its defined by user input. You see, in this app (pdf imposition app) I wrote some code that calculates the best imposition on a sheet for a given pdf and the arraylist holds the position and dimensions for each pdf rectangle/shape.

Now, you're the programmer...
Here's here's the scenario you want to see happening.

1-) The user click the impose button.
2-) The custom JPanel clears itself of any previous drawings and draws the rectangles as seen in the ArrayList of rectangles.

So you have three separate things to contend with: an ArrayList of stuff to draw, a button to initiate the drawing, and a custom jpanel to draw on.

How do you do this?

Thanks,


ps: On the internet, most code examples refer to painting that's controlled either at the class creation time or by mouse events inside the component (usually a jpanel) itself. I didn't find any examples where an external component, like a button, controls through its click event the drawing on another component that in turns draws stuff that is defined outside its own class data.

ps2: I would donate a Starbucks card for someone showing me a working example. :)
Posted
Updated 15-Sep-14 4:47am
v3
Comments
TorstenH. 2-Sep-14 2:37am    
Please write your homework yourself and come back when you've got specific questions. Posting code on that is welcome.
Shaareable 3-Sep-14 14:52pm    
Hi TorstenH, I'm 37 and getting back into programming, so its no homework... its hard work! I think I have it figured out, I needed to declare my custom canvas outside the init and at the class level so that its accessible from the click event of my button. I'll post the code sometime this week when I have a chance to get back to it.
TorstenH. 4-Sep-14 6:54am    
Sounds like a plan!
Please think about how the rectangle should be defined. They might simply use the Object Rectangle, but there are also other ways to define one (like using height and width / coordinates / ... )-

Please also take a look here: http://www.seas.gwu.edu/~rhyspj/fall05cs143/lec9/lec93.html
Shaareable 9-Sep-14 12:18pm    
Hi TorstenH, I posted the code. Thanks to your help I figured it out. Have a look! :)

1 solution

Hello!

Thanks TorstenH. for the link, it was quite good. I'd love to hear how I can make this code better, being a new programmer and all... ;) Your comments are appreciated!

So to get it to work I had to start by having my main application class extend another class (I chose JFrame). If I don't extend my main class like that I can't draw(?).

Then inside my main app class I created right at the top my two classes. One is simply to store the location of a rectangle. The other is to draw.That drawing class extends JPanel (sort of the norm for swing).

What's special about Java drawing is that since you're at the mercy of the system (you can't access the drawing directly) you have to stash all your drawing stuff in a bag like a bloody squirrel. In my case, I have to use an array, and every time the screen is repainted (repaint()) the whole thing needs to be repainted by going through everything I put inside my array.

Java
class DrawCanvas extends JPanel
{
   @Override
   public void paintComponent(Graphics g) 
   {
      super.paintComponent(g);
      for (PdfLocation p : PdfLocations)
      {
         g.drawRect((int)p.xPos, (int)p.yPos, 35, 20);
         repaint();
      }
   }
}


So above everytime repaint() is called, either from there or from somewhere else in my code (I think the fact I extend my main app class to a JFrame allows me to use repaint() anywhere in my code) this for each construct will repaint everything.

This means if you're doing some sort of drawing app, you'd need to store all your shapes as Shape objects. There's tons of stuff on the web for that.

So in my case, I needed to draw rectangles (Pdf Imposition app I'm writing) on the screen based on the click event of a button. My button simply calls a function called AddRectangle() and then repaint() the screen, for good measure.


Java
JButton btnAddARectangle = new JButton("Add a rectangle");
btnAddARectangle.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent arg0) 
   {
      AddRectangle();
      repaint();
   }
});


This AddRectangle() function in turns prepares the stuff to be drawn on the screen. Again, since you need to act like a bloody squirrel and stash your stuff away in arrays, the function that I use to prepare to draw looks at the array to see where we are and adds a rectangle next to the previous one.

Java
public void AddRectangle()
{
   PdfImagesCount++; //defined in the main app class (I hate global variables too but what else can I do in this case ?????
   lblPdfcount.setText(Integer.toString(PdfImagesCount));
		
   PdfLocation rect = new PdfLocation();
		
   if (PdfLocations.isEmpty() == false)
   {
      PdfLocation spot = PdfLocations.get(PdfLocations.size() - 1); // this gives me the last object in the array (size actually returns the number of items in the array and not the size in kb or whatever)
      rect.xPos = spot.xPos + 45;
      rect.yPos = 10;
   }	
   else
   {
      rect.xPos = 10;
      rect.yPos = 10;			
   }
   PdfLocations.add(rect);				
}


Thanks again for your link it was very good TorstenH.! :)

Java
package views;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.*;

public class appMainWindow extends JFrame
{
   class PdfLocation
   {
      public double xPos;
      public double yPos; 
   }
	
   class DrawCanvas extends JPanel
   {
      @Override
      public void paintComponent(Graphics g) 
      {
         super.paintComponent(g);
         for (PdfLocation p : PdfLocations)
         {
            g.drawRect((int)p.xPos, (int)p.yPos, 35, 20);
            repaint();
         }
      }
   }
	
   public void AddRectangle()
   {
      PdfImagesCount++;
      lblPdfcount.setText(Integer.toString(PdfImagesCount));
		
      PdfLocation rect = new PdfLocation();
		
      if (PdfLocations.isEmpty() == false)
      {
         PdfLocation spot = PdfLocations.get(PdfLocations.size() - 1);
         rect.xPos = spot.xPos + 45;
         rect.yPos = 10;
      }	
      else
      {
         rect.xPos = 10;
         rect.yPos = 10;			
      }
      PdfLocations.add(rect);				
   }

   private JFrame frame;
   public ArrayList<pdflocation> PdfLocations = new  ArrayList<pdflocation>();
   public int PdfImagesCount = 0;

   public static final int CANVAS_HEIGHT = 700;
   public static final int CANVAS_WIDTH = 1000;

   private DrawCanvas canvas;
   private JLabel lblPdfcount;
	
   public static void main(String[] args)
   {
      EventQueue.invokeLater(new Runnable() {
         public void run()
         {
            try
            {
               appMainWindow window = new appMainWindow();
               window.frame.setVisible(true);
            }
            catch (Exception e)
            {
               e.printStackTrace();
            }
         }
      });
   }

   public appMainWindow() 
   { 
      // Set up a custom drawing JPanel
      canvas = new DrawCanvas();
      canvas.setBackground(Color.WHITE);
      canvas.setBounds(150, 25, CANVAS_WIDTH, CANVAS_HEIGHT);
      initialize(); 
   }

   private void initialize() 
   {
      frame = new JFrame();
      frame.setBounds(100, 100, 1280, 850);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().setLayout(null);
		
      JButton btnAddARectangle = new JButton("Add a rectangle");
      btnAddARectangle.addActionListener(new ActionListener()
      {
         public void actionPerformed(ActionEvent arg0) 
         {
            AddRectangle();
            repaint();
         }
      });
      btnAddARectangle.setBounds(0, 6, 151, 29);
      frame.getContentPane().add(btnAddARectangle);
		
      frame.getContentPane().add(canvas);
		
      lblPdfcount = new JLabel("PdfCount");
      lblPdfcount.setBounds(10, 43, 61, 16);
      frame.getContentPane().add(lblPdfcount);
   }

}


Here's another link that is quite good as well for those like me starting with Java and drawing.
https://www3.ntu.edu.sg/home/ehchua/programming/java/J4b_CustomGraphics.html[^]

Hope this can help someone else trying to draw stuff based on events from buttons and what not!
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900