我做了一个绘画应用程序。并需要你的帮助来解决问题。如您所见,此代码在调用paint事件时反复绘制形状。当形状很多时,预览矩形特征变得缓慢且不能平稳地工作。有没有办法只在鼠标按下和释放时绘制形状?当我尝试鼠标拖动时,形状开始消失,并在鼠标释放时出现。
这是基本代码:
private class drawer extends JComponent{
ArrayList<Shape> shapes = new ArrayList<Shape>();
ArrayList<Color> fillcolo = new ArrayList<Color>();
ArrayList<Color> strokecolo = new ArrayList<Color>();
Point drawst, drawend;
public drawer(){
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
drawst = new Point(e.getX(), e.getY());
drawend = drawst;
if(currentaction == 0){
ArrayList<Shape> availables = new ArrayList<Shape>();
for(Shape s : shapes){
if(s.contains(drawst)){
availables.add(s);
}
}
if(!availables.isEmpty()){
int tmpindex = shapes.indexOf(availables.get(availables.size() -1));
shapes.remove(tmpindex);
fillcolo.remove(tmpindex);
strokecolo.remove(tmpindex);
}
}
flowthrough = true;
repaint();
}
public void mouseReleased(MouseEvent e){
switch (currentaction){
case 0:
break;
case 1:
break;
case 4:
Shape shape01 = drawellipse(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape01);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
case 3:
Shape shape = drawrect(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
}
drawst = null; drawend = null;
flowthrough = true;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
drawend = new Point(e.getX(), e.getY());
repaint();
}
}
);
}
public void paint(Graphics g){
Graphics2D graph = (Graphics2D)g;
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
graph.setStroke(new BasicStroke(2));
if(flowthrough){
Iterator<Color> strokecounter = strokecolo.iterator();
Iterator<Color> fillcounter = fillcolo.iterator();
for(Shape s : shapes){
graph.setPaint(strokecounter.next());
graph.draw(s);
graph.setPaint(fillcounter.next());
graph.fill(s);
}
}
if(drawst != null && drawend != null){
switch (currentaction){
case 4:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape bshape = drawellipse(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(bshape);
break;
case 3:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape ashape = drawrect(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(ashape);
break;
}
}
}
private Rectangle2D.Float drawrect(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1-x2);
int height = Math.abs(y1-y2);
return new Rectangle2D.Float(x,y,width,height);
}
private Ellipse2D.Float drawellipse(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1 - x2);
int height = Math.abs(y1 - y2);
return new Ellipse2D.Float(x,y,width,height);
}
}
这是完整代码(我将其最小化了一点):
public class Basics extends JFrame {
JButton brushbut, shapebut, linebut, strokecolbut, fillcolbut;
int currentaction = 1;
int strokesize = 2;
boolean flowthrough = false;
Color strokecol = Color.black, fillcol = Color.darkGray;
public Basics(){
this.setBounds(new Rectangle(50,50,1000,600));
this.setTitle("Dandle");
JPanel buttonpanel = new JPanel();
Box thebox = Box.createHorizontalBox();
brushbut = makebutton("/home/kamal/Pictures/brushicon(sized).png", 4);
shapebut = makebutton("/home/kamal/Pictures/shapeicon(sized).png", 3);
linebut = makebutton("/home/kamal/Pictures/vector-path-lineicon(sized).png",0);
strokecolbut = makebutton("/home/kamal/Pictures/strokecolor(sized).png", true);
fillcolbut = makebutton("/home/kamal/Pictures/fill-coloricon(sized).png", false);
thebox.add(brushbut);
........
buttonpanel.add(thebox);
this.add(buttonpanel, BorderLayout.SOUTH);
this.add(new drawer(), BorderLayout.CENTER);
}
private JButton makebutton(String icon, final int num){
JButton thebut = new JButton();
........
thebut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
currentaction = num;
}
});
return thebut;
}
private JButton makebutton(String icon, final boolean stroke){
JButton thebut = new JButton();
thebut.setIcon(new ImageIcon(icon));
thebut.setSize(50,50);
thebut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
if(stroke) strokecol = JColorChooser.showDialog(null, "Pick a stroke", strokecol);
..........
}
});
return thebut;
}
public static void main(String[] args){
new Basics().setVisible(true);
}
private class drawer extends JComponent{
ArrayList<Shape> shapes = new ArrayList<Shape>();
ArrayList<Color> fillcolo = new ArrayList<Color>();
ArrayList<Color> strokecolo = new ArrayList<Color>();
Point drawst, drawend;
public drawer(){
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
drawst = new Point(e.getX(), e.getY());
drawend = drawst;
if(currentaction == 0){
ArrayList<Shape> availables = new ArrayList<Shape>();
for(Shape s : shapes){
if(s.contains(drawst)){
availables.add(s);
}
}
if(!availables.isEmpty()){
int tmpindex = shapes.indexOf(availables.get(availables.size() -1));
shapes.remove(tmpindex);
fillcolo.remove(tmpindex);
strokecolo.remove(tmpindex);
}
}
flowthrough = true;
repaint();
}
public void mouseReleased(MouseEvent e){
switch (currentaction){
case 0:
break;
case 1:
break;
case 4:
Shape shape01 = drawellipse(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape01);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
case 3:
Shape shape = drawrect(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
}
drawst = null; drawend = null;
flowthrough = true;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
drawend = new Point(e.getX(), e.getY());
repaint();
}
}
);
}
public void paint(Graphics g){
Graphics2D graph = (Graphics2D)g;
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
graph.setStroke(new BasicStroke(2));
if(flowthrough){
Iterator<Color> strokecounter = strokecolo.iterator();
Iterator<Color> fillcounter = fillcolo.iterator();
for(Shape s : shapes){
graph.setPaint(strokecounter.next());
graph.draw(s);
graph.setPaint(fillcounter.next());
graph.fill(s);
}
}
if(drawst != null && drawend != null){
switch (currentaction){
case 4:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape bshape = drawellipse(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(bshape);
break;
case 3:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape ashape = drawrect(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(ashape);
break;
}
}
}
private Rectangle2D.Float drawrect(int x1, int y1, int x2, int y2){
..........
return new Rectangle2D.Float(x,y,width,height);
}
private Ellipse2D.Float drawellipse(int x1, int y1, int x2, int y2){
..........
return new Ellipse2D.Float(x,y,width,height);
}
}
}