Hi,

I am trying to do something like this:-

1         10         20        30
##########|##########|##########
  rect 1     rect2      rect3
 
    5 ########### 15
      user rect - (transparent and temporary based on user mousedrag)

Now If a user clicks suppose in the middle of rect1 and drags it to the middle of rect2. I want to create a transparent rectangle or just a simple rectangle from the start point to the end point. Then it should print the values 5 and 15 in line and compared to the original rectangles.

Here is my input file:-

1	50	993	Andrew
51	100	399	Peacock
101	143	993	John
144	155	333	Mathew
156	200	993	David
201	235	300	Peter
236	256	993	Austin

Here is my code so far:-

import java.io.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;

      public class Demo extends JFrame {
              public Color color;
              public int height;
              public int fixvalue1;
              public int fixvalue2;
              public int width;
              public String text;
              
              private JPanel paintPanel;

      public Demo(int height, int fixvalue1, int width, int fixvalue2, Color c,String text) {
        this.color = c;
        this.height = height;
        this.fixvalue1 = fixvalue1;
        this.width = width;
        this.fixvalue2 = fixvalue2;
        this.text = text;

      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setMinimumSize(new Dimension(1000, 200));
      paintPanel = new PaintPanel();
      getContentPane().add(paintPanel, BorderLayout.CENTER);
      pack();
      }
      class PaintPanel extends JPanel implements MouseMotionListener {
      public List<Glyph> glyphs;
          public int height;
          public int width;
          public String f[];
          private final static int NUM_FIELDS = 4;
          BufferedImage image;
	  Graphics2D g2d;
          Point startPoint = null;
          Point endPoint = null;
          private int xMin;
          private int xMax;
	  private int yMin;
	  private int yMax;
          
      public PaintPanel(){
      super();
      addMouseMotionListener(this);
      glyphs = new ArrayList<Glyph>();
              String n = null;  
        try{
            BufferedReader fh = new BufferedReader(new FileReader("InputFile.txt"));    
            while((n = fh.readLine()) != null && (n = n.trim()).length() > 0){

                f = n.split("\t");
                int height = Integer.parseInt(f[0].trim());
                int width = Integer.parseInt(f[1].trim());
                String text = f[3];
                Color color = new Color(Integer.parseInt(f[2]));
                int fixvalue1 = 60;
                int fixvalue2 = 27;

                glyphs.add(new Glyph(height, fixvalue1, width, fixvalue2, color, text));

            }
            fh.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e2) {
            e2.printStackTrace();
        }
      }
      public void paintComponent(Graphics g) {
      super.paintComponent(g);
      for (Glyph glyph : glyphs){
      glyph.draw(g);
      }
      			if (image == null)
			{
				createEmptyImage();
			}

			g.drawImage(image, 0, 0, null);

			//  Paint the Rectangle as the mouse is being dragged

			if (startPoint != null && endPoint != null)
			{
				int x = Math.min(startPoint.x, endPoint.x);
				int y = Math.min(startPoint.y, endPoint.y);
				int width = Math.abs(startPoint.x - endPoint.x);
				int height = Math.abs(startPoint.y - endPoint.y);
				g.drawRect(x, y, width, height);
			}
      }
      		private void createEmptyImage()
		{
			image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
			g2d = (Graphics2D)image.getGraphics();
			g2d.setColor(Color.BLACK);
			g2d.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15);
		}

		public void clear()
		{
			createEmptyImage();
			repaint();
		}
      public void mousePressed(MouseEvent e) {
				startPoint = e.getPoint();
				xMin = startPoint.x;
				xMax = startPoint.x;
				yMin = startPoint.y;
				yMax = startPoint.y;
      } 
      public void mouseDragged(MouseEvent e) {
          			endPoint = e.getPoint();
				xMin = Math.min(xMin, endPoint.x);
				xMax = Math.max(xMax, endPoint.x);
				yMin = Math.min(yMin, endPoint.y);
				yMax = Math.max(yMax, endPoint.y);
				repaint(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1);
      }
      public void mouseReleased(MouseEvent e) {
          			int x = Math.min(startPoint.x, endPoint.x);
				int y = Math.min(startPoint.y, endPoint.y);
				int width = Math.abs(startPoint.x - endPoint.x);
				int height = Math.abs(startPoint.y - endPoint.y);

				g2d.setColor( e.getComponent().getForeground() );
				g2d.drawRect(x, y, width, height);
				startPoint = null;
      }
      public void mouseMoved(MouseEvent e) {
      for(Glyph g : glyphs){
      g.showLabel( g.contains(e.getX(), e.getY()) );
      }
      repaint();
      }
      }

      class Glyph {
      private Rectangle bounds;
      private Color color;
      private Paint paint;
      private String label;
      private boolean showLabel = false;
      public Glyph(int x, int y, int width, int height, Color color, String label) {
      bounds = new Rectangle(x, y, width, height);
      this.color = color;
      this.paint = new GradientPaint(x, y, color, x, y+height, Color.WHITE);
      this.label = label;
      }
      public void draw(Graphics g){
      Graphics2D g2 = (Graphics2D)g;
      g2.setPaint(paint);
      g2.fill(bounds);
      if (showLabel){
      g2.setColor(Color.BLACK);
      int labelWidth = g2.getFontMetrics().stringWidth(label);
      int fontHeight = g2.getFontMetrics().getHeight();
      g2.drawString( label,
      (int)(bounds.getX()),
      (int)(bounds.getY()));
      }
      }
      public boolean contains(int x, int y){
      return bounds.contains(x,y);
      }
      public void showLabel(boolean show){
      showLabel = show;
      }
      }
      public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
      new Demo(0, 0, 0, 0, null, null).setVisible(true);
      }
      });
      }
    public Color getColor(){
        return color;
    }

    public String toString() {
        return String.format("Color=%s,top=%d,bottom=%d,width=%d", color.toString(), height, fixvalue1, width, fixvalue2, text);
    }
      }

