paint program using canvas

A

Andy Cho

Hello all
I'm developing small paint program using canvas class.
But I don't know how retain lines which I draw.
All lines are disapeared when another window is on top of my paint
window.

And how can I control the thickness of lines.

Plaease give me an idea.
Thanks

Andy
 
K

Knute Johnson

Andy said:
Hello all
I'm developing small paint program using canvas class.
But I don't know how retain lines which I draw.
All lines are disapeared when another window is on top of my paint
window.

And how can I control the thickness of lines.

Plaease give me an idea.
Thanks

Andy

import java.awt.*;
import java.awt.event.*;

public class test extends Canvas {
public test() {
setPreferredSize(new Dimension(640,480));
}

public void paint(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;

g.setColor(Color.GREEN);
g.drawLine(10,getHeight()/2,getWidth()-10,getHeight()/2);

g.setColor(Color.RED);
g.setStroke(new BasicStroke(6.0f));
g.drawLine(10,10,getWidth()-10,getHeight()-10);

g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(2.0f));
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}

public static void main(String[] args) {
final Frame f = new Frame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
}
});

test t = new test();
f.add(t,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}
 
J

John B. Matthews

Andy Cho said:
I'm developing small paint program using canvas class. But I don't
know how retain lines which I draw. All lines are disapeared when
another window is on top of my paint window.

Suppose each line has these attributes:

class Line {

Point p1; Point p2; float width;

public Line(Point p1, Point p2, float width) {
this.p1 = p1;
this.p2 = p2;
this.width = width;
}
}

Create a suitable collection of Lines:

List<Line> lines = new ArrayList<Line>();

Each time the user creates a line, add it to the list:

lines.add(new Line(...));

Finally loop through all the lines in your paint() method, drawing each
one:

for (Line line : lines) { ... }
And how can I control the thickness of lines.

See Knute Johnson's example, nearby.
 
A

Andy Cho

Andy said:
Hello all
I'm developing small paint program using canvas class.
But I don't know how retain lines which I draw.
All lines are disapeared when another window is on top of my paint
window.
And how can I control the thickness of lines.
Plaease give me an idea.
Thanks

import java.awt.*;
import java.awt.event.*;

public class test extends Canvas {
public test() {
setPreferredSize(new Dimension(640,480));
}

public void paint(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;

g.setColor(Color.GREEN);
g.drawLine(10,getHeight()/2,getWidth()-10,getHeight()/2);

g.setColor(Color.RED);
g.setStroke(new BasicStroke(6.0f));
g.drawLine(10,10,getWidth()-10,getHeight()-10);

g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(2.0f));
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}

public static void main(String[] args) {
final Frame f = new Frame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
}
});

test t = new test();
f.add(t,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}

}

Thanks Knute
I got an idea of Graphics2D class.
Regards

Andy
 
A

Andy Cho

Suppose each line has these attributes:

    class Line {

        Point p1; Point p2; float width;

        public Line(Point p1, Point p2, float width) {
            this.p1 = p1;
            this.p2 = p2;
            this.width = width;
        }
    }

Create a suitable collection of Lines:

    List<Line> lines = new ArrayList<Line>();

Each time the user creates a line, add it to the list:

    lines.add(new Line(...));

Finally loop through all the lines in your paint() method, drawing each
one:

    for (Line line : lines) { ... }


See Knute Johnson's example, nearby.

Thanks John
I've wrote my own LineData class including coordinates, thickness and
color.
Regards

Andy
 
A

Andy Cho

Andy said:
Hello all
I'm developing small paint program using canvas class.
But I don't know how retain lines which I draw.
All lines are disapeared when another window is on top of my paint
window.
And how can I control the thickness of lines.
Plaease give me an idea.
Thanks

import java.awt.*;
import java.awt.event.*;

public class test extends Canvas {
public test() {
setPreferredSize(new Dimension(640,480));
}

public void paint(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;

g.setColor(Color.GREEN);
g.drawLine(10,getHeight()/2,getWidth()-10,getHeight()/2);

g.setColor(Color.RED);
g.setStroke(new BasicStroke(6.0f));
g.drawLine(10,10,getWidth()-10,getHeight()-10);

g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(2.0f));
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}

public static void main(String[] args) {
final Frame f = new Frame();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
}
});

test t = new test();
f.add(t,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}

}

I meet another problems.
If I dragged mouse faster, lines become discrete.

My code is here,

public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if ( p2 == null || p3 == null ) {
return;
}
g2.setStroke(new BasicStroke(5));
Line2D line = new Line2D.Double(p2.x, p2.y, p3.x, p3.y);
g2.draw(line);
return;
}

