Сохранение нарисованного объекта на JPanel

Привет, эксперты: у меня есть класс, который расширяет JPanel теперь ShapePanel (Sp), который добавляется к обычному JPanel (контейнеру), который, в свою очередь, добавляется в JFrame (окно). В методе paintComponent я рисую форму.... но форма никогда не сохраняется после рендеринга. В отладчике я вижу, что он перерисовывается каждый раз, когда я изменяю размер или что-то в этом роде.

Теперь я перегрузил PaintComponent JPanel (Sp) и добавил это

    super.paintComponent(g);        

    ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics());
    //for(Shape s : ArrayOfShapes)
    {
        if(s instanceof Rectangle)
                SdG.Paint((Rectangle)s);
            else if(s instanceof Triangle)
                SdG.Paint((Triangle)s);
            else
                SdG.Paint((Circle)s);
    } //s is a custom-shape object

графический объект исходит из (очевидно) JPanel....

Но нарисованное изображение никогда не остается на панели - видишь его на долю секунды и его нет...

Я сделал некоторые поиски, но безрезультатно.

Фактический рисунок

public ShapeDrawerGui(Graphics2D _g)
{
    g = _g;
    g.setColor(Color.Black);
}

@Override
public void Paint(Circle c) 
{
    g.drawArc(0, 0, 50, 50, 0, 360);
}

@Override
public void Paint(Triangle t) 
{        
    Polygon p = new Polygon();
    p.addPoint(0, 25);
    p.addPoint(0 , 50);
    p.addPoint(50, 50);       
    g.drawPolygon(p);
}

@Override
public void Paint(Rectangle r) 
{
    g.drawRect(0, 0, 50, 50);
}

С уважением

Маркус


person Markus    schedule 19.03.2012    source источник
comment
У вас есть метод Paint() с заглавной буквой P - ну... ну, это не проблема.   -  person ring bearer    schedule 19.03.2012
comment
Вы пытались изменить ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics()); на ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)g);   -  person ring bearer    schedule 19.03.2012
comment
графический объект поступает (очевидно) из JPanel SSCCE обычно делает вещи очевидными.   -  person Andrew Thompson    schedule 19.03.2012
comment
@AndrewThompson: Я не могу в это поверить, но это сработало .... тогда в чем разница между this.getGraphics и g, они одно и то же, не так ли?   -  person Markus    schedule 19.03.2012


Ответы (2)


..в чем разница между this.getGraphics и g..?

Графический пользовательский интерфейс должен перерисовывать, когда ему говорят об этом, и использовать объект Graphics, предоставленный методу paint(Graphics) или paintComponent(Graphics). Этот метод может быть вызван в любое время графическим интерфейсом, например, для перерисовки после того, как он находится за другим окном.

Когда вы вызываете getGraphics(), вам предоставляется непостоянный графический объект, который исчезнет при следующей отрисовке.

person Andrew Thompson    schedule 19.03.2012
comment
+1 Я проглядел это. @Markus: вам также может потребоваться вызвать repaint(), если вы измените несвязанное свойство. - person trashgod; 19.03.2012

Вот проблема:

super.paintComponent(g);        

ShapeDrawerGui SdG = new ShapeDrawerGui((Graphics2D)this.getGraphics());

g и SdG — это два разных объекта, и вопреки интуиции, g, принадлежащий вашей специализированной панели, НЕ является тем, который всегда рисует на ней.

В зависимости от того, что делает ваша программа, они могут ОБА использоваться для рисования на холсте, однако g всегда будет отображаться последним и сохраняться после завершения рисования SgD. даже если Graphics2D, которое вы извлекли, SgD ДЕЙСТВИТЕЛЬНО принадлежит компоненту, который вы хотите нарисовать, ( getGraphics() ), это не означает, что это Graphics, который используется для рисования холста.

Я знаю, что это противоречит здравому смыслу. Каждый jJXXX имеет связанный с ним объект Graphics, который используется для его рисования, но это не означает, что Swing БУДЕТ использовать его для рисования, несмотря ни на что.

Графика, поступающая к вам через параметр в paintComponent, НЕ является той же самой графикой, которую вы получаете от getGraphics(), хотя paintComponent() является методом для того же объекта, для которого вы вызываете getGraphics.

Если вы хотите увидеть это, просто установите логическое значение для первой строки этого оператора в paintComponent(Graphics g):

boolean sameObject = (g== getGraphics())

и распечатайте sameObject. Вы увидите слово false.

Таким образом, оба используются для рисования на экране. Вы видите это, потому что в это время g вашего холста рисует. Затем через микросекунду g, которое вы получаете в качестве параметра, выполняет отрисовку, и отрисовывается последней.

Выигрывает тот, кто рисует последним. Это своего рода обратное шоу-даун.

person Swing God    schedule 14.06.2014