Thanks in advance and need guidance.

Recommended Answers

All 19 Replies

You can draw the Rectangle from within paintComponent just by using g.drawRect or g.draw3DRect or whatever the methods are. You are over complicating things by using the coordinates and whatnot.

Class PaintPanel must implements MouseListener.

Class PaintPanel must implements MouseListener.

Thats what I am doing :) lol

No, your class def only states that it implements MouseMotionListener. It also needs to implement MouseListener as adatapost says and it needs to register itself with addMouseListener().

edit: You'll need to add mouseClicked(), mouseEntered(), and mouseExited() methods as well to fulfill the implementation.

Ok. I will have a thorough look at the code again and try to implement.

Thanks

Just adding

class PaintPanel extends JPanel implements MouseMotionListener[B], MouseListener[/B] {

and the mouseClicked(), mouseEntered(), and mouseExited() method signatures (empty implementations) will get you a lot further along. The rectangle drag and paint code that you wrote does work. You just missed the additional listener to tie it in. Don't forget to add

addMouseListener(this);

as well, after your other listener registration.

Dear Ezzaral,

Bingo :) Yes it works now. I made the changes that you had suggested. Now the only issue that I am facing is that I want to get the start and end locations as per the original rectangle coordinates (Like in example I have given above 5 and 15). Currently I am just able to print the X and Y coordinates. I need your guidance there. I think one way to solve could be to scale as per the pixels and then retrieve back the values but I am not sure howto do it since never used.......
One more issue that I am facing now is that once I draw a rectangle based on the mouse functions they still remain there and I have no control over them. I want them to erase off once I draw another. Again I am trying on this once.

Here is my code this far which works :)

