Last active
August 29, 2015 14:07
-
-
Save aterai/7f9a0abb8fd17e62390a to your computer and use it in GitHub Desktop.
「漢字の線に囲まれた部分だけを塗りつぶした画像で何の四字熟語か当てるスレ:キニ速」をみて作ってみた。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//package example; | |
//-*- mode:java; encoding:utf-8 -*- | |
// vim:set fileencoding=utf-8: | |
// http://ateraimemo.com/Swing/FontSilhouette.html | |
// http://stackoverflow.com/questions/18686199/fill-unicode-characters-in-labels | |
// http://blog.livedoor.jp/kinisoku/archives/4204798.html | |
import java.awt.*; | |
import java.awt.font.*; | |
import java.awt.geom.*; | |
import java.io.Serializable; | |
import javax.swing.*; | |
public final class MainPanel { | |
private static final int SIZE = 50; | |
private static final Font FONT = new Font(Font.SANS_SERIF, Font.PLAIN, SIZE); | |
private JComponent makeUI() { | |
String[] pieces = { | |
"\u4E2D", "\u767E", "\u820c", "\u9CE5", "\u99C5" | |
}; | |
JPanel p = new JPanel(new GridBagLayout()); | |
p.setBackground(Color.WHITE); | |
p.add(makePanel(pieces)); | |
return p; | |
} | |
private static JPanel makePanel(String[] pieces) { | |
JPanel p = new JPanel(new GridBagLayout()); | |
GridBagConstraints c = new GridBagConstraints(); | |
c.weightx = 0.0; | |
c.weighty = 0.0; | |
c.insets = new Insets(0, 0, 0, 0); | |
c.anchor = GridBagConstraints.CENTER; | |
c.gridwidth = 1; | |
c.gridheight = 1; | |
c.gridy = 0; | |
c.gridx = 0; | |
for (String s : pieces) { | |
p.add(makeLabel(s)); | |
} | |
p.setOpaque(false); | |
p.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, Color.BLACK)); | |
return p; | |
} | |
private static JLabel makeLabel(String str) { | |
JLabel l = new JLabel(new SilhouetteIcon(FONT, str, SIZE)); | |
l.setOpaque(false); | |
l.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.BLACK)); | |
return l; | |
} | |
public static void main(String[] args) { | |
EventQueue.invokeLater(new Runnable() { | |
@Override public void run() { | |
createAndShowGUI(); | |
} | |
}); | |
} | |
public static void createAndShowGUI() { | |
JFrame frame = new JFrame(); | |
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | |
frame.getContentPane().add(new MainPanel().makeUI()); | |
frame.setSize(320, 240); | |
frame.setLocationRelativeTo(null); | |
frame.setVisible(true); | |
} | |
} | |
class SilhouetteIcon implements Icon, Serializable { | |
private static final long serialVersionUID = 1L; | |
private static final Color PIECE_PAINT = new Color(150, 100, 20); | |
private final Font font; | |
private final String str; | |
private final int size; | |
public SilhouetteIcon(Font font, String str, int size) { | |
this.font = font; | |
this.str = str; | |
this.size = size; | |
} | |
private static Area getOuterShape(Shape shape) { | |
Area area = new Area(); | |
Path2D.Double path = new Path2D.Double(); | |
PathIterator pi = shape.getPathIterator(null); | |
double[] coords = new double[6]; | |
while (!pi.isDone()) { | |
int pathSegmentType = pi.currentSegment(coords); | |
switch (pathSegmentType) { | |
case PathIterator.SEG_MOVETO: | |
path.moveTo(coords[0], coords[1]); | |
break; | |
case PathIterator.SEG_LINETO: | |
path.lineTo(coords[0], coords[1]); | |
break; | |
case PathIterator.SEG_QUADTO: | |
path.quadTo(coords[0], coords[1], coords[2], coords[3]); | |
break; | |
case PathIterator.SEG_CUBICTO: | |
path.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); | |
break; | |
case PathIterator.SEG_CLOSE: | |
path.closePath(); | |
area.add(new Area(path)); | |
path.reset(); | |
break; | |
default: | |
System.err.println("Unexpected value! " + pathSegmentType); | |
break; | |
} | |
pi.next(); | |
} | |
return area; | |
} | |
@Override public void paintIcon(Component c, Graphics g, int x, int y) { | |
Graphics2D g2 = (Graphics2D) g.create(); | |
g2.translate(x, y); | |
//g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
FontRenderContext frc = g2.getFontRenderContext(); | |
Shape shape = font.createGlyphVector(frc, str).getOutline(); | |
Rectangle r = shape.getBounds(); | |
int sx = getIconWidth() - r.width; | |
int sy = getIconHeight() - r.height; | |
AffineTransform at = AffineTransform.getTranslateInstance(-r.x + sx / 2, -r.y + sy / 2); | |
Shape shapeCentered = at.createTransformedShape(shape); | |
Shape silhouette = getOuterShape(shapeCentered); | |
g2.setPaint(Color.BLACK); | |
Area aa = new Area(silhouette); | |
aa.exclusiveOr(new Area(shapeCentered)); | |
g2.fill(aa); | |
//g2.setStroke(new BasicStroke(1.6f)); | |
//g2.setPaint(Color.WHITE); | |
//g2.fill(shapeCentered); | |
//g2.draw(shapeCentered); | |
g2.dispose(); | |
} | |
@Override public int getIconWidth() { | |
return size; | |
} | |
@Override public int getIconHeight() { | |
return size; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment