понедельник, 15 сентября 2008 г.

Wrapper for JComponent

Trouble: we have some JComponent. We need paint this component and remove all logic from it.

At the begining, I think that solution is very simple: override paint() method, and draw inner component in wrpapper's Graphics.

public class ComponentWrapper extends JComponent {
  private JComponent innerComponent;

  public ComponentWrapper(JComponent innerComponent) {
      this.innerComponent = innerComponent;
  }

  @Override
  public void paint(Graphics g)
  {
      if (innerComponent != null) {
          innerComponent.paint(g);
      }
  }

}

But I don't see innerComponent, because it hasn't bound. We should delegate methods that set sizes and bound on innerComponent. Now our wrapper looks like this:

public class ComponentWrapper extends JComponent {
  private JComponent innerComponent;

  public ComponentWrapper(JComponent innerComponent) {
      this.innerComponent = innerComponent;
  }

  @Override
  public void paint(Graphics g) {
      innerComponent.paint(g);
  }
   
  @Override
  public void setMaximumSize(Dimension maximumSize) {
      super.setMaximumSize(maximumSize);
      innerComponent.setMaximumSize(maximumSize);
  }

  @Override
  public void setMinimumSize(Dimension minimumSize) {
      super.setMinimumSize(minimumSize);
      innerComponent.setMinimumSize(minimumSize);
  }

  @Override
  public void setPreferredSize(Dimension preferredSize) {
      super.setPreferredSize(preferredSize);
      innerComponent.setPreferredSize(preferredSize);
  }

  @Override
  public void setBounds(Rectangle r) {
      super.setBounds(r);
      innerComponent.setBounds(r);
  }

  @Override
  public void setBounds(int x, int y, int width, int height) {
      super.setBounds(x, y, width, height);
      innerComponent.setBounds(x, y, width, height);
  }

  @Override
  public void setSize(int width, int height) {
      super.setSize(width, height);
      innerComponent.setSize(width, height);
  }
}


At first blush all is ok. But if we wrap JPanel with some layout, we dont see anything. This occurs because components in panel haven't sizes. We should apply layout on panel. JComponent have a wonderful method - doLayout(). Now, when our wrapper change size, we need call innerComponent.doLayout() and after this components in panel will have actual sizes. In paint method we should iterate over components in panel and paint its in translated coordinates. 

Final class:

public class ComponentWrapper extends JComponent {
  private JComponent innerComponent;

  public ComponentWrapper(JComponent innerComponent) {
      this.innerComponent = innerComponent;
  }

  @Override
  public void paint(Graphics g) {

      if (innerComponent instanceof JPanel) {
          for (Component comp : innerComponent.getComponents()) {
              Graphics gnew = g.create();
              Point location = comp.getLocation();
              gnew.translate((int)location.getX(), (int)location.getY());
             comp.paint(gnew);

         }
      } else innerComponent.paint(g);
  }
   
  @Override
  public void setMaximumSize(Dimension maximumSize) {
      super.setMaximumSize(maximumSize);
      innerComponent.setMaximumSize(maximumSize);

      innerComponent.doLayout();
  }

  @Override
  public void setMinimumSize(Dimension minimumSize) {
      super.setMinimumSize(minimumSize);
      innerComponent.setMinimumSize(minimumSize);

      innerComponent.doLayout();
  }

  @Override
  public void setPreferredSize(Dimension preferredSize) {
      super.setPreferredSize(preferredSize);
      innerComponent.setPreferredSize(preferredSize);

      innerComponent.doLayout();
  }

  @Override
  public void setBounds(Rectangle r) {
      super.setBounds(r);
      innerComponent.setBounds(r);

      innerComponent.doLayout();
  }

  @Override
  public void setBounds(int x, int y, int width, int height) {
      super.setBounds(x, y, width, height);
      innerComponent.setBounds(x, y, width, height);

      innerComponent.doLayout();
  }

  @Override
  public void setSize(int width, int height) {
      super.setSize(width, height);
      innerComponent.setSize(width, height);

      innerComponent.doLayout();
  }
}

P.S.(Intro to my blog): Hi all, I hope that my tips help you. But my English is very bad and I want to do it better. If you can, correct me in comments, please.

Комментариев нет:

Most popular

Authors