Слоистая роспись на яве? - PullRequest
4 голосов
/ 12 февраля 2012

Я в основном пытаюсь сделать что-то вроде классического "Paint" (программа Microsoft). Но я хочу работать со слоями при рисовании. Я думал, что могу использовать компонент JPanel в качестве слоя.

Я тестировал код ниже. Цель - нарисовать прямоугольник с помощью мыши. При перетаскивании мышью на нем отображается временный слой (темп), а при отпускании мыши существует фактический слой (область) для рисования. Но каждый раз, когда я начинаю рисовать новый прямоугольник, старые исчезают. Также, если я снова выполню setVisible (false) и true, все исчезнет.

MouseInputAdapter mia = new MouseInputAdapter() {
    private int startx = 0, starty = 0, stopx = 0, stopy = 0;

    public void mousePressed(MouseEvent evt) {
        startx = evt.getX();
        starty = evt.getY();
    }

    public void mouseDragged(MouseEvent evt) {
        Graphics2D tempg = (Graphics2D) temp.getGraphics();

        int width = Math.abs(startx - evt.getX());
        int height = Math.abs(starty - evt.getY());
        int x = evt.getX(), y = evt.getY();
        if(x > startx)
            x = startx;
        if(y > starty)
            y = starty;

        Rectangle r = new Rectangle(x, y, width, height); 
        tempg.clearRect(0, 0, getWidth(), getHeight());
        tempg.draw(r);
    }

    public void mouseReleased(MouseEvent evt) {
        Graphics2D g = (Graphics2D) area.getGraphics();
        stopx = evt.getX();
        stopy = evt.getY();

        int width = Math.abs(startx - stopx);
        int height = Math.abs(starty - stopy);
        int x = startx, y = starty;
        if(x > stopx)
            x = stopx;
        if(y > stopy)
            y = stopy;

        Rectangle r = new Rectangle(x, y, width, height);
        g.draw(r);
    }
};
area.addMouseListener(mia);
area.addMouseMotionListener(mia);
temp.addMouseListener(mia);
temp.addMouseMotionListener(mia);

Что не так с этим кодом?

Ответы [ 4 ]

6 голосов
/ 12 февраля 2012

Каждый раз, когда происходит перекраска, нет гарантии, что вы получите ту же графику в том состоянии, в котором вы ее оставили.

Два двухэтапных вместо:

  • Создать списокПрямоугольники в вашем классе.
  • В вашем слушателе мыши вместо рисования к графике, добавьте прямоугольник в список.
  • Переопределите paintComponent и там нарисуйте список прямоугольников для графики, которую онпропущено.

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

2 голосов
/ 12 февраля 2012

Классическая графика на основе растровой графики Программное обеспечение работает на целевом растровом изображении.Вы можете визуализировать несколько Layer с в paintComponent(), как @Keily предлагает для Rectangle с.

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

1 голос
/ 12 февраля 2012

Вот общая идея: (я предполагаю, что вы имеете в виду слои, такие как в фотошопе)

Настройка одного JPanel для рисования.

Создайте структуру данных, содержащую все нарисованные объекты, необходимые для рисования.

В этой структуре данных также создайте поле, содержащее целое число, выражающее, к какому слою привязан данный рисованный объект.

В вашем методе paintComponent () проверьте, какой слой активен в данный момент, и нарисуйте данные только в этом слое или ниже.

0 голосов
/ 13 февраля 2012

Это то, что я искал; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

Моя ошибка; используя метод getGraphics () из paintComponent () и ожидая сохранения изменений.

Почему ответ @ Кейли мне не подходит; Потому что, если я помещаю фигуры в список или массив, при изменении фигуры (например, удаляя 1/4 окружности) я не могу обновить элемент в списке. Потому что это больше не будет той же формы. Поэтому я должен сохранять формы в виде рисунков, и мне не нужно (и не хочу) хранить их отдельно.

...