I have to use the Console class in HoltSoft's Ready to Program. I'm not supposed to use swing, so if I can't do it without swing, kindly ignore this.
//imports
import java.awt.*;
import java.awt.event.*;
import hsa.*;
public class DrawLines extends Panel implements MouseListener, MouseMotionListener
{
Console c;
int startX, startY, prevX, prevY; //mouse coordinates
private boolean dragging; //whether or not the mouse is being dragged
MouseEvent e;
public DrawLines ()
{
c = new Console (); //creates console window
addMouseListener (this); //detects press/release
addMouseMotionListener (this);//detects dragging
}
public void mousePressed (MouseEvent e)
{
while (!dragging)
{
try
{
startX = e.getX ();//get the
startY = e.getY ();//original co-ordinates
dragging = true;
}
catch (NullPointerException q) //because I kept getting this error
{
}
}
}
public void mouseDragged (MouseEvent e)
{
while (dragging)
{
try
{
int x = e.getX (); //gets and
int y = e.getY (); //updates
prevX = x; //the mouse
prevY = y; //coordinates
}
catch (NullPointerException q)//because I kept getting this error
{
}
}
}
public void mouseReleased (MouseEvent e)
{
dragging = false; //stopped dragging
}
public void drawTheLine ()
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is
mouseReleased (e);
}
public void mouseMoved (MouseEvent e){}
public void mouseEntered (MouseEvent e){}
public void mouseExited (MouseEvent e){}
public void mouseClicked (MouseEvent e){}
public static void main (String[] args)
{
DrawLines a = new DrawLines ();
a.drawTheLine ();
}
}
I've been trying to use MouseListener and MouseMotionListener in Console. At first, the program kept giving me errors, so I added the try/catch structures. Now it doesn't crash, but nothing appears on the screen. Why? Help?
If I shouldn't use try/catch to just ignore it, what should I do?
I'm not allowed to use anything other than Console() for this program. It's a course assignment.
Look at this:
public void drawTheLine ()
{
while (true)
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50); //draws a circle where the mouse is
mouseReleased (e);
}
}
The parameter "e" you're passing is null. It is declared here:
public class DrawLines extends Panel
implements MouseListener, MouseMotionListener
{
MouseEvent e; // IT IS NEVER SET TO ANYTHING! IT IS NULL!!!
Somewhere in your constructor you should do this so it's no longer null:
e = (something);
Swing is an event driven system and is a single threaded system.
This means that your application "waits" for events to occur (which is taken care for you by the Event Dispatching Thread) and that anyone that blocks the EDT, like, loops, long running processes or blocking IO, will prevent you application from receiving notification of those events, making impossible for you application to run.
So, if we have a look at this...
while (true)
{
mousePressed (e);
mouseDragged (e);
c.setColor (Color.black);
c.fillOval (prevX, prevY, 50, 50);
mouseReleased (e);
}
}
It suggest that...one, you don't understand how events are generated in Swing and two, how the EDT actually works.
Unlike some UI frameworks, you are not required to implement a event loop, this is taken care of you by Swing. Blocking the EDT like this, will prevent it for processing events
Instead, remove the drawLineMethod as it is doing absolute nothing for you and replace you main method with something like...
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawLines());
// I prefer pack, but you've not specified a preferred size for your panel...
//frame.pack();
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
Now. I have no idea what the Console class is or does, but in your mouse event methods, you will need to update it so that it can update it's output...
Updated with example
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DrawPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawPane extends JPanel {
private Point center;
private int radius;
public DrawPane() {
MouseAdapter handler = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
center = e.getPoint();
radius = 0;
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
radius = Math.max(width, height);
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (center != null) {
g.setColor(Color.RED);
g.fillOval(center.x - 2, center.y - 2, 4, 4);
g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);
}
}
}
}
I would suggest that you take the time to have a read through...
Creating a GUI with Swing to get an understanding of the overall basics of Swing
Performing Custom Painting to get an understanding of how custom painting is actually performed in Swing
Painting in AWT and Swing as all developers wishing to perform custom painting in Swing need to understand how this works...
Update with a pure AWT version
As it was pointed out to me that the OP was using AWT instead of Swing, why, cause they seem to be able to ...
public class DrawCircleAWT {
public static void main(String[] args) {
new DrawCircleAWT();
}
public DrawCircleAWT() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Frame frame = new Frame("Testing");
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setLayout(new BorderLayout());
frame.add(new DrawPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawPane extends Panel {
private Point center;
private int radius;
public DrawPane() {
MouseAdapter handler = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
center = e.getPoint();
radius = 0;
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
int width = Math.max(e.getX(), center.x) - Math.min(e.getX(), center.x);
int height = Math.max(e.getY(), center.y) - Math.min(e.getY(), center.y);
radius = Math.max(width, height);
repaint();
}
};
addMouseListener(handler);
addMouseMotionListener(handler);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (center != null) {
g.setColor(Color.RED);
g.fillOval(center.x - 2, center.y - 2, 4, 4);
g.drawOval(center.x - (radius / 2), center.y - (radius / 2), radius, radius);
}
}
}
}
Related
When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?
Below is the what I have currently tried:
public final class TestFrame extends JFrame {
public TestFrame() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
// These methods do not appear to be called at all when a JFrame
// is being resized.
#Override
public void setSize(int width, int height) {
System.out.println("setSize");
}
#Override
public void setBounds(Rectangle r) {
System.out.println("setBounds A");
}
#Override
public void setBounds(int x, int y, int width, int height) {
System.out.println("setBounds B");
}
}
How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?
You can add a component listener and implement the componentResized function like that:
JFrame component = new JFrame("My Frame");
component.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
//........
}
});
EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.
One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.
I know, this isn't the most elegant solution, but it works!
Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:
public final class TestFrame extends JFrame {
public TestFrame() {
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
}
Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.
You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.
public class MouseDrag extends Component implements MouseListener,
MouseMotionListener {
/** The Image we are to paint */
Image curImage;
/** Kludge for showStatus */
static Label status;
/** true if we are in drag */
boolean inDrag = false;
/** starting location of a drag */
int startX = -1, startY = -1;
/** current location of a drag */
int curX = -1, curY = -1;
// "main" method
public static void main(String[] av) {
JFrame f = new JFrame("Mouse Dragger");
Container cp = f.getContentPane();
if (av.length < 1) {
System.err.println("Usage: MouseDrag imagefile");
System.exit(1);
}
Image im = Toolkit.getDefaultToolkit().getImage(av[0]);
// create a MouseDrag object
MouseDrag j = new MouseDrag(im);
cp.setLayout(new BorderLayout());
cp.add(BorderLayout.NORTH, new Label(
"Hello, and welcome to the world of Java"));
cp.add(BorderLayout.CENTER, j);
cp.add(BorderLayout.SOUTH, status = new Label());
status.setSize(f.getSize().width, status.getSize().height);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// "Constructor" - creates the object
public MouseDrag(Image i) {
super();
curImage = i;
setSize(300, 200);
addMouseListener(this);
addMouseMotionListener(this);
}
public void showStatus(String s) {
status.setText(s);
}
// Five methods from MouseListener:
/** Called when the mouse has been clicked on a component. */
public void mouseClicked(MouseEvent e) {
}
/** Called when the mouse enters a component. */
public void mouseEntered(MouseEvent e) {
}
/** Called when the mouse exits a component. */
public void mouseExited(MouseEvent e) {
}
// And two methods from MouseMotionListener:
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
// System.err.println("mouse drag to " + p);
showStatus("mouse Dragged to " + p);
curX = p.x;
curY = p.y;
if (inDrag) {
repaint();
}
}
public void paint(Graphics g) {
int w = curX - startX, h = curY - startY;
Dimension d = getSize();
g.drawImage(curImage, 0, 0, d.width, d.height, this);
if (startX < 0 || startY < 0)
return;
System.err.println("paint:drawRect #[" + startX + "," + startY
+ "] size " + w + "x" + h);
g.setColor(Color.red);
g.fillRect(startX, startY, w, h);
}
}
I want the coordinates from the Mouse class to go to the Paint class in the paint method. And that the square moved with the movement of the mouse. But the coordinates are not transmitted.
g.drawRect(mouse.getX(), mouse.getY(), 10, 10);
mouse.getX(), mouse.getY() starts only at the beginning. and after does not change.
Class Draw Points
public class DrawPoints
{
Frame f;
KeyBoard key;
Mouse mouse;
Paint c;
public void GUI()
{
f = new Frame("DrawPoints");
f.setSize(300, 300);
mouse = new Mouse(); // edit
c = new Paint(mouse); // edit
c.setSize(300, 300);
c.setBackground(Color.WHITE);
c.addMouseListener(mouse);
c.addMouseMotionListener(mouse);
key = new KeyBoard();
c.addKeyListener(key);
f.add(c);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
Class Paint
class Paint extends Canvas
{
Mouse mouse; // edit
public Paint() // added
{
mouse = new Mouse();
}
#Override
public void paint(Graphics g)
{
g.drawRect(mouse.getX(), mouse.getY(), 10, 10);
repaint(); // added
}
}
Class Mouse
class Mouse implements MouseListener, MouseMotionListener
{
private int x;
private int y;
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
// MouseMotionListener
#Override
public void mouseMoved(MouseEvent e)
{
x = e.getX();
y = e.getY();
//System.out.println(e.getX() + " " + e.getY());
}
#Override
public void mouseDragged(MouseEvent e)
{
System.out.println("mouseDragged");
}
I dont know the other classes but i think problem is you are created different mouse objects. Move your new Mouse() to before new Paint() and change new Paint to Paint(mouse).
DrawPoints class:
public class DrawPoints
{
Frame f;
KeyBoard key;
Mouse mouse;
Paint c;
public void GUI()
{
f = new Frame("DrawPoints");
f.setSize(300, 300);
mouse = new Mouse();
c = new Paint(mouse);
c.setSize(300, 300);
c.setBackground(Color.WHITE);
c.addMouseListener(mouse);
c.addMouseMotionListener(mouse);
key = new KeyBoard();
c.addKeyListener(key);
f.add(c);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}}
Paint class: Change Paint() to Paint(Mouse mouse) and new Mouses() line to this.mouse = mouse;
class Paint extends Canvas
{
Mouse mouse;
public Paint(Mouse mouse)
{
this.mouse = mouse;
}
#Override
public void paint(Graphics g)
{
g.drawRect(mouse.getX(), mouse.getY(), 10, 10);
}
}
Forgetting the fact that you shouldn't be coding using the AWT library as this GUI library is over 20 yrs out of date, this is not how you do event-driven programming, since you need to notify the program of changes in mouse state, something that your code doesn't do. Your mouse listener methods need to change x, and y properties within your drawing Paint object, and then call repaint() on that same object.
I am only posting the relevant code. I am fairly new to java and right now I am building a program that will allow the user to use a draw method. However, when I click the button for drawing in the interface, it automatically generates a random line anywhere on the page and does not allow user interaction. I think the error is occurring in my mouseListener method, but I am not sure as this is my first time doing anything like this. Any help would be greatly appreciated. Thank you!
Also, the error that prints out is: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
public class SimplePaint extends JFrame {
JButton drawing = new JButton();
Line2D draw = new Line2D.Float();
Point start = null;
Point end = null;
public SimplePaint() {
JPanel panel = new JPanel() {
{
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
start = e.getPoint();
}
public void mouseReleased(MouseEvent e) {
start = e.getPoint();
//start = null;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
end = e.getPoint();
}
public void mouseDragged(MouseEvent e) {
end = e.getPoint();
repaint();
}
});
}
};
drawing.setText("Draw");
panel.add(drawing);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == drawing) {
draw = new Line2D.Float(start.x, start.y, end.x, end.y);
}
repaint();
}
};
drawing.addActionListener(actionListener);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
Line2D line = new Line2D.Float(0, 250, 2000, 300);
g2.draw(draw);
}
}
I have a panel which contains custom components that have been added to it. It paints correctly except when the components (which have their own mouselisteners) are being dragged it starts to paint weirdly.
Interestingly if I slightly re-size the parent panel it will now paint as intended. I know that the parent panel is being repainted through
super.paintComponent(g);
and a print statement inside the panels
paintComponent(Graphics g):
method. I tried revalidating when the component is dragged around (as the component is having its bounds re-set) it becomes invalidated. Still I am having no success and was wondering if anyone could help.
Is there some place where i am not repainting correctly that might be causing this behavior?
Also as an addendum I have a mouse listener on both the panel and its components, is there a way so that when a component is clicked the panel mouse listener also responds (beyond going back up to the parent class from the component)
Here is a working example of the issue I am having
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;
public class testHome {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
testHome window = new testHome();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public testHome() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new myPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
}
class myPanel extends JPanel {
MyComponent comp;
public myPanel() {
super(null);
comp = new MyComponent(5, 5);
this.add(comp);
revalidate();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
Line2D.Double line = new Line2D.Double(10, 10, comp.getX(), comp.getY());
System.out.println(comp.getX() + " " + comp.getY());
g2d.draw(line);
}
}
class MyComponent extends JComponent implements MouseListener, MouseMotionListener {
int x;
int y;
int mx;
int my;
public MyComponent(int x, int y) {
this.setVisible(true);
this.setBounds(x, y, 15, 15);
this.x = x;
this.y = y;
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
g2d.fillRect(this.x, this.y, 15, 15);
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println("dragging");
int dx = e.getX() - mx;
int dy = e.getY() - my;
this.setBounds(this.getX() + dx, this.getY() + dy, 15, 15);
}
#Override
public void mousePressed(MouseEvent e) {
mx = e.getX();
my = e.getY();
}
#Override
public void mouseMoved(MouseEvent e) {}
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
}
The parent panel does not actually get automatically repainted completely. paintComponent() is called, but if you check the clipping, for example by:
System.out.println(g.getClipBounds());
you'll see that only the area below the smaller component is painted. (The component is not opaque, so the parent component needs to paint the area below it). You need to call repaint() explicitly for the parent panel:
getParent().repaint();
(Or using the repaint() variants that specify the region, if the parent component is expensive to draw and can optimize partial draws).
When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?
Below is the what I have currently tried:
public final class TestFrame extends JFrame {
public TestFrame() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
// These methods do not appear to be called at all when a JFrame
// is being resized.
#Override
public void setSize(int width, int height) {
System.out.println("setSize");
}
#Override
public void setBounds(Rectangle r) {
System.out.println("setBounds A");
}
#Override
public void setBounds(int x, int y, int width, int height) {
System.out.println("setBounds B");
}
}
How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?
You can add a component listener and implement the componentResized function like that:
JFrame component = new JFrame("My Frame");
component.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
//........
}
});
EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.
One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.
I know, this isn't the most elegant solution, but it works!
Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:
public final class TestFrame extends JFrame {
public TestFrame() {
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
}
Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.
You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.
public class MouseDrag extends Component implements MouseListener,
MouseMotionListener {
/** The Image we are to paint */
Image curImage;
/** Kludge for showStatus */
static Label status;
/** true if we are in drag */
boolean inDrag = false;
/** starting location of a drag */
int startX = -1, startY = -1;
/** current location of a drag */
int curX = -1, curY = -1;
// "main" method
public static void main(String[] av) {
JFrame f = new JFrame("Mouse Dragger");
Container cp = f.getContentPane();
if (av.length < 1) {
System.err.println("Usage: MouseDrag imagefile");
System.exit(1);
}
Image im = Toolkit.getDefaultToolkit().getImage(av[0]);
// create a MouseDrag object
MouseDrag j = new MouseDrag(im);
cp.setLayout(new BorderLayout());
cp.add(BorderLayout.NORTH, new Label(
"Hello, and welcome to the world of Java"));
cp.add(BorderLayout.CENTER, j);
cp.add(BorderLayout.SOUTH, status = new Label());
status.setSize(f.getSize().width, status.getSize().height);
f.pack();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// "Constructor" - creates the object
public MouseDrag(Image i) {
super();
curImage = i;
setSize(300, 200);
addMouseListener(this);
addMouseMotionListener(this);
}
public void showStatus(String s) {
status.setText(s);
}
// Five methods from MouseListener:
/** Called when the mouse has been clicked on a component. */
public void mouseClicked(MouseEvent e) {
}
/** Called when the mouse enters a component. */
public void mouseEntered(MouseEvent e) {
}
/** Called when the mouse exits a component. */
public void mouseExited(MouseEvent e) {
}
// And two methods from MouseMotionListener:
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
// System.err.println("mouse drag to " + p);
showStatus("mouse Dragged to " + p);
curX = p.x;
curY = p.y;
if (inDrag) {
repaint();
}
}
public void paint(Graphics g) {
int w = curX - startX, h = curY - startY;
Dimension d = getSize();
g.drawImage(curImage, 0, 0, d.width, d.height, this);
if (startX < 0 || startY < 0)
return;
System.err.println("paint:drawRect #[" + startX + "," + startY
+ "] size " + w + "x" + h);
g.setColor(Color.red);
g.fillRect(startX, startY, w, h);
}
}