Thanks in advance
Andy
 
L

Lew

Knute said:
import java.awt.*;
import java.awt.event.*;

public class test extends Canvas {

Class names should start with an upper-case letter.
public test() {
setPreferredSize(new Dimension(640,480));
}

public void paint(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;

g.setColor(Color.GREEN);
g.drawLine(10,getHeight()/2,getWidth()-10,getHeight()/2);

g.setColor(Color.RED);
g.setStroke(new BasicStroke(6.0f));
g.drawLine(10,10,getWidth()-10,getHeight()-10);

g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(2.0f));
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}

public static void main(String[] args) {
final Frame f = new Frame();

Graphic events should occur only on the EDT.
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
}
});

test t = new test();
f.add(t,BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
}

For the sake of future newsgroup denizens it is best to show good practices,
at least the simple ones.
 
K

Knute Johnson

Lew said:
Knute said:
import java.awt.*;
import java.awt.event.*;

public class test extends Canvas {

Class names should start with an upper-case letter.
public test() {
setPreferredSize(new Dimension(640,480));
}

public void paint(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;

g.setColor(Color.GREEN);
g.drawLine(10,getHeight()/2,getWidth()-10,getHeight()/2);

g.setColor(Color.RED);
g.setStroke(new BasicStroke(6.0f));
g.drawLine(10,10,getWidth()-10,getHeight()-10);

g.setColor(Color.BLUE);
g.setStroke(new BasicStroke(2.0f));
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}

public static void main(String[] args) {
final Frame f = new Frame();

Graphic events should occur only on the EDT.

Swing yes, AWT not necessary.
For the sake of future newsgroup denizens it is best to show good
practices, at least the simple ones.
 
L

Lew

Knute said:
Swing yes, AWT not necessary.

Are you sure about that?

We went through this with AWT. AWT was initially exposed as a normal
multi-threaded Java library. But as the Java team looked at the experience
with AWT and with the deadlocks and races that people had encountered, we
began to realize that we were making a promise we couldn't keep.

Note also that the events dispatched on the "Swing" Event Dispatch Thread are
all AWT events. In fact, Swing is itself built on AWT.

I'm not saying you're wrong. I'm just curious how AWT is immune to a
phenomenon that seems to grip every other GUI invented, for Java or otherwise.

And why do Sun engineers say that AWT cannot keep the multithreaded promise?
 
K

Knute Johnson

Lew said:
Are you sure about that?



Note also that the events dispatched on the "Swing" Event Dispatch
Thread are all AWT events. In fact, Swing is itself built on AWT.

I'm not saying you're wrong. I'm just curious how AWT is immune to a
phenomenon that seems to grip every other GUI invented, for Java or
otherwise.

And why do Sun engineers say that AWT cannot keep the multithreaded
promise?

I've yet to see Sun recommend that you keep all AWT GUI actions on the
EDT like they do for Swing. It's possible I've missed it somewhere though.
 
J

Joshua Cranmer

Lew said:
I'm not saying you're wrong. I'm just curious how AWT is immune to a
phenomenon that seems to grip every other GUI invented, for Java or
otherwise.

Judging from a brief glance at some of the AWT code, the AWT does a lot
more synchronization (java.awt.List has 33 instances of synchronized,
whereas javax.swing.JList has 0 [1]). At the very least, it can be used
in a multithreaded manner--simple operations would not need to be
proxied to work correctly.

Or perhaps a more correct answer is that Sun more or less abandoned the
AWT and have not bothered to recommend that people keep to the EDT.
And why do Sun engineers say that AWT cannot keep the multithreaded
promise?

Well, multithreaded programming is insanely hard. I have to imagine that
they judged that ensuring correct functionality without the negative
side-effects of multithreading was too difficult compared to using an
event queue model.

[1] But both use Vector, which is of course a synchronized collection.
 
L

Lew

Joshua said:
Well, multithreaded programming is insanely hard. I have to imagine that
they judged that ensuring correct functionality without the negative
side-effects of multithreading was too difficult compared to using an
event queue model.

Doesn't that mean that AWT code (and why not use Swing, BTW?) needs to keep
GUI stuff on the EDT, too?
 
A

Andy Cho

Doesn't that mean that AWT code (and why not use Swing, BTW?) needs to keep
GUI stuff on the EDT, too?

Thanks Knute,John and all.
I looked into my code, from John's comment.

I found the reason.

This is my code after correcting error,
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if ( p2 == null || p3 == null ) {
return;
}
g2.setStroke(new BasicStroke(5));
Line2D line = new Line2D.Double(p2.x, p2.y, p3.x, p3.y);
g2.draw(line);
p2 = p3; // <- moved
return;
}

@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub

System.out.println("Mouse Dragged button : " + e.getPoint().getX() +
"," + e.getPoint().getY());

p3 = e.getPoint();
repaint();
// p2 = p3; <- removed
}

I moved line "p2=p3;" to paint method from mouseDragged method.
It seems that the problem was from GUI threading.

Thanks all.
Regards

Andy
 
R

Roedy Green

I'm developing small paint program using canvas class.
But I don't know how retain lines which I draw.
All lines are disapeared when another window is on top of my paint
window.

You must retain them is some sort of Collection. You might retain the
end points of each line, or just retain an list of things to draw, and
redraw from the raw data each time.

You want to be clever and only bother drawing stuff that overlaps the
clip region.

For thick lines, draw filled rectangles. You won't get pretty mitres
that way though.

See http://mindprod.com/jgloss/canvas.html
for some basics.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur."
~ Red Adair (born: 1915-06-18 died: 2004-08-07 at age: 89)
 
R

Roedy Green

I've yet to see Sun recommend that you keep all AWT GUI actions on the
EDT like they do for Swing. It's possible I've missed it somewhere though.

They did not originally, but IIRC they now recommend the same sort of
practices as for Swing.

It gives you belt and suspenders.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"If you think it’s expensive to hire a professional to do the job, wait until you hire an amateur."
~ Red Adair (born: 1915-06-18 died: 2004-08-07 at age: 89)
 
K

Knute Johnson

Roedy said:
They did not originally, but IIRC they now recommend the same sort of
practices as for Swing.

It gives you belt and suspenders.

Can you point me to a document?

Thanks,
 
R

Roedy Green

Can you point me to a document?

Sorry, it was too long ago I stumbled on it.

It probably would have been in some documentation on the AWT threads.

It could have been in Frame docs, or a discussion about how to launch
a GUI app.

It is a fuzzy memory. The gist of it was they seemed to be treating
AWT more and more like Swing, probably because of rarely occurring
thread problems. I recall thinking -- AWT is probably too complicated
to find and nail down all these bugs, so they are now just
recommending more conservative use of it.

There was an odd sentence of the form, AWT will probably work fine
without these precautions, but if you have trouble here is what to do.
I got the impression, simple apps were safe, but complicated ones were
note, where simple/complicated was to be determined by experiment.

The stuff I have done in AWT is I think all single thread. All my
multi-thread stuff is Swing using invokeLater.
 
J

John B. Matthews

Roedy Green said:
Sorry, it was too long ago I stumbled on it.

It probably would have been in some documentation on the AWT threads.

It could have been in Frame docs, or a discussion about how to launch
a GUI app.

It is a fuzzy memory. The gist of it was they seemed to be treating
AWT more and more like Swing, probably because of rarely occurring
thread problems. I recall thinking -- AWT is probably too complicated
to find and nail down all these bugs, so they are now just
recommending more conservative use of it.

There was an odd sentence of the form, AWT will probably work fine
without these precautions, but if you have trouble here is what to do.
I got the impression, simple apps were safe, but complicated ones were
note, where simple/complicated was to be determined by experiment.

The stuff I have done in AWT is I think all single thread. All my
multi-thread stuff is Swing using invokeLater.

Here's a short bibliography; top-level entries link to subheads:

A<http://java.sun.com/javase/6/docs/api/java/awt/Component.html>
A1<http://java.sun.com/products/jfc/tsc/articles/painting/index.html>
A2<http://java.sun.com/javase/6/docs/api/java/awt/doc-files/
AWTThreadIssues.html>
A3<http://java.sun.com/products/jfc/tsc/articles/threads/
threads1.html>

B<http://java.sun.com/docs/books/tutorial/uiswing/concurrency/
initial.html>
B1<http://weblogs.java.net/blog/kgh/archive/2004/10/
multithreaded_t.html>
 
K

Knute Johnson

John said:

This page has a demo that does not do GUI creation on the EDT.

Same here.

None of these actually come out and say that you need to use the EDT for
AWT GUIs as you must for Swing. And a couple actually show examples
without using the EDT.

I haven't created any really large AWT projects because Swing is much
prettier, so I've never seen any problems with AWT.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,998
Messages
2,570,242
Members
46,834
Latest member
vina0631

Latest Threads

Top