/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.tools;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class FlagTest extends JFrame {
private static final int[][] layout = new int[51][2];
static {
for (int[] bars : new int[][] {
{ 5, 4 }, { 5, 6 }, { 6, 5 }, { 5, 5 }
}) {
int sum = bars[0] + bars[1];
boolean even = true;
while (sum < 51) {
layout[sum] = bars;
if (even) {
sum += bars[0];
even = false;
} else {
sum += bars[1];
even = true;
}
}
}
}
public class Flag {
private static final double width = 100;
private static final double length = 1.9 * width;
private static final double unionLength = 0.4 * length;
private static final double star = 0.0616 * width;
private double unionWidth;
private final Color red = new Color(.698f, .132f, .203f);
private final Color blue = new Color(.234f, .233f, .430f);
private BufferedImage image;
public Flag(int stars, int stripes) {
image = new BufferedImage((int) length, (int) width,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(red);
Rectangle2D.Double background =
new Rectangle2D.Double(0, 0, length, width);
g.fill(background);
g.setColor(Color.WHITE);
double stripeWidth = width / stripes;
Rectangle2D.Double stripe =
new Rectangle2D.Double(0, 0, length, stripeWidth);
AffineTransform transform = g.getTransform();
for (int i = 0; i < stripes / 2; i++) {
g.translate(0, stripeWidth);
g.fill(stripe);
g.translate(0, stripeWidth);
}
g.setTransform(transform);
g.setColor(blue);
if (stripes == 1) {
unionWidth = stripeWidth / 2;
} else {
unionWidth = stripeWidth * Math.ceil(stripes / 2.0);
}
Rectangle2D.Double union =
new Rectangle2D.Double(0, 0, unionLength, unionWidth);
g.fill(union);
GeneralPath unionPath;
if (stars == 1) {
unionPath = getPentagram();
} else if (stars == 2) {
unionPath = new GeneralPath();
unionPath.append(getPentagram(), false);
GeneralPath newStar = getPentagram();
newStar.transform(AffineTransform.getTranslateInstance(unionLength/3, 0));
unionPath.append(newStar, false);
} else if (stars < 14) {
unionPath = getCircleOfStars(stars);
} else {
unionPath = getGrid(stars);
}
unionPath.transform(AffineTransform
.getTranslateInstance(-unionPath.getBounds().getX(),
-unionPath.getBounds().getY()));
double x = unionLength - unionPath.getBounds().getWidth();
double y = unionWidth - unionPath.getBounds().getHeight();
unionPath.transform(AffineTransform.getTranslateInstance(x/2, y/2));
g.setColor(Color.WHITE);
g.fill(unionPath);
}
public Image getImage() {
return image;
}
public GeneralPath getGrid(int states) {
int[] bars = new int[2];
for (int count = states; count < 51; count++) {
if (layout[count][0] > 0) {
bars = layout[count];
break;
}
}
int maxCols = Math.max(bars[0], bars[1]);
int rows = 2;
int sum = bars[0] + bars[1];
while (sum < states) {
sum += bars[rows%2];
rows++;
}
double hSpace = unionLength / (2 * maxCols);
double vSpace = unionWidth / (2 * rows);
double y = 0;
GeneralPath star = getPentagram();
GeneralPath grid = new GeneralPath();
int count = 1;
for (int row = 0; row < rows; row++) {
int cols = bars[row%2];
double x = (cols == maxCols) ? 0 : hSpace;
for (int col = 0; col < cols; col++) {
if (count > states) {
break;
}
GeneralPath newStar = (GeneralPath) star.clone();
newStar.transform(AffineTransform.getTranslateInstance(x, y));
grid.append(newStar, false);
x += 2 * hSpace;
count++;
}
y += 2 * vSpace;
}
return grid;
}
public GeneralPath getPentagram() {
double angle = 2 * Math.PI / 5;
double y = -star / 2;
GeneralPath pentagram = new GeneralPath(GeneralPath.WIND_NON_ZERO);
pentagram.moveTo(0, y);
int[] vertex = new int[] { 2, 4, 1, 3 };
for (int i : vertex) {
double phi = i * angle;
double xx = -y * Math.sin(phi);
double yy = y * Math.cos(phi);
pentagram.lineTo(xx, yy);
}
pentagram.closePath();
return pentagram;
}
public GeneralPath getCircleOfStars(int n) {
double radius = 0.3 * unionWidth;
double phi = Math.PI * 2 / n;
GeneralPath star = getPentagram();
GeneralPath circle = new GeneralPath();
for (int i = 0; i < n; i++) {
GeneralPath newStar = (GeneralPath) star.clone();
double xx = -radius - radius * Math.sin(i * phi);
double yy = -radius * Math.cos(i * phi);
newStar.transform(AffineTransform.getTranslateInstance(xx, yy));
circle.append(newStar, false);
}
double x = circle.getBounds().getX();
double y = circle.getBounds().getY();
circle.transform(AffineTransform.getTranslateInstance(-x, -y));
return circle;
}
}
public FlagTest() {
super("FlagTest");
JPanel panel = new JPanel(new GridLayout(0, 5, 5, 5));
JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
for (int states = 1; states < 51; states++) {
Flag flag = new FlagTest.Flag(states, Math.min(13, states));
JLabel label = new JLabel(new ImageIcon(flag.getImage()));
panel.add(label);
}
add(scrollPane);
}
public static void main(String[] args) {
FlagTest frame = new FlagTest();
// display the window
frame.pack();
frame.setVisible(true);
}
}