在标签中“填充”Unicode字符 [英] 'Fill' Unicode characters in labels

查看:179
本文介绍了在标签中“填充”Unicode字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Swing中填写标签中的Unicode字符?





我试图为国际象棋程序制作一个用户界面,我最近编程了
(象上面看到的棋子)。在其中我使用unicode字符来表示我的棋子( \\\♔ 通过 \\\♟ )。 / p>

问题如下:



当我设置我的棋子的背景 JLabel 到像白色这样的东西,整个标签被填充(在我的例子是一个50×50像素的白色,上面的字符)。这导致我的作品看起来像瓷砖而不是他们的照片。



当我将标签设置为不透明,我只是得到一个饼干版本的我的棋子,不是一个与它的内部充满。 EG





有没有办法只填充字符?



如果不是我想我会制作一个精灵表,但我喜欢这样,我可以使用棋子的 toString()方法为标签。



代码



  import java.awt。*; 
import javax.swing。*;
import java.util.Random;

class ChessBoard {

static Font font = new Font(Sans-Serif,Font.PLAIN,50);
static Random rnd = new Random();

public static void addUnicodeCharToContainer(
String s,Container c,boolean randomColor){

JLabel l = new JLabel(s);
l.setFont(font);
if(randomColor){
int r = rnd.nextInt(255);
int g = rnd.nextInt(255);
int b = rnd.nextInt(255);

l.setForeground(new Color(r,g,b));
l.setBackground(new Color(255-r,255-g,255-b));
l.setOpaque(true);
}
c.add(l);
}

public static void main(String [] args){
Runnable r = new Runnable(){

@Override
public void run(){
JPanel gui = new JPanel(new GridLayout(0,6,4,4));

String [] pieces = {
\\\♔,\\\♕,\\\♖,\\\♗,\\\♘ \\ u2659,
\\\♚,\\\♛,\\\♜,\\\♝,\\\♞,\\\♟
}

for(String piece:pieces){
addUnicodeCharToContainer(piece,gui,false);
}
for(String piece:pieces){
addUnicodeCharToContainer(piece,gui,true);
}

JOptionPane.showMessageDialog(null,gui);
}
};
SwingUtilities.invokeLater(r);
}
}


解决方案

img src =https://i.stack.imgur.com/21xA8.pngalt =棋子>



这两行是通过巫术生成的的Java-2D。诀窍是:




  • 忽略黑色棋子,因为我们的颜色实际上来自形状'。

  • 创建一个 GlyphVector ,表示字符的形状。这对于Java-2D中的进一步操作很重要。

  • 创建 Rectangle 图片大小。

  • subtract()从图像形状中减去字符的形状。


  • 用背景颜色填充区域,但 跳过单个区域 ,0.0(表示最外层区域,我们需要透明)。

  • 最后,使用大纲颜色填充字符本身的形状。



代码



  import java.awt。*; 
import java.awt.font。*;
import java.awt.geom。*;
import java.awt.image.BufferedImage;
import javax.swing。*;
import java.util。*;

class ChessBoard {

static Font font = new Font(Sans-Serif,Font.PLAIN,50);
static Random rnd = new Random();

public static ArrayList< Shape> separateShapeIntoRegions(Shape shape){
ArrayList< Shape> regions = new ArrayList< Shape>();

PathIterator pi = shape.getPathIterator(null);
int ii = 0;
GeneralPath gp = new GeneralPath();
while(!pi.isDone()){
double [] coords = new double [6];
int pathSegmentType = pi.currentSegment(coords);
int windingRule = pi.getWindingRule();
gp.setWindingRule(windingRule);
if(pathSegmentType == PathIterator.SEG_MOVETO){
gp = new GeneralPath();
gp.setWindingRule(windingRule);
gp.moveTo(coords [0],coords [1]);
System.out.println(ii ++ +\t+ coords [0] +,+ coords [1]);
} else if(pathSegmentType == PathIterator.SEG_LINETO){
gp.lineTo(coords [0],coords [1]);
} else if(pathSegmentType == PathIterator.SEG_QUADTO){
gp.quadTo(coords [0],coords [1],coords [2],coords [3]);
} else if(pathSegmentType == PathIterator.SEG_CUBICTO){
gp.curveTo(
coords [0],coords [1],
coords [2],coords [3] ],
coords [4],coords [5]);
} else if(pathSegmentType == PathIterator.SEG_CLOSE){
gp.closePath();
regions.add(new Area(gp));
} else {
System.err.println(Unexpected value!+ pathSegmentType);
}

pi.next();
}

返回地区;
}

public static void addColoredUnicodeCharToContainer(
String s,Container c,
Color bgColor,Color outlineColor,boolean blackSquare){

int sz = font.getSize();
BufferedImage bi = new BufferedImage(
sz,sz,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(
RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
g.setRenderingHint(
RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc,s);
Rectangle2D box1 = gv.getVisualBounds();

Shape shape1 = gv.getOutline();
Rectangle r = shape1.getBounds();
System.out.println(shape rect:+ r);
int spaceX = sz - r.width;
int spaceY = sz - r.height;
AffineTransform trans = AffineTransform.getTranslateInstance(
-r.x +(spaceX / 2),-r.y +(spaceY / 2));
System.out.println(Box2D+ trans);

形状shapeCentered = trans.createTransformedShape(shape1);

Shape imageShape = new Rectangle2D.Double(0,0,sz,sz);
区域imageShapeArea =新区域(imageShape);
area shapeArea = new Area(shapeCentered);
imageShapeArea.subtract(shapeArea);
ArrayList< Shape> regions = separateShapeIntoRegions(imageShapeArea);
g.setStroke(new BasicStroke(1));
for(Shape region:regions){
Rectangle r1 = region.getBounds();
if(r1.getX()< 0.001&& r1.getY()< 0.001){
} else {
g.setColor(bgColor);
g.fill(region);
}
}
g.setColor(outlineColor);
g.fill(shapeArea);
g.dispose();

JLabel l = new JLabel(new ImageIcon(bi),JLabel.CENTER);
颜色bg =(blackSquare?Color.BLACK:Color.WHITE);
l.setBackground(bg);
l.setOpaque(true);
c.add(l);
}

public static void main(String [] args){
Runnable r = new Runnable(){

@Override
public void run(){
JPanel gui = new JPanel(new GridLayout(0,6,4,4));

String [] pieces = {
\\\♔,\\\♕,\\\♖,\\\♗,\\\♘ \\ u2659
};

boolean blackSquare = false;
for(String piece:pieces){
addColoredUnicodeCharToContainer(
piece,gui,
new Color(203,203,197),
Color.DARK_GRAY,
blackSquare) ;
blackSquare =!blackSquare;
}
blackSquare =!blackSquare;
for(String piece:pieces){
addColoredUnicodeCharToContainer(
piece,gui,
new Color(192,142,60),
Color.DARK_GRAY,
blackSquare);
blackSquare =!blackSquare;
}

JOptionPane.showMessageDialog(null,gui);
}
};
SwingUtilities.invokeLater(r);
}
}



棋盘



这可能是一个(11.64Kb)。



(13.44Kb)。





Sprite Set



  import java.awt。*; 
import java.awt.font。*;
import java.awt.geom。*;
import java.awt.image.BufferedImage;
import javax.swing。*;
import javax.swing.border。*;

import java.io. *;
import javax.imageio.ImageIO;
import java.util。*;
import java.util.logging。*;

class ChessBoard {

/ **
*棋子的Unicodes。
* /
static final String [] pieces = {
\\\♔,\\\♕,\\\♖,\\\♗,\\\♘ ,\\\♙
};
static final int KING = 0,QUEEN = 1,CASTLE = 2,
BISHOP = 3,KNIGHT = 4,PAWN = 5;
public static final int [] order = new int [] {
CASTLE,KNIGHT,BISHOP,QUEEN,KING,BISHOP,KNIGHT,CASTLE
};

/ *
*颜色..
* /
public static final颜色outlineColor = Color.DARK_GRAY;
public static final Color [] pieceColors = {
new Color(203,203,197),new Color(192,142,60)
};
static final int WHITE = 0,BLACK = 1;

/ *
*字体。图像使用字体sizeXsize。
* /
static Font font = new Font(Sans-Serif,Font.PLAIN,64);

public static ArrayList< Shape> separateShapeIntoRegions(Shape shape){
ArrayList< Shape> regions = new ArrayList< Shape>();

PathIterator pi = shape.getPathIterator(null);
int ii = 0;
GeneralPath gp = new GeneralPath();
while(!pi.isDone()){
double [] coords = new double [6];
int pathSegmentType = pi.currentSegment(coords);
int windingRule = pi.getWindingRule();
gp.setWindingRule(windingRule);
if(pathSegmentType == PathIterator.SEG_MOVETO){
gp = new GeneralPath();
gp.setWindingRule(windingRule);
gp.moveTo(coords [0],coords [1]);
} else if(pathSegmentType == PathIterator.SEG_LINETO){
gp.lineTo(coords [0],coords [1]);
} else if(pathSegmentType == PathIterator.SEG_QUADTO){
gp.quadTo(coords [0],coords [1],coords [2],coords [3]);
} else if(pathSegmentType == PathIterator.SEG_CUBICTO){
gp.curveTo(
coords [0],coords [1],
coords [2],coords [3 ],
coords [4],coords [5]);
}其他if(pathSegmentType == PathIterator.SEG_CLOSE){
gp.closePath();
regions.add(new Area(gp));
} else {
System.err.println(Unexpected value!+ pathSegmentType);
}

pi.next();
}

返回地区;
}

public static BufferedImage getImageForChessPiece(
int piece,int side,boolean gradient){
int sz = font.getSize();
BufferedImage bi = new BufferedImage(
sz,sz,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(
RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
g.setRenderingHint(
RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc,pieces [piece]);
Rectangle2D box1 = gv.getVisualBounds();

Shape shape1 = gv.getOutline();
Rectangle r = shape1.getBounds();
int spaceX = sz - r.width;
int spaceY = sz - r.height;
AffineTransform trans = AffineTransform.getTranslateInstance(
-r.x +(spaceX / 2),-r.y +(spaceY / 2));

形状shapeCentered = trans.createTransformedShape(shape1);

Shape imageShape = new Rectangle2D.Double(0,0,sz,sz);
区域imageShapeArea =新区域(imageShape);
area shapeArea = new Area(shapeCentered);
imageShapeArea.subtract(shapeArea);
ArrayList< Shape> regions = separateShapeIntoRegions(imageShapeArea);
g.setStroke(new BasicStroke(1));
g.setColor(pieceColors [side]);
color baseColor = pieceColors [side];
if(gradient){
颜色c1 = baseColor.brighter();
颜色c2 = baseColor;
GradientPaint gp = new GradientPaint(
sz / 2-(r.width / 4),sz / 2-(r.height / 4),c1,
sz / 2 + .width / 4),sz / 2 +(r.height / 4),c2,
false);
g.setPaint(gp);
} else {
g.setColor(baseColor);
}

(Shape region:regions){
Rectangle r1 = region.getBounds();
if(r1.getX()< 0.001&& r1.getY()< 0.001){
} else {
g.fill(region);
}
}
g.setColor(outlineColor);
g.fill(shapeArea);
g.dispose();

return bi;
}

public static void addColoredUnicodeCharToContainer(
Container c,
int piece,
int side,
color bg,
boolean gradient){

JLabel l = new JLabel(
new ImageIcon(getImageForChessPiece(piece,side,gradient)),
JLabel.CENTER);
l.setBackground(bg);
l.setOpaque(true);
c.add(l);
}

public static void addPiecesToContainer(
Container c,
int intialSquareColor,
int side,
int [] pieces,
boolean gradient){

for(int piece:pieces){
addColoredUnicodeCharToContainer(
c,piece,side,
intialSquareColor ++%2 == BLACK? BLACK:Color.WHITE,
gradient);
}
}

public static void addPiecesToContainer(
Container c,
Color bg,
int side,
int [ ] piece,
boolean gradient){

for(int piece:pieces){
addColoredUnicodeCharToContainer(
c,piece,side,bg,gradient);
}
}

public static void addBlankLabelRow(Container c,int initialSquareColor){
for(int ii = 0; ii <8; ii ++){
JLabel l = new JLabel();
颜色bg =(initialSquareColor ++%2 == BLACK
?Color.BLACK:Color.WHITE);
l.setBackground(bg);
l.setOpaque(true);
c.add(l);
}
}

public static void main(String [] args){
final int [] pawnRow = new int [] {
PAWN, PAWN,PAWN,PAWN,PAWN,PAWN,PAWN,PAWN
};
Runnable r = new Runnable(){

@Override
public void run(){
int gradient = JOptionPane.showConfirmDialog(
null,使用渐变线色?);
boolean gradientFill = gradient == JOptionPane.OK_OPTION;
JPanel gui = new JPanel(new GridLayout(0,8,0,0));
gui.setBorder(new BevelBorder(
BevelBorder.LOWERED,
Color.GRAY.brighter(),Color.GRAY,
Color.GRAY.darker(),Color.GRAY ));
//设置一个棋盘
addPiecesToContainer(gui,WHITE,BLACK,order,gradientFill);
addPiecesToContainer(gui,BLACK,BLACK,pawnRow,gradientFill);

addBlankLabelRow(gui,WHITE);
addBlankLabelRow(gui,BLACK);
addBlankLabelRow(gui,WHITE);
addBlankLabelRow(gui,BLACK);

addPiementsToContainer(gui,WHITE,WHITE,pawnRow,gradientFill);
addPiecesToContainer(gui,BLACK,WHITE,order,gradientFill);

JOptionPane.showMessageDialog(
null,
gui,
Chessboard,
JOptionPane.INFORMATION_MESSAGE);

JPanel tileSet = new JPanel(new GridLayout(0,6,0,0));
tileSet.setOpaque(false);
int [] tileSetOrder = new int [] {
KING,QUEEN,CASTLE,KNIGHT,BISHOP,PAWN
};
addPiecesToContainer(
tileSet,
new Color(0,0,0,0),
BLACK,
tileSetOrder,
gradientFill);
addPiecesToContainer(
tileSet,
new Color(0,0,0,0),
WHITE,
tileSetOrder,
gradientFill);
int result = JOptionPane.showConfirmDialog(
null,
tileSet,
Save this tileset?,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE) ;
if(result == JOptionPane.OK_OPTION){
BufferedImage bi = new BufferedImage(
tileSet.getWidth(),
tileSet.getHeight(),
BufferedImage。 TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
tileSet.paint(g);
g.dispose();

String gradientString = gradientFill? gradient:solid;
File f = new File(
chess-pieces-tileset-+ gradientString +.png);
try {
ImageIO.write(bi,png,f);
Desktop.getDesktop()。open(f);
} catch(IOException ex){
Logger.getLogger(
ChessBoard.class.getName())。log(
Level.SEVERE,null,ex);
}
}
}
};
SwingUtilities.invokeLater(r);
}
}



另请参阅




  • 开发出 GlyphVector 代码,如。




How to 'fill' Unicode characters in labels in Swing?

I'm trying to make a user interface for the chess program I've recently programmed (with chess pieces something like seen above). In it I'm using unicode characters to represent my chess pieces (\u2654 through \u265F).

The problem is as follows:

When I set the background of my chess piece JLabel to something like white, the entire label is filled (in my case it's a 50*50px square of white with the character on top). This leads to my pieces looking like tiles instead of just their pictures.

When I set the label to opaque, I just get a cookie cutter version of my chess piece, not one with its insides filled. E.G.

Is there a way to fill only the character?

If not I guess I'll make a sprite sheet but I like this because I can use the chess pieces' toString() methods for the labels.

Code

import java.awt.*;
import javax.swing.*;
import java.util.Random;

class ChessBoard {

    static Font font = new Font("Sans-Serif", Font.PLAIN, 50);
    static Random rnd = new Random();

    public static void addUnicodeCharToContainer(
        String s, Container c, boolean randomColor) {

        JLabel l = new JLabel(s);
        l.setFont(font);
        if (randomColor) {
            int r = rnd.nextInt(255);
            int g = rnd.nextInt(255);
            int b = rnd.nextInt(255);

            l.setForeground(new Color(r,g,b));
            l.setBackground(new Color(255-r,255-g,255-b));
            l.setOpaque(true);
        }
        c.add(l);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new GridLayout(0,6,4,4));

                String[] pieces = {
                    "\u2654","\u2655","\u2656","\u2657","\u2658","\u2659",
                    "\u265A","\u265B","\u265C","\u265D","\u265E","\u265F"
                };

                for (String piece : pieces) {
                    addUnicodeCharToContainer(piece,gui,false);
                }
                for (String piece : pieces) {
                    addUnicodeCharToContainer(piece,gui,true);
                }

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

解决方案

The two rows are generated through the sorcery of Java-2D. The trick is to:

  • Ignore the 'black' chess pieces on the basis that our color is actually coming from 'the spaces contained by the shape'. Those are larger in the white chess pieces.
  • Create a GlyphVector that represents the shape of the character. This is important for further operations in Java-2D.
  • Create a Rectangle the size of the image.
  • subtract() the shape of the character from the shape of the image.
  • Break that altered shape into regions.
  • Fill the regions with the background color, but skip the single region that starts at 0.0,0.0 (representing the outermost region which we need transparent).
  • Finally, fill the shape of the character itself using the outline color.

Code

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.util.*;

class ChessBoard {

    static Font font = new Font("Sans-Serif", Font.PLAIN, 50);
    static Random rnd = new Random();

    public static ArrayList<Shape> separateShapeIntoRegions(Shape shape) {
        ArrayList<Shape> regions = new ArrayList<Shape>();

        PathIterator pi = shape.getPathIterator(null);
        int ii = 0;
        GeneralPath gp = new GeneralPath();
        while (!pi.isDone()) {
            double[] coords = new double[6];
            int pathSegmentType = pi.currentSegment(coords);
            int windingRule = pi.getWindingRule();
            gp.setWindingRule(windingRule);
            if (pathSegmentType == PathIterator.SEG_MOVETO) {
                gp = new GeneralPath();
                gp.setWindingRule(windingRule);
                gp.moveTo(coords[0], coords[1]);
                System.out.println(ii++ + " \t" + coords[0] + "," + coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_LINETO) {
                gp.lineTo(coords[0], coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_QUADTO) {
                gp.quadTo(coords[0], coords[1], coords[2], coords[3]);
            } else if (pathSegmentType == PathIterator.SEG_CUBICTO) {
                gp.curveTo(
                        coords[0], coords[1],
                        coords[2], coords[3],
                        coords[4], coords[5]);
            } else if (pathSegmentType == PathIterator.SEG_CLOSE) {
                gp.closePath();
                regions.add(new Area(gp));
            } else {
                System.err.println("Unexpected value! " + pathSegmentType);
            }

            pi.next();
        }

        return regions;
    }

    public static void addColoredUnicodeCharToContainer(
            String s, Container c,
            Color bgColor, Color outlineColor, boolean blackSquare) {

        int sz = font.getSize();
        BufferedImage bi = new BufferedImage(
                sz, sz, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = bi.createGraphics();
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(
                RenderingHints.KEY_DITHERING,
                RenderingHints.VALUE_DITHER_ENABLE);
        g.setRenderingHint(
                RenderingHints.KEY_ALPHA_INTERPOLATION,
                RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

        FontRenderContext frc = g.getFontRenderContext();
        GlyphVector gv = font.createGlyphVector(frc, s);
        Rectangle2D box1 = gv.getVisualBounds();

        Shape shape1 = gv.getOutline();
        Rectangle r = shape1.getBounds();
        System.out.println("shape rect: " + r);
        int spaceX = sz - r.width;
        int spaceY = sz - r.height;
        AffineTransform trans = AffineTransform.getTranslateInstance(
                -r.x + (spaceX / 2), -r.y + (spaceY / 2));
        System.out.println("Box2D " + trans);

        Shape shapeCentered = trans.createTransformedShape(shape1);

        Shape imageShape = new Rectangle2D.Double(0, 0, sz, sz);
        Area imageShapeArea = new Area(imageShape);
        Area shapeArea = new Area(shapeCentered);
        imageShapeArea.subtract(shapeArea);
        ArrayList<Shape> regions = separateShapeIntoRegions(imageShapeArea);
        g.setStroke(new BasicStroke(1));
        for (Shape region : regions) {
            Rectangle r1 = region.getBounds();
            if (r1.getX() < 0.001 && r1.getY() < 0.001) {
            } else {
                g.setColor(bgColor);
                g.fill(region);
            }
        }
        g.setColor(outlineColor);
        g.fill(shapeArea);
        g.dispose();

        JLabel l = new JLabel(new ImageIcon(bi), JLabel.CENTER);
        Color bg = (blackSquare ? Color.BLACK : Color.WHITE);
        l.setBackground(bg);
        l.setOpaque(true);
        c.add(l);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new GridLayout(0, 6, 4, 4));

                String[] pieces = {
                    "\u2654", "\u2655", "\u2656", "\u2657", "\u2658", "\u2659"
                };

                boolean blackSquare = false;
                for (String piece : pieces) {
                    addColoredUnicodeCharToContainer(
                            piece, gui,
                            new Color(203,203,197),
                            Color.DARK_GRAY,
                            blackSquare);
                            blackSquare = !blackSquare;
                }
                            blackSquare = !blackSquare;
                for (String piece : pieces) {
                    addColoredUnicodeCharToContainer(
                            piece, gui,
                            new Color(192,142,60),
                            Color.DARK_GRAY,
                            blackSquare);
                            blackSquare = !blackSquare;
                }

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Chess Board

This is what it might look like as a Chess Board (22.81 Kb).

Sprite sets

Sprite sets of chess pieces (64x64 pixel) rendered from Unicode characters - as a PNG with transparent BG. Each has 6 columns for the pieces x 2 rows for the opponents (total size 384x128 pixels).

Chess pieces with solid fill (bronze/pewter) (11.64Kb).

Chess pieces with gradient fill (gold/silver) (13.61Kb).

Chess pieces with gradient fill (darker cyan/magenta) (13.44Kb).

Code for Chess Board & Sprite Set

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import javax.imageio.ImageIO;
import java.util.*;
import java.util.logging.*;

class ChessBoard {

    /**
     * Unicodes for chess pieces.
     */
    static final String[] pieces = {
        "\u2654", "\u2655", "\u2656", "\u2657", "\u2658", "\u2659"
    };
    static final int KING = 0, QUEEN = 1, CASTLE = 2,
            BISHOP = 3, KNIGHT = 4, PAWN = 5;
    public static final int[] order = new int[]{
        CASTLE, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, CASTLE
    };

    /*
     * Colors..
     */
    public static final Color outlineColor = Color.DARK_GRAY;
    public static final Color[] pieceColors = {
        new Color(203, 203, 197), new Color(192, 142, 60)
    };
    static final int WHITE = 0, BLACK = 1;

    /*
     * Font. The images use the font sizeXsize.
     */
    static Font font = new Font("Sans-Serif", Font.PLAIN, 64);

    public static ArrayList<Shape> separateShapeIntoRegions(Shape shape) {
        ArrayList<Shape> regions = new ArrayList<Shape>();

        PathIterator pi = shape.getPathIterator(null);
        int ii = 0;
        GeneralPath gp = new GeneralPath();
        while (!pi.isDone()) {
            double[] coords = new double[6];
            int pathSegmentType = pi.currentSegment(coords);
            int windingRule = pi.getWindingRule();
            gp.setWindingRule(windingRule);
            if (pathSegmentType == PathIterator.SEG_MOVETO) {
                gp = new GeneralPath();
                gp.setWindingRule(windingRule);
                gp.moveTo(coords[0], coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_LINETO) {
                gp.lineTo(coords[0], coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_QUADTO) {
                gp.quadTo(coords[0], coords[1], coords[2], coords[3]);
            } else if (pathSegmentType == PathIterator.SEG_CUBICTO) {
                gp.curveTo(
                        coords[0], coords[1],
                        coords[2], coords[3],
                        coords[4], coords[5]);
            } else if (pathSegmentType == PathIterator.SEG_CLOSE) {
                gp.closePath();
                regions.add(new Area(gp));
            } else {
                System.err.println("Unexpected value! " + pathSegmentType);
            }

            pi.next();
        }

        return regions;
    }

    public static BufferedImage getImageForChessPiece(
            int piece, int side, boolean gradient) {
        int sz = font.getSize();
        BufferedImage bi = new BufferedImage(
                sz, sz, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = bi.createGraphics();
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(
                RenderingHints.KEY_DITHERING,
                RenderingHints.VALUE_DITHER_ENABLE);
        g.setRenderingHint(
                RenderingHints.KEY_ALPHA_INTERPOLATION,
                RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

        FontRenderContext frc = g.getFontRenderContext();
        GlyphVector gv = font.createGlyphVector(frc, pieces[piece]);
        Rectangle2D box1 = gv.getVisualBounds();

        Shape shape1 = gv.getOutline();
        Rectangle r = shape1.getBounds();
        int spaceX = sz - r.width;
        int spaceY = sz - r.height;
        AffineTransform trans = AffineTransform.getTranslateInstance(
                -r.x + (spaceX / 2), -r.y + (spaceY / 2));

        Shape shapeCentered = trans.createTransformedShape(shape1);

        Shape imageShape = new Rectangle2D.Double(0, 0, sz, sz);
        Area imageShapeArea = new Area(imageShape);
        Area shapeArea = new Area(shapeCentered);
        imageShapeArea.subtract(shapeArea);
        ArrayList<Shape> regions = separateShapeIntoRegions(imageShapeArea);
        g.setStroke(new BasicStroke(1));
        g.setColor(pieceColors[side]);
        Color baseColor = pieceColors[side];
        if (gradient) {
            Color c1 = baseColor.brighter();
            Color c2 = baseColor;
            GradientPaint gp = new GradientPaint(
                    sz/2-(r.width/4), sz/2-(r.height/4), c1, 
                    sz/2+(r.width/4), sz/2+(r.height/4), c2, 
                    false);
            g.setPaint(gp);
        } else {
            g.setColor(baseColor);
        }

        for (Shape region : regions) {
            Rectangle r1 = region.getBounds();
            if (r1.getX() < 0.001 && r1.getY() < 0.001) {
            } else {
                g.fill(region);
            }
        }
        g.setColor(outlineColor);
        g.fill(shapeArea);
        g.dispose();

        return bi;
    }

    public static void addColoredUnicodeCharToContainer(
            Container c,
            int piece,
            int side,
            Color bg,
            boolean gradient) {

        JLabel l = new JLabel(
                new ImageIcon(getImageForChessPiece(piece, side, gradient)),
                JLabel.CENTER);
        l.setBackground(bg);
        l.setOpaque(true);
        c.add(l);
    }

    public static void addPiecesToContainer(
            Container c,
            int intialSquareColor,
            int side,
            int[] pieces,
            boolean gradient) {

        for (int piece : pieces) {
            addColoredUnicodeCharToContainer(
                    c, piece, side,
                    intialSquareColor++%2 == BLACK ? Color.BLACK : Color.WHITE,
                    gradient);
        }
    }

    public static void addPiecesToContainer(
            Container c,
            Color bg,
            int side,
            int[] pieces,
            boolean gradient) {

        for (int piece : pieces) {
            addColoredUnicodeCharToContainer(
                    c, piece, side, bg, gradient);
        }
    }

    public static void addBlankLabelRow(Container c, int initialSquareColor) {
        for (int ii = 0; ii < 8; ii++) {
            JLabel l = new JLabel();
            Color bg = (initialSquareColor++ % 2 == BLACK
                    ? Color.BLACK : Color.WHITE);
            l.setBackground(bg);
            l.setOpaque(true);
            c.add(l);
        }
    }

    public static void main(String[] args) {
        final int[] pawnRow = new int[]{
            PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN
        };
        Runnable r = new Runnable() {

            @Override
            public void run() {
                int gradient = JOptionPane.showConfirmDialog(
                        null, "Use gradient fille color?");
                boolean gradientFill = gradient == JOptionPane.OK_OPTION;
                JPanel gui = new JPanel(new GridLayout(0, 8, 0, 0));
                gui.setBorder(new BevelBorder(
                        BevelBorder.LOWERED,
                        Color.GRAY.brighter(), Color.GRAY,
                        Color.GRAY.darker(), Color.GRAY));
                // set up a chess board
                addPiecesToContainer(gui, WHITE, BLACK, order, gradientFill);
                addPiecesToContainer(gui, BLACK, BLACK, pawnRow, gradientFill);

                addBlankLabelRow(gui, WHITE);
                addBlankLabelRow(gui, BLACK);
                addBlankLabelRow(gui, WHITE);
                addBlankLabelRow(gui, BLACK);

                addPiecesToContainer(gui, WHITE, WHITE, pawnRow, gradientFill);
                addPiecesToContainer(gui, BLACK, WHITE, order, gradientFill);

                JOptionPane.showMessageDialog(
                        null,
                        gui,
                        "Chessboard",
                        JOptionPane.INFORMATION_MESSAGE);

                JPanel tileSet = new JPanel(new GridLayout(0, 6, 0, 0));
                tileSet.setOpaque(false);
                int[] tileSetOrder = new int[]{
                    KING, QUEEN, CASTLE, KNIGHT, BISHOP, PAWN
                };
                addPiecesToContainer(
                        tileSet,
                        new Color(0, 0, 0, 0),
                        BLACK,
                        tileSetOrder, 
                        gradientFill);
                addPiecesToContainer(
                        tileSet,
                        new Color(0, 0, 0, 0),
                        WHITE,
                        tileSetOrder, 
                        gradientFill);
                int result = JOptionPane.showConfirmDialog(
                        null,
                        tileSet,
                        "Save this tileset?",
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE);
                if (result == JOptionPane.OK_OPTION) {
                    BufferedImage bi = new BufferedImage(
                            tileSet.getWidth(),
                            tileSet.getHeight(),
                            BufferedImage.TYPE_INT_ARGB);
                    Graphics g = bi.createGraphics();
                    tileSet.paint(g);
                    g.dispose();

                    String gradientString = gradientFill ? "gradient" : "solid";
                    File f = new File(
                            "chess-pieces-tileset-" + gradientString + ".png");
                    try {
                        ImageIO.write(bi, "png", f);
                        Desktop.getDesktop().open(f);
                    } catch (IOException ex) {
                        Logger.getLogger(
                                ChessBoard.class.getName()).log(
                                Level.SEVERE, null, ex);
                    }
                }
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

See also

  • Developed out of the GlyphVector code as seen in this answer.

这篇关于在标签中“填充”Unicode字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