2014-09-19 3 views
1

Это скорее концептуальный вопрос, поэтому трудно опубликовать небольшой пример работоспособного кода. Но, у меня есть класс, который переопределяет paintComponent здесь:Переопределение краски Компонент дважды

public abstract class BasePanel extends JPanel { 

    ...  

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g);  
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
          RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 

     this.standardDraw(drawObjects,g2); 
    } 
} 

В принципе, я хотел бы, чтобы это было «стандартным способом» эта базовая панель рисует, если paintComponent не переопределен в производном классе. Итак, я производный класс называется AspectRatioPanel, который я хотел бы вновь указать, как он рисует вещи:

public class AspectRatioPanel extends BasePanel { 

    ... 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g);  
     Graphics2D g2 = (Graphics2D)g; 
     g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
          RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 

     // Get ViewPort Bounding Box to clip 
     BoundingBox viewPortBoundingBox = this.getViewPortBoundingBox(); 

     // Clip to viewport 
     g2.setClip((int)viewPortBoundingBox.topLeft.getX(),(int)viewPortBoundingBox.topLeft.getY(),(int)viewPortBoundingBox.getWidth(),(int)viewPortBoundingBox.getHeight()); 

     this.standardDraw(drawObjectsBuf,g2); 
    } 
} 

Проблема у меня есть вызов super.paintComponent(g) в производном классе. Я намерен позвонить ему paintComponent в JComponent, но он проходит через BasePanel. Есть ли лучший способ подойти к этой проблеме? Я мог бы удалить метод paintComponent в BasePanel, но для меня полезен стандартный способ рисования. Я также не могу назвать JComponent.paintComponent напрямую, так как это protected. Есть ли решение для этого? Кроме того, я делаю что-то концептуально неправильно?

+0

Интересно, хотите ли вы реализовать как общий интерфейс, так и, возможно, поделиться одним и тем же композиционным компонентом, чтобы разрешить совместное поведение, а не использовать наследование здесь. –

+0

Возможно, вы захотите проверить [этот вопрос] (http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java). – Rob

+0

Другим способом, если панели в противном случае то же самое, имеет только одну реализацию, которая имеет возможность работать в режиме сохранения пропорций. – kiheru

ответ

4

Возможно, я неправильно понял вашу проблему, но я бы отделить стандартные и пользовательские картины

public abstract class BasePanel extends JPanel { 

...  

    @Override 
    protected void paintComponent(Graphics g) { 
    super.paintComponent(g);  
    provideCustomPainting(g); 
    } 

    protected void provideCustomPainting(Graphics g) { 
    Graphics2D g2 = (Graphics2D)g; 
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
         RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 

    this.standardDraw(drawObjects,g2); 
    } 
} 

public class AspectRatioPanel extends BasePanel { 
    protected void provideCustomPainting(Graphics g) { 
    Graphics2D g2 = (Graphics2D)g; 
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
         RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 

    // Get ViewPort Bounding Box to clip 
    BoundingBox viewPortBoundingBox = this.getViewPortBoundingBox(); 

    // Clip to viewport 
    g2.setClip((int)viewPortBoundingBox.topLeft.getX(),(int)viewPortBoundingBox.topLeft.getY(),(int)viewPortBoundingBox.getWidth(),(int)viewPortBoundingBox.getHeight()); 

    this.standardDraw(drawObjectsBuf,g2); 
    } 
} 
+0

'' Наверное, я неправильно понял вашу проблему, ... "' - нет, этот ответ кажется мне интересным. 100+ –

+0

Это будет работать, и я пойду дальше и приму это. Я действительно задаюсь вопросом, могу ли я подойти к нему лучше. Благодаря! – Justin

1

Вы могли бы просто не вызов super.paintComponent (Graphics); путем перезаписи paintComponent() у вас есть 3 варианта:

a.) Звоните супер в начале метода; вы рисуете краска кода поверх того, что было написано суперклассом.

b.) Не называйте супер вообще - ваш paintComponent должен гарантировать, что он красит все, что необходимо; если компоненты непрозрачны, это означает, что вам нужно нарисовать всю область, занимаемую компонентом.

c.) Позвоните супер по вашему желанию; все, что написано в супер, похоже, «многослойно» в последовательности, где вы его называете. Имеет смысл только в том случае, если супер-метод не рисует всю область.

Если вы настаиваете, чтобы использовать paintComponent из определенного класса иерархии наследования как super.paintComponent, независимо от иерархии наследования между ними, то будет возможно:

BasePanel extends JPanel { 
    protected final defaultPaintComponent(Graphics g) { 
     super.paintComponent(g); 
    } 
} 

классы по уходу за детьми могут называть «defaultPaintComponent» вместо super.paintComponent, таким образом, обходя любые классы реализации между ними в иерархии, определенной (я предлагаю объявить ее окончательной, чтобы предотвратить случайную перезапись).

+0

Я ценю предложения. Это то, о чем я буду думать больше. – Justin

Смежные вопросы