// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// @homepage@

package example;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.*;

public final class MainPanel extends JPanel {
  private MainPanel() {
    super();
    Icon i = new ImageIcon(getClass().getResource("duke.gif"));
    add(makeLabel("Default", i));
    add(makeLabel("Rotate: 180", new RotateIcon(i, 180)));
    add(makeLabel("Rotate:  90", new RotateIcon(i, 90)));
    add(makeLabel("Rotate: -90", new RotateIcon(i, -90)));
    setBorder(BorderFactory.createEmptyBorder(0, 32, 0, 32));
    setPreferredSize(new Dimension(320, 240));
  }

  private static JLabel makeLabel(String title, Icon icon) {
    JLabel l = new JLabel(title, icon, SwingConstants.CENTER);
    l.setVerticalTextPosition(SwingConstants.BOTTOM);
    l.setHorizontalTextPosition(SwingConstants.CENTER);
    l.setBorder(BorderFactory.createLineBorder(Color.GRAY));
    return l;
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class RotateIcon implements Icon {
  private final Dimension dim = new Dimension();
  private final Image image;
  private final AffineTransform trans;

  protected RotateIcon(Icon icon, int rotate) {
    if (rotate % 90 != 0) {
      throw new IllegalArgumentException(rotate + ": Rotate must be (rotate % 90 == 0)");
    }
    dim.setSize(icon.getIconWidth(), icon.getIconHeight());
    image = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);
    Graphics g = image.getGraphics();
    icon.paintIcon(null, g, 0, 0);
    g.dispose();

    int numquadrants = (rotate / 90) % 4;
    switch (numquadrants) {
      case 3:
      case -1:
        trans = AffineTransform.getTranslateInstance(0, dim.width);
        dim.setSize(icon.getIconHeight(), icon.getIconWidth());
        break;
      case 1:
      case -3:
        trans = AffineTransform.getTranslateInstance(dim.height, 0);
        dim.setSize(icon.getIconHeight(), icon.getIconWidth());
        break;
      case 2:
        trans = AffineTransform.getTranslateInstance(dim.width, dim.height);
        break;
      default:
        trans = AffineTransform.getTranslateInstance(0, 0);
        break;
    }
    trans.rotate(Math.toRadians(90d * numquadrants));
  }

  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.drawImage(image, trans, c);
    g2.dispose();
  }

  @Override public int getIconWidth() {
    return dim.width;
  }

  @Override public int getIconHeight() {
    return dim.height;
  }
}

@@ -203,167 +203,659 @@
 java
-x.swing.*;%0A%0Apublic final class MainPanel extends JPanel %7B%0A  private MainPanel() %7B%0A    super();%0A    Icon i = new ImageIcon(getClass().getResource(%22duke.gif
+.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.util.Optional;%0Aimport javax.imageio.ImageIO;%0Aimport javax.swing.*;%0A%0Apublic final class MainPanel extends JPanel %7B%0A  private MainPanel() %7B%0A    super();%0A    String path = %22example/duke.gif%22;%0A    ClassLoader cl = Thread.currentThread().getContextClassLoader();%0A    Icon icon = Optional.ofNullable(cl.getResource(path)).map(url -%3E %7B%0A      try (InputStream s = url.openStream()) %7B%0A        return new ImageIcon(ImageIO.read(s));%0A      %7D catch (IOException ex) %7B%0A        return UIManager.getIcon(%22OptionPane.warningIcon%22);%0A      %7D%0A    %7D).orElseGet(() -%3E UIManager.getIcon(%22OptionPane.warningIcon
 %22));%0A
+%0A
     
@@ -880,16 +880,19 @@
 ault%22, i
+con
 ));%0A    
@@ -936,16 +936,19 @@
 teIcon(i
+con
 , 180)))
@@ -998,16 +998,19 @@
 teIcon(i
+con
 , 90)));
@@ -1059,16 +1059,19 @@
 teIcon(i
+con
 , -90)))

argument 'getClass().getResource(...)' might be null