import java.io.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;

      public class Demo extends JFrame {
              public Color color;
              public int height;
              public int fixvalue1;
              public int fixvalue2;
              public int width;
              public String text;
              
              private JPanel paintPanel;

      public Demo(int height, int fixvalue1, int width, int fixvalue2, Color c,String text) {
        this.color = c;
        this.height = height;
        this.fixvalue1 = fixvalue1;
        this.width = width;
        this.fixvalue2 = fixvalue2;
        this.text = text;

      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setMinimumSize(new Dimension(1000, 200));
      paintPanel = new PaintPanel();
      getContentPane().add(paintPanel, BorderLayout.CENTER);
      pack();
      }
      class PaintPanel extends JPanel implements MouseMotionListener, MouseListener  {
      public List<Glyph> glyphs;
          public int height;
          public int width;
          public String f[];
          private final static int NUM_FIELDS = 4;
          BufferedImage image;
	  Graphics2D g2d;
          Point startPoint = null;
          Point endPoint = null;
          private int xMin;
          private int xMax;
	  private int yMin;
	  private int yMax;
          
      public PaintPanel(){
      super();
      addMouseMotionListener(this);
      addMouseListener(this);
      glyphs = new ArrayList<Glyph>();
              String n = null;  
        try{
            BufferedReader fh = new BufferedReader(new FileReader("InputFile.txt"));    
            while((n = fh.readLine()) != null && (n = n.trim()).length() > 0){

                f = n.split("\t");
                int height = Integer.parseInt(f[0].trim());
                int width = Integer.parseInt(f[1].trim());
                String text = f[3];
                Color color = new Color(Integer.parseInt(f[2]));
                int fixvalue1 = 50;
                int fixvalue2 = 30;

                glyphs.add(new Glyph(height, fixvalue1, width, fixvalue2, color, text));

            }
            fh.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e2) {
            e2.printStackTrace();
        }
      }
      public void paintComponent(Graphics g) {
      super.paintComponent(g);
      for (Glyph glyph : glyphs){
      glyph.draw(g);
      }
      			if (image == null)
			{
				createEmptyImage();
			}

			g.drawImage(image, 0, 0, null);

			//  Paint the Rectangle as the mouse is being dragged

			if (startPoint != null && endPoint != null)
			{
				int x = Math.min(startPoint.x, endPoint.x);
				int y = Math.min(startPoint.y, endPoint.y);
				int width = Math.abs(startPoint.x - endPoint.x);
				int height = Math.abs(startPoint.y - endPoint.y);
				g.drawRect(x, y, width, height);
                                System.out.println(x);
                                System.out.println(y);
// HERE I want to print my positions relative to the original rectangles like 5 and 15 in example I have given at the first.
			}
      }
      		private void createEmptyImage()
		{
			image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
			g2d = (Graphics2D)image.getGraphics();
			g2d.setColor(Color.BLACK);
			g2d.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15);
		}

		public void clear()
		{
			createEmptyImage();
			repaint();
		}
      public void mousePressed(MouseEvent e) {
				startPoint = e.getPoint();
				xMin = startPoint.x;
				xMax = startPoint.x;
				yMin = startPoint.y;
				yMax = startPoint.y;
      } 
      public void mouseDragged(MouseEvent e) {
          			endPoint = e.getPoint();
				xMin = Math.min(xMin, endPoint.x);
				xMax = Math.max(xMax, endPoint.x);
				yMin = Math.min(yMin, endPoint.y);
				yMax = Math.max(yMax, endPoint.y);
				repaint(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1);
      }
      public void mouseReleased(MouseEvent e) {
          			int x = Math.min(startPoint.x, endPoint.x);
				int y = Math.min(startPoint.y, endPoint.y);
				int width = Math.abs(startPoint.x - endPoint.x);
				int height = Math.abs(startPoint.y - endPoint.y);

				g2d.setColor( e.getComponent().getForeground() );
				g2d.drawRect(x, y, width, height);
				startPoint = null;
      }
      public void mouseMoved(MouseEvent e) {
      for(Glyph g : glyphs){
      g.showLabel( g.contains(e.getX(), e.getY()) );
      }
      repaint();
      }
      public void mouseClicked(MouseEvent e) { }
      public void mouseEntered(MouseEvent e) { }
      public void mouseExited(MouseEvent e) { }
      }

      class Glyph {
      private Rectangle bounds;
      private Color color;
      private Paint paint;
      private String label;
      private boolean showLabel = false;
      public Glyph(int x, int y, int width, int height, Color color, String label) {
      bounds = new Rectangle(x, y, width, height);
      this.color = color;
      this.paint = new GradientPaint(x, y, color, x, y+height, Color.WHITE);
      this.label = label;
      }
      public void draw(Graphics g){
      Graphics2D g2 = (Graphics2D)g;
      g2.setPaint(paint);
      g2.fill(bounds);
      if (showLabel){
      g2.setColor(Color.BLACK);
      int labelWidth = g2.getFontMetrics().stringWidth(label);
      int fontHeight = g2.getFontMetrics().getHeight();
      g2.drawString( label,
      (int)(bounds.getX()),
      (int)(bounds.getY()));
      }
      }
      public boolean contains(int x, int y){
      return bounds.contains(x,y);
      }
      public void showLabel(boolean show){
      showLabel = show;
      }
      }
      public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
      new Demo(0, 0, 0, 0, null, null).setVisible(true);
      }
      });
      }
    public Color getColor(){
        return color;
    }

    public String toString() {
        return String.format("Color=%s,top=%d,bottom=%d,width=%d", color.toString(), height, fixvalue1, width, fixvalue2, text);
    }
      }

