Как предотвратить промывку при рисовании прямоугольника в Java

#java #swing #paint

#java #swing #Краски

Вопрос:

 import javax.swing.*;
import java.awt.*;
import java.awt.event.*;  
import java.util.List;
import java.util.ArrayList;

class DrawningBoard extends Canvas implements MouseMotionListener{
      private List<Point> points = new ArrayList<>();
      private List<List<Point>> curves = new ArrayList<>();
      private boolean isRectangle = false;
      private int xr, yr, widthr, heightr;

public void setIsRectangle(boolean trueOrFalse){
    isRectangle = trueOrFalse;
}
public boolean getIsRectangle(){
    return isRectangle;
}

public DrawningBoard(){
    setBackground(Color.MAGENTA);
    addMouseMotionListener(this); 
    addMouseListener(new MouseAdapter(){
        public void mouseReleased(MouseEvent e){
            curves.add(points);
            points = new ArrayList<>();
        }
        public void mousePressed(MouseEvent e){
            points.add(new Point(e.getX(), e.getY()));
        }
    });
}

public void paint(Graphics g){
    g.setColor(Color.CYAN);
    if(isRectangle){
        g.drawRect(xr, yr, widthr, heightr);
    }
    for(List<Point> curve : curves){
        for(int i = 0; i < curve.size() - 1; i  ){
            g.drawLine((int)curve.get(i).getX(), (int)curve.get(i).getY(), (int)curve.get(i   1).getX(), (int)curve.get(i   1).getY());
        }
    }
}

public void mouseDragged(MouseEvent e){  
    Graphics g = getGraphics();
    g.setColor(Color.CYAN);
    
    int xx = e.getX();
    int yy = e.getY();
    
    int x = (int)points.get(points.size() - 1).getX();
    int y = (int)points.get(points.size() - 1).getY();
    int dx = xx-x;
    int dy = yy-y;

    if(isRectangle){
        if(dx >= 0 amp;amp; dy >= 0){
            xr = x;
            yr = y;
            widthr = dx;
            heightr = dy;
        } else if(dx < 0 amp;amp; dy < 0){
            xr = xx;
            yr = yy;
            widthr = -dx;
            heightr = -dy;
        } else if(dx >= 0 amp;amp; dy < 0){
            xr = x;
            yr = yy;
            widthr = dx;
            heightr = -dy;
        } else if(dx < 0 amp;amp; dy >= 0){
            xr = xx;
            yr = y;
            widthr = -dx;
            heightr = dy;
        }
        repaint();
    } 
    else {
        g.drawLine(xx, yy, (int)points.get(points.size() - 1).getX(), (int)points.get(points.size() - 1).getY());
        points.add(new Point(xx, yy));
    }
    
}

public void mouseMoved(MouseEvent e) { }  
}

class GUI extends JFrame implements ActionListener{
private JPanel[] panel;
private JButton[] button;
private DrawningBoard board;

public GUI(String title){
    super(title);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    setSize(416, 400);
    
    board = new DrawningBoard();
    board.setBounds(0,0, 400, 400);
    
    panel = new JPanel[3];
    panel[0] = new JPanel();
    panel[1] = new JPanel();
    panel[2] = new JPanel();
    panel[0].setLayout(null);
    panel[1].setLayout(null);
    panel[2].setLayout(null);
    panel[0].setBounds(0, 0, 400, 20);
    panel[1].setBounds(0, 20, 400, 400);
    panel[2].add(panel[0]);
    panel[2].add(panel[1]);
    panel[0].setBackground(Color.red);
    
    button = new JButton[5];
    button[0] = new JButton("Rectangle");
    button[1] = new JButton("b1");
    button[2] = new JButton("b2");
    button[3] = new JButton("b3");
    button[4] = new JButton("b4");
    button[0].addActionListener(this);
    button[3].addActionListener(this);

    button[0].setBounds(0, 0, 100, 20);
    button[1].setBounds(100, 0, 100, 20);
    button[2].setBounds(200, 0, 100, 20);
    button[3].setBounds(300, 0, 100, 20);
    button[4].setBounds(0, 0, 100, 20);
    
    panel[0].add(button[0]);
    panel[0].add(button[1]);
    panel[0].add(button[2]);
    panel[0].add(button[3]);
    panel[0].add(button[4]);
    
    panel[1].add(board);

    add(panel[2]);  
    
    show();
}
public void actionPerformed(ActionEvent e){
    String command = e.getActionCommand();
    if(command.equals("Rectangle")) 
        board.setIsRectangle(!board.getIsRectangle());
}
}


public class Paint{
public static void main(String []str){
    new GUI("Paint");
}
}
  

Я хочу создать приложение для рисования. Если я рисую несколько кривых на доске, а затем хочу нарисовать
прямоугольник (используя drawRect(x, y, width, height) ), эти кривые перерисовываются и приводят к некоторой промывке в результате использования repaint() метода. Как я могу избежать этой промывки?

Я пытался использовать update() метод, но многие прямоугольники рисуются при перетаскивании мышью.

Комментарии:

1. Создайте модель приложения, используя простые классы Java для хранения ваших кривых и прямоугольников, затем метод paintComponent вашего чертежа JPanel перерисовывает все на основе модели.

Ответ №1:

Swing по умолчанию имеет двойную буферизацию.

 public void paint(Graphics g){
  

Не переопределяйте paint() . Вы сделали это неправильно и потеряли преимущество двойной буферизации.

Вместо этого пользовательское рисование должно выполняться путем переопределения paintComponent(...) метода. Прочитайте раздел из учебника Swing по пользовательскому рисованию для получения дополнительной информации и рабочих примеров.

Вы также можете ознакомиться с DrawOnComponent примером из пользовательских подходов к рисованию для более полного примера, который делает то, что вы хотите.