paintComponent удаляет ранее нарисованные компоненты
Я пишу простую программу рисования. Я создал JPanel
и переписали "общественную пустоту paintComponent(Graphics g)
"Я также создал соответствующий Listeners
, Проблема в том, что каждый раз, когда я рисую новую фигуру, моя предыдущая исчезает. Кто-нибудь знает, как я могу сохранить прежние фигуры на их месте? Я могу взять super.paintComponent(g)
прочь, но потом Jpanel's
layout
будет искажен. Любое предложение высоко ценится.:) это мой метод paintComponent:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = xend-xstart;
int height = yend - ystart;
if(width<0)
width *= -1;
if(height <0)
height *= -1;
if(color!= null && shape !=null){
if(fill.isSelected())
{
g.setColor(color);
if(shape.equals("Rectangle"))
g.fillRect(xstart, ystart, width, height);
if(shape.equals("Square"))
g.fillRect(xstart, ystart, width, width);
if(shape.equals("Circle"))
g.fillOval(xstart,ystart,width ,width);
}
}
}
2 ответа
Чтобы нарисовать несколько объектов "Прямоугольник", "Квадрат" или "Круг", необходимо добавить их в коллекцию (например, ArrayList
) И каждый звонок paintComponent(Graphics)
, итерируйте коллекцию и нарисуйте каждый.
Либо так, либо нарисуйте фигуры в BufferedImage
и нарисуйте изображение вместо этого.
... не повлияет ли это на эффективность, так как я рисую все больше и больше фигур? потому что тогда paintComponent должен рисовать много фигур каждый раз, когда я вызываю repaint();
На это я могу дать 3 ответа. Вот они:
- Да, это так.
- Но нет, должны быть тысячи, прежде чем вызвать видимое замедление.
- В случае, если производительность является проблемой. Использовать
BufferedImage
, Таким образом, для каждой новой добавленной фигуры рисуется только еще одна фигура, независимо от того, сколько ..миллионов было ранее отображено на ней.
.. Также мне нужно написать функцию отмены, и список будет полезен и в этом случае
Похоже, что список - это путь для этого варианта использования.
Ответ Эндрю Томпсона - это "типичный" способ сделать то, что вы хотите. Однако, если вы хотите погрузиться глубже в глубины Swing...
Одна из вещей, которые super.paintComponent() делает (в конце концов), это получить JComponent.paintComponent()
, который вызывает ComponentUI.update()
, Javadocs говорят (курсив добавлен мной):
"По умолчанию этот метод заменит указанный компонент цветом фона (если его непрозрачное свойство имеет значение true), а затем немедленно вызовет paint".
Итак, попробуйте позвонить setOpaque(false)
, Однако это часто приводит к другим проблемам, например, когда вы действительно хотите стереть то, что было нарисовано ранее.