Краска недостаточно быстро «тикает» и оставляет точки

Я пытаюсь создать небольшое приложение для рисования, в котором вы вводите нужный цвет и меняете размер кисти. Я сделал это, и это работает, но если я пытаюсь рисовать быстро, приложение не обновляется в течение короткого периода времени, оставляя точки, похожие на это: Краска недостаточно быстро «тикает» и оставляет точки

60 раз в секунду (поскольку 60 раз в секунду должен достаточно, чтобы не оставлять точек/пробелов. См. Метод отметок. В качестве теста я попытался установить ограничение нет на ticksPerSecond, и я получил тот же результат), если пользователь вызывает событие mouseDragged или mousePressed, я добавляю экземпляр класса Circle (см. ниже)

class Circle {
    int x, y;
    int radius;
    Color color;

    Circle(int x, int y, int radius, Color color) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.color = color;
    }
}

Мой метод тика: (вызывается 60 раз в секунду)

private void tick() {
    this.middle = this.brush.radius / 2; // Used because java.awt.Graphics will paint from your cursors xy, which will paint the circle down and to the right of the cursor

    if (this.frame.isDragging) {
        add(new Circle(this.frame.x - this.middle, this.frame.y - this.middle, this.brush.radius, this.brush.color));
    }
}

Для рендеринга я просто запускаю цикл foreach, показанный ниже.

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g); // Paint over everything else

    try {
        for (Circle circle : this.circles) {
            g.setColor(circle.color);
            g.fillOval(circle.x, circle.y, circle.radius, circle.radius);
        }
    } catch (ConcurrentModificationException ignore) {} //TODO MAKE THIS BETTER
}

Не обращайте внимания на то, что я ловлю ConcurrentModifictionException, это временное исправление, потому что я добавляю в список, который читается здесь. (Это заставляет краску мигать только во время рисования, так что пока это работает)

У меня попросили мой фрейм, вот он (Возможно, вам это не нужно, но я включил любой код, который вам нужен. Я удаляю implement methods, который я не использовал):

class Frame extends JFrame implements MouseListener, MouseMotionListener {

int x, y;
boolean isDragging, isMouseOnScreen;

Frame(int width) {
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.getContentPane().setPreferredSize(new Dimension(width, width / 3 * 2));
    this.setResizable(false);
    this.pack();
    this.setLocationRelativeTo(null);

    BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
    Cursor cursor = this.getToolkit().createCustomCursor(image, new Point(0, 0), "Cursor");
    this.setCursor(cursor);

    this.setFocusable(true);
    this.requestFocus();
    this.addMouseListener(this);
    this.addMouseMotionListener(this);

    this.x = this.y = 0;
    this.isDragging = this.isMouseOnScreen = false;
}

@Override
public void mouseDragged(MouseEvent e) {
    this.x = e.getX() - 5;
    this.y = e.getY() - 35;
}

@Override
public void mouseMoved(MouseEvent e) {
    this.x = e.getX() - 5;
    this.y = e.getY() - 35;
}

@Override
public void mousePressed(MouseEvent e) {
    this.isDragging = true;
}

@Override
public void mouseReleased(MouseEvent e) {
    this.isDragging = false;
}

@Override
public void mouseEntered(MouseEvent e) {
    isMouseOnScreen = true;
}

@Override
public void mouseExited(MouseEvent e) {
    isMouseOnScreen = false;
}
}

Вам нужно провести «линию» кистей между точками, чтобы заполнить пробелы. Как предположение, кажется, что mouseDragged() вызывается недостаточно быстро. Где вы настраиваете frame?

Steve Smith 20.03.2019 17:06

Вы можете перемещать мышь на несколько сотен или даже тысяч пикселей в секунду, поэтому могут возникать пробелы, особенно если вы хотите рисовать линии (это уже должно быть подсказкой: не рисуйте точки/круги, а линии между мышью). должности). Кроме того, скорость, с которой генерируются события мыши, может быть ниже скорости рендеринга, т. е. у вас может быть намного меньше 60 событий мыши в секунду.

Thomas 20.03.2019 17:12

Как бы я нарисовал линию? Я предполагаю, что линии прямые, но люди могут «изгибать» свои линии. Я добавил свой класс Frame, но не упростил его. Я знаю, что моя проблема заключается не только в том, что мышь перемещается на 1000 пикселей в секунду, потому что я пытался не устанавливать ограничений на количество тиков в секунду. Не имеет значения, если я получаю менее 60 событий мыши, потому что это только обновляет мою переменную isDragging.

CJCrafter 20.03.2019 19:18

Вы можете провести линию между текущей точкой и предыдущей.

Slim 20.03.2019 19:32

Вы также можете рисовать кривые, чтобы избежать углов. В интернете есть алгоритмы по этому поводу.

Slim 20.03.2019 19:42
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
38
0

Другие вопросы по теме