Reputation: 572
I am making a molecule designing application. I can draw the lines and circles, but it clears the old lines each time you click, so basically, you can only design molecules with 2 atoms. Also, the mouseEvents don't deliver if you click very fast which is also a problem. Here is the code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class MoleculeDesigner extends JComponent implements MouseListener {
private Point op, cp;
private boolean first = true;
public static final Color linecolor = new Color(0, 255, 0);
private static final long serialVersionUID = 1L;
private BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
public MoleculeDesigner() {
JFrame f = new JFrame("Molecule Designer");
f.setBackground(Color.WHITE);
f.addMouseListener(this);
f.add(this);
f.setSize(100, 100);
f.setDefaultCloseOperation(3);
f.setVisible(true);
}
public static void main(String[] args) {
new MoleculeDesigner();
}
@Override
protected void paintComponent(Graphics g) {
if(op != null && cp != null) {
Graphics2D g2 = img.createGraphics();
super.paintComponent(g2);
g2.setColor(linecolor);
g2.drawLine((int) op.getX(), (int) op.getY(), (int) cp.getX(), (int) cp.getY());
g2.setColor(Color.BLACK);
g2.fillOval((int) cp.getX(), (int) cp.getY(), 10, 10);
op = (Point) cp.clone();
g2.dispose();
}
}
@Override
public Dimension getPreferredSize() {
return getParent().getMaximumSize();
}
@Override
public void mouseClicked(MouseEvent e) {
if(!first) {
cp = e.getPoint();
cp.setLocation(cp.getX(), cp.getY() - 8);
}
else {
op = e.getPoint();
first = false;
}
repaint();
}
@Override public void mousePressed(MouseEvent e) {}
@Override public void mouseReleased(MouseEvent e) {}
@Override public void mouseEntered(MouseEvent e) {}
@Override public void mouseExited(MouseEvent e) {}
}
All help appreciated!
Upvotes: 3
Views: 561
Reputation: 285405
Either 1) draw in a BufferedImage which is then displayed inside of your paintComponent
override, or 2) put your data into an ArrayList or other collection, and then iterate through the collection inside of paintComponent
. I'd do the latter if I needed the data for other purposes. Also, never ever do this:
public void update(Graphics g) {
paintComponent(g);
}
This is not how Swing graphics are supposed to be done and is potentially dangerous code. Please read:
Edit
More detail regarding option 1:
getGraphics()
or createGrahpics()
(for a Graphics2D object)dispose()
the Graphics object.repaint()
to ask the JVM to repaint the component.paintComponent
method by calling g.drawImage(...)
, passing in your buffered image.Benefits: often the drawing is quicker, and I often use this to draw background images.
Drawbacks: the data points are not available, and so if you need to do manipulation or animation of your data points, this is not the way to go.
Upvotes: 4
Reputation: 347184
You don't, nor should you.
paint
in Swing is a destructive process, this is the way it was designed. That is, there is an expectation that when you component is requested to paint itself, it will clean up the Graphics
context before painting anything (this is slightly different for transparent components though).
Swing has no concept of what was painted on your component before and because the Graphics
context is shared amongst all the components been painted, unless you clear the graphics first, you could end up with unwanted paint artifacts
Possible solutions might include...
BufferedImage
), which you use the paintComponent
method to draw. This is limited in the fact that it just acts like a paint program, painting pixels to the image. You will also need to provide functionality when the size of the viewable area changes, as the BufferedImage
won't know.List
and iterate this list when paintComponent
is called. This is a little more flexible in that you can control the order of the objects drawn, remove objects and insert new ones where you likeUpvotes: 3