【问题标题】:java graphics - cannot save shapes drawnjava图形 - 无法保存绘制的形状
【发布时间】:2017-07-25 15:58:14
【问题描述】:

我有一个我一直在编写的 Java 应用程序,它是一个可以让我绘制矩形等形状的应用程序。我的应用程序可以绘制形状,但我无法保存它们,因为当我尝试绘制新形状并单击其他位置时,先前绘制的形状消失并被新形状取代。我尝试使用数组列表来保存我的形状,但它不起作用。

这是我的代码:

    public class Toile extends JPanel {

    Vector<Forme> forme = new Vector<Forme>();
    private Color couleur;
    private int x;
    private int y;
    private int x2;
    private int y2;
    private Oval oval;
    private Rectangl rect;


    public Toile(){
    initComponents();
    }

    public void initComponents(){
   addMouseListener(new java.awt.event.MouseAdapter() { 
   public void mousePressed(java.awt.event.MouseEvent evt) { 
    formMousePressed(evt); } 
     public void mouseReleased(java.awt.event.MouseEvent evt) { 
    formMouseReleased(evt); } }); 
   addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { 
      public void mouseDragged(java.awt.event.MouseEvent evt) { 
    formMouseDragged(evt); } });
    }
    public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.setColor(couleur);
    drawfillRect(g, x, y, x2, y2);
    }


    public void setStartPoint(int x, int y) {
    this.x = x;
    this.y = y;
    }

    public void setEndPoint(int x, int y) {
    x2 = (x);
    y2 = (y);
    }

    public void drawfillRect(Graphics g, int x, int y, int x2, int y2) {
        int px = Math.min(x,x2);
        int py = Math.min(y,y2);
        int pw=Math.abs(x-x2);
        int ph=Math.abs(y-y2);
        //g.fillRect(px, py, pw, ph);
        Rectangl rect = new Rectangl(px,y,x2,py,pw,ph,couleur,true);
        rect.dessinerfrect(g);
        forme.add(rect);
      }
 }

       private void formMousePressed(java.awt.event.MouseEvent evt) { 
       setStartPoint(evt.getX(), evt.getY());
      repaint(); 
       }

      private void formMouseReleased(java.awt.event.MouseEvent evt) {{
      setEndPoint(evt.getX(), evt.getY());
      repaint(); 
      //dessiner(this.getGraphics());
      }
      }

      private void formMouseDragged(java.awt.event.MouseEvent evt){{
      setEndPoint(evt.getX(), evt.getY());
      repaint(); 
      //dessiner(this.getGraphics()); 
      }
      }

正如你所看到的,这是绘制的类,将要绘制的矩形是我创建的类中的一个对象,这个类是超类 Forme 的子类。正如我之前所说,应用程序可以绘制形状,但绘制的形状不会被保存。此外,我从我的帖子中删除了 getter 和 setter,因为我只想保留必要的内容,并且我想让我的帖子更清晰。

这是 Rectangl 类:

  public class Rectangl extends Forme {
  private int largeur;
  private int hauteur;
  private Rectangle rectangle;
  public Rectangl(int x1,int y1, int x2 ,int y2,int largeur,int hauteur,Color couleur,Boolean plein){
  super(x1,y1,x2,y2,couleur,plein);
  this.largeur = largeur;
  this.hauteur = hauteur;
}

  public void dessinerrect(Graphics g){
  g.setColor(couleur); 
  g.drawRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
 }
  public void dessinerfrect(Graphics g){
  g.setColor(couleur); 
  g.fillRect((int)point1.getX(), (int)point2.getY(), largeur, hauteur);
 }

   }

【问题讨论】:

  • 绘制是破坏性的,当调用paintComponent 时,您应该从头开始重新绘制整个状态。这意味着您需要某种方式来存储要绘制的形状,可能是某种List

标签: java arraylist vector graphics


【解决方案1】:

您需要实现一个显示列表。这是一个数据结构,表示当前图形中的所有项目。组件绘制器只是遍历列表并绘制每个项目(通常在擦除屏幕以使已删除的对象不会出现在新绘图中之后)。如果鼠标已被按下但尚未释放,它还可以选择绘制“橡皮筋光标”。鼠标动作(通常释放鼠标按钮只是修改状态变量,包括显示列表(添加、选择、删除等),然后重新绘制绘图表面,以便调用组件绘制器。

Java ArrayList 是实现简单显示列表的合理方法。这些项目本身是接口和/或继承的经典用法:

interface DisplayListItem {
  void draw(Graphics g);
}

abstract class AbstractRectangle implements DisplayListItem {
  protected int x, y, w, h;
  protected Color color;
  Rectangle(int x, int y, int w, int h, Color color) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.color = color;
  }
}

class Rectangle extends AbstractRectangle {
  Rectangle(int x, int y, int w, int h, Color color) { 
    super(x, y, w, h, color);
  }
  @Override
  void draw(Graphic g) {
    g.setColor(color);
    g.drawRect(x, y, w, h);
  }
}
class FilledRectangle extends AbstractRectangle {
  FilledRectangle(int x, int y, int w, int h, Color color) { 
    super(x, y, w, h, color);
  }
  @Override
  void draw(Graphic g) {
    g.setColor(color);
    g.fillRect(x, y, w, h);
  }
}

private List<DisplayListItem> displayList = new ArrayList<>();
private int xPress, yPress, xDrag, yDrag;
private boolean mousePressed = false;

@Override
public void paintComponent(Graphics g) { 
  super.paintComponent(g);
  for (DisplayListItem item : displayList) {
    item.draw(g);
  }
  if (mousePressed) {
   // Draw the click-and-drag cursor.
   g.setColor(Color.RED);
   g.drawRect(xPress, yPress, xDrag - xPress, yDrag - yPress);
  }
}

private void formMousePressed(MouseEvent evt) { 
  xPress = evt.getX();
  yPress = evt.getY();
  mousePressed = true;
}

private void formMouseDragged(MouseEvent evt) {
  if (!mousePressed) return;
  xDrag = evt.getX();
  yDrag = evt.getY();
  repaint();
} 

private void formMouseReleased(MouseEvent evt) {
  if (!mousePressed) return;
  xDrag = evt.getX();
  yDrag = evt.getY();
  // Adding a rectangle to the display list makes it permanent.
  displayList.add(new Rectangle(xPress, yPress, xDrag - xPress, yDrag - yPress));
  mousePressed = false;
  repaint();
}

警告:这是未经编译、未经测试的代码。使用风险自负。

【讨论】:

    【解决方案2】:

    Swing 具有有用的 Shape 接口,该接口已实现到几个可以很好地满足您的目的的具体类中。

    有几种不同的Shape(Ellipse2D、Rectangle2D、RoundRectangle2D)存储在Shape对象的ArrayList中,然后在JPanelpaintComponent方法中绘制首先将 Graphics 对象转换为 Graphics2D。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 2020-04-29
      • 2013-10-17
      相关资源
      最近更新 更多