Need a bit more guidance to crack this one.

Thanks for your kind guidance :)

Ok. I have solved one problem of erasing the previous mouse drawn rectangles using function

g2d.dispose();

inside

public void mouseReleased(MouseEvent e)

Now the ONE problem that is still there is getting the locations as per the original rectangle like 5 and 15 as per the example I have given above in the beginning. I think pixel methodology may be applied but I am not sure how and have never used :(

So do require guidance in this matter ..

Thanks for encouragement.

As I already told in the beginning I want something like this to happen:-

1         10         20        30
##########|##########|##########
  rect 1     rect2      rect3
 
    5 ########### 15
      user rect - (transparent and temporary based on user mousedrag)

That means now I am allowing user to draw rectangle like he uses mouse to draw a rectangle from the middle of rect1 to the middle of rect2. Currently I am just able to print X and Y values of the mouse as per the panel like :- 60 , 20. Whereas I want to get the values of start and end as per the original rectangles as here in this example:- 5 and 15. That's That's why I was thinking of using pixel map or something like that but not sure what to do since i am a beginner and never tried such a thing before.

So I need some guidance here :(

Thanks for all ur help

So you have some object start/end values for each rectangle (not screen x coordinates) that you need to compare against?

If that is the case, you'll need to test for containment of your start point and end point as you did in the mouseMoved() method. Once you know which rectangle contains a point, you can use the ratio of of the user drawn x to the containing rectangle's start and end x coordinates to calculate your "object start" value:

val=10               20
     #################
     #               #           < existing rect
     #################     
x=  30               80

new val= 12
          ###################       < rect drawn  by user
  user x=40
        
new val = val1 + ((userx-x)/(x2-x1) * (val2-val1)) = 10 + ((40-30)/(80-30) * (20-10)) = 12

Repeat for the end point rectangle.

Is that what you're looking for?

Yes I am looking for something like this. Thanks for the example :) I will try to implement now. Let me see how much success I get.
So I am going to work on the code again.

Thanks for kind guidance :)

Let me explain the problem a bit more:-

RectStart    RectEnd	width	color	LabelText   
1	50	50	993	Andrew
51	100	49	399	Peacock
101	143	42	993	John

I am am filling the details like this suppose:-

glyphs.add(new Glyph(RectStart, fixvalue1, width, fixvalue2, color, text));

fixvalue1 = 50
fixvalue2 = 20

both are constant and don't change value throughout the program.

I drawing rectangles side by side: 

1 ######### 50 ########## 51 ########## 101 ######## 143
      *
   user clicks here               * 
                             upto here

I want the value suppose 25 and 75 to be printed. Not X and Y coordinates.

In view of the above I am confused how to fill X / X2 / X1 :(

Getstart = RectStart +((e.getX() - X) / (X2 - X1) * (RectStart - RectEnd) );

Thanks

From your example, the start and end values just look like x values. I don't see where you have any other scale your trying to translate to. You say "not X and Y coordinates" but your example only shows x values and it would appear you are just trying to capture startPoint.x and endPoint.x, with no need for the ratio calculation.

So I don't to calculate ratio in view of the problem that I defined ? So how can I capture them ? Can I do it by just printing out the startPoint.x , endPoint.y. Any example for doing this ?

It sounds like you just want the x postions. Your y positions are fixed. Since you already capture startPoint and endPoint in your mouse listener routines, you have all of the coordinates you need.

But will it give me the values as per my input file like as I already said in the above example :- 25 and 75 in accordance with my input file rectangle start and stop points.

Need your kind guidance in this matter. I feel a bit confused. Even though the problem is clear what I require but howto do it is something that makes me confuse :(

Thanks for all your guidance

Ok I will try to print and see what happens.

May God bless you with more and more knowledge from His treasure of knowledge.
Bingo :) yes that's what I wanted :) :)
I got it..... :)
You are simply amazing :) My guru.
So here it goes. One more solved feather to your cap :)

God Bless Ezzaral.
Web_Sailor

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.