英文:
How Do I Create Dot Matrix Digits using Java Swing
问题
如何为时钟项目制作5 x 7点阵类型的数字呢?
以下是我所寻找的示例。
我手动编写了每个数字中每个点的位置。
是否有更好的方法来创建点阵数字?
更好的意思是编码更简单,验证更容易,利用现有字体或其他组件,或者其他有经验的Swing开发者可能考虑的重要因素。
剩下的问题是对那些声称我没有足够努力地构思问题的人提供背景信息。
由于我正在为这个问题提供一个答案,所以我不会在问题中发布虚假的糟糕代码。当然,当人们展示他们的努力时,我们会很感激。在我看来,答案中的代码和文本应该为问题提供补充说明。
就在几天前,就在我写这篇文章的时候,有人发了一个关于制作带有点阵数字的时钟的问题。提问者提供了代码和他们所创建内容的图片。这个人创建了一个BufferedImage
,在其中硬编码了他的4 x 7点阵数字中每个方形点的位置。
我对这个人在他的BufferedImage
中投入了多少工作感到印象深刻,所以我去我的Eclipse里研究如何将他的工作泛化。
当我离开的时候,人们评论并关闭了他的问题。等我带着我的答案回来时,这个人已经删除了他的问题。
因为我认为我有一个很好的答案,所以我搜索了一个适当的问题。当我没有找到一个适当的问题时,我就创造了一个问题。
当然,我更注重我的答案而不是我的问题。我真是傻了,我以为答案会帮助为问题提供背景。
嗯,我希望这个解释能更多地解释为什么我认为这个主题重要到足以创建一个问题并寻求答案。
英文:
How can I produce 5 x 7 dot matrix type digits for a clock project?
Here's an example of what I'm looking for.
I manually coded the position of each dot in each digit.
Is there a better way to create dot matrix digits?
By better I mean easier to code, easier to verify, makes use of existing fonts or other components, or anything else an experienced Swing developer might consider as an important consideration.
The rest of this question is the context for the naysayers that claim I didn't put enough effort into formulating my question.
Since I'm providing an answer to this question, I'm not posting fake bad code in the question. Sure, we appreciate it when people show their efforts. The code and text in my answer should supplement the question, in my opinion.
A few days ago, as I'm writing this, someone posted a question about making a clock with dot-matrix digits. The person posting the question provided code and a picture of what they had created. The person had created a BufferedImage
where they had hardcoded the position of each square dot in his 4 x 7 dot matrix digits.
I was impressed with how much work the person had put into his BufferedImage
, so I went off to my Eclipse to figure out how to generalize what he had done.
While I was away, people commented and closed his question. By the time I got back with my answer, the person had deleted his question.
Since I had what I thought was a good answer, I searched for an appropriate question. When I didn't find an appropriate question, I created a question.
Sure, I focused more on my answer than my question. Silly me, I thought that the answer would help provide context for the question.
Well, I hope that this explanation sheds some more light on why I thought this topic was important enough to create a question and ask for answers.
答案1
得分: 4
很抱歉,由于你的要求,我只能返回翻译好的代码部分,以下是代码的翻译内容:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DotMatrixDigits implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DotMatrixDigits());
}
@Override
public void run() {
JFrame frame = new JFrame("Dot Matrix Digits");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(defineTopPanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(defineBottomPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel defineTopPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(0, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(1, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(2, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(3, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(4, Color.YELLOW, Color.BLACK));
return panel;
}
private JPanel defineBottomPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(5, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(6, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(7, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(8, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(9, Color.YELLOW, Color.BLACK));
return panel;
}
public class DotMatrixDigit extends JPanel {
private static final long serialVersionUID = 1L;
private int digit;
private int dotWidth;
private int pixelWidth;
private int margin;
private final Color dotColor;
private int[][][] matrices;
public DotMatrixDigit(int digit, Color dotColor, Color backgroundColor) {
this.digit = digit;
this.dotColor = dotColor;
this.dotWidth = 10;
this.pixelWidth = 15;
this.margin = dotWidth;
this.matrices = defineDigitMatrices();
int width = 4 * pixelWidth + dotWidth + margin + margin;
int height = 6 * pixelWidth + dotWidth + margin + margin;
this.setBackground(backgroundColor);
this.setPreferredSize(new Dimension(width, height));
}
private int[][][] defineDigitMatrices() {
int[][][] matrices = new int[10][][];
matrices[0] = defineZeroMatrix();
matrices[1] = defineOneMatrix();
matrices[2] = defineTwoMatrix();
matrices[3] = defineThreeMatrix();
matrices[4] = defineFourMatrix();
matrices[5] = defineFiveMatrix();
matrices[6] = defineSixMatrix();
matrices[7] = defineSevenMatrix();
matrices[8] = defineEightMatrix();
matrices[9] = defineNineMatrix();
return matrices;
}
private int[][] defineZeroMatrix() {
// ...
}
// Other define methods...
public void setDigit(int digit) {
this.digit = digit;
this.repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(dotColor);
for (int row = 0; row < matrices[digit].length; row++) {
for (int column = 0; column < matrices[digit][row].length; column++) {
if (matrices[digit][row][column] != 0) {
int x = margin + column * pixelWidth;
int y = margin + row * pixelWidth;
g.fillOval(x, y, dotWidth, dotWidth);
}
}
}
}
}
}
注意:由于我不能回答关于翻译的问题,如果你有其他问题或需要进一步帮助,请随时提问。
英文:
Unfortunately, you have to code the position of each dot in each digit.
However, you can do this in a flexible way.
Here's what I mean. A 5 x 7 dot matrix digit can be represented as a two-dimensional int
array. It could also be represented as a boolean
array, but a matrix of 0 and 1 values is easier to visually verify.
As an example. here's a method to code the zero digit. You can see that the ones create a visual outline that can be easily verified.
private int[][] defineZeroMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 1, 0, 0, 0, 1 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
It took me about 15 minutes to code all of the dot matrix digit matrices.
It's possible to code a dot matrix digit using a sparse matrix. Unfortunately, that idea leads to more code that's visually harder to verify.
Here's an example of the dot matrix digit two coded as a sparse matrix of coordinates.
private Point[] defineTwoCoordinates() {
Point[] array = new Point[14];
array[0] = new Point(0, 1);
array[1] = new Point(1, 0);
array[2] = new Point(2, 0);
array[3] = new Point(3, 0);
array[4] = new Point(4, 1);
array[5] = new Point(4, 2);
array[6] = new Point(3, 3);
array[7] = new Point(2, 4);
array[8] = new Point(1, 5);
array[9] = new Point(0, 6);
array[10] = new Point(1, 6);
array[11] = new Point(2, 6);
array[12] = new Point(3, 6);
array[13] = new Point(4, 6);
return array;
}
After we've coded all of the digit matrices, we'll create an array of matrices.
private int[][][] matrices;
The leftmost index is the digit, from 0 to 9. The second index is the row of the digit matrix. The third index is the column of the digit matrix.
Finally, we extend a JPanel
and override the paintComponent
method to actually paint the dot matrix digit.
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(dotColor);
for (int row = 0; row < matrices[digit].length; row++) {
for (int column = 0; column < matrices[digit][row].length; column++) {
if (matrices[digit][row][column] != 0) {
int x = margin + column * pixelWidth;
int y = margin + row * pixelWidth;
g.fillOval(x, y, dotWidth, dotWidth);
}
}
}
}
Here's a complete runnable example of how you would create a dot matrix digit panel by extending a JPanel
, and use several dot matrix digit panels to create whatever GUI you want.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DotMatrixDigits implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DotMatrixDigits());
}
@Override
public void run() {
JFrame frame = new JFrame("Dot Matrix Digits");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(defineTopPanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(defineBottomPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel defineTopPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(0, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(1, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(2, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(3, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(4, Color.YELLOW, Color.BLACK));
return panel;
}
private JPanel defineBottomPanel() {
JPanel panel = new JPanel();
panel.add(new DotMatrixDigit(5, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(6, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(7, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(8, Color.YELLOW, Color.BLACK));
panel.add(new DotMatrixDigit(9, Color.YELLOW, Color.BLACK));
return panel;
}
/**
* <p>
* The <code>DotMatrixDigit</code> class creates a dot-matrix digit panel by
* extending <code>JPanel</code>. The dot matrix digit is 5 positions across and
* 7 positions down. The size of the dot and distance between dots are defined
* in the constructor of this class. The shape of the dot is determined in the
* <code>paintComponent</code> method.
* </p>
*
* @author Gilbert G. Le Blanc
* @version 1.8 - 20 October 2020
*
* @see JPanel
* @see Color
*/
public class DotMatrixDigit extends JPanel {
private static final long serialVersionUID = 1L;
/** int field to hold the digit to display **/
private int digit;
/** int field to hold the width of the dot in pixels **/
private int dotWidth;
/** int field to hold the distance between the
* top left corner of the dots in pixels **/
private int pixelWidth;
/** int field to hold the margin size in
* pixels surrounding the digit **/
private int margin;
private final Color dotColor;
private int[][][] matrices;
/**
* <p>
* This constructor creates a dot matrix digit panel. The preferred size of the
* panel is determined by the pixel width of each dot, including the space
* between the dots.
* </p>
*
* @param digit - The initial digit to display from 0 through 9.
* @param dotColor - The <code>Color</code> of the dots.
* @param backgroundColor - The background <code>Color</code> of the dot matrix
* digit panel.
*
*/
public DotMatrixDigit(int digit, Color dotColor, Color backgroundColor) {
this.digit = digit;
this.dotColor = dotColor;
this.dotWidth = 10;
this.pixelWidth = 15;
this.margin = dotWidth;
this.matrices = defineDigitMatricies();
int width = 4 * pixelWidth + dotWidth + margin + margin;
int height = 6 * pixelWidth + dotWidth + margin + margin;
this.setBackground(backgroundColor);
this.setPreferredSize(new Dimension(width, height));
}
private int[][][] defineDigitMatricies() {
int[][][] matrices = new int[10][][];
matrices[0] = defineZeroMatrix();
matrices[1] = defineOneMatrix();
matrices[2] = defineTwoMatrix();
matrices[3] = defineThreeMatrix();
matrices[4] = defineFourMatrix();
matrices[5] = defineFiveMatrix();
matrices[6] = defineSixMatrix();
matrices[7] = defineSevenMatrix();
matrices[8] = defineEightMatrix();
matrices[9] = defineNineMatrix();
return matrices;
}
private int[][] defineZeroMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 1, 0, 0, 0, 1 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineOneMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 0, 1, 0, 0 };
matrix[1] = new int[] { 0, 1, 1, 0, 0 };
matrix[2] = new int[] { 1, 0, 1, 0, 0 };
matrix[3] = new int[] { 0, 0, 1, 0, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 0, 1, 0, 0 };
matrix[6] = new int[] { 1, 1, 1, 1, 1 };
return matrix;
}
private int[][] defineTwoMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 0, 1, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 1, 0, 0, 0 };
matrix[6] = new int[] { 1, 1, 1, 1, 1 };
return matrix;
}
private int[][] defineThreeMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 1, 1, 0 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineFourMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 0, 0, 1, 0 };
matrix[1] = new int[] { 0, 0, 1, 1, 0 };
matrix[2] = new int[] { 0, 1, 0, 1, 0 };
matrix[3] = new int[] { 1, 0, 0, 1, 0 };
matrix[4] = new int[] { 1, 1, 1, 1, 1 };
matrix[5] = new int[] { 0, 0, 0, 1, 0 };
matrix[6] = new int[] { 0, 0, 0, 1, 0 };
return matrix;
}
private int[][] defineFiveMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 1, 1, 1, 1, 1 };
matrix[1] = new int[] { 1, 0, 0, 0, 0 };
matrix[2] = new int[] { 1, 0, 0, 0, 0 };
matrix[3] = new int[] { 1, 1, 1, 1, 0 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineSixMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 0 };
matrix[3] = new int[] { 1, 1, 1, 1, 0 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineSevenMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 1, 1, 1, 1, 1 };
matrix[1] = new int[] { 0, 0, 0, 0, 1 };
matrix[2] = new int[] { 0, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 0, 0, 1, 0 };
matrix[4] = new int[] { 0, 0, 1, 0, 0 };
matrix[5] = new int[] { 0, 0, 1, 0, 0 };
matrix[6] = new int[] { 0, 0, 1, 0, 0 };
return matrix;
}
private int[][] defineEightMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 1, 1, 1, 0 };
matrix[4] = new int[] { 1, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
private int[][] defineNineMatrix() {
int[][] matrix = new int[7][];
matrix[0] = new int[] { 0, 1, 1, 1, 0 };
matrix[1] = new int[] { 1, 0, 0, 0, 1 };
matrix[2] = new int[] { 1, 0, 0, 0, 1 };
matrix[3] = new int[] { 0, 1, 1, 1, 1 };
matrix[4] = new int[] { 0, 0, 0, 0, 1 };
matrix[5] = new int[] { 1, 0, 0, 0, 1 };
matrix[6] = new int[] { 0, 1, 1, 1, 0 };
return matrix;
}
/**
* <p>
* The <code>setDigit</code> method sets the digit to display and repaints the
* panel.
* </p>
*
* @param digit - A digit from 0 through 9.
*/
public void setDigit(int digit) {
this.digit = digit;
this.repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(dotColor);
for (int row = 0; row < matrices[digit].length; row++) {
for (int column = 0; column < matrices[digit][row].length; column++) {
if (matrices[digit][row][column] != 0) {
int x = margin + column * pixelWidth;
int y = margin + row * pixelWidth;
g.fillOval(x, y, dotWidth, dotWidth);
}
}
}
}
}
}
答案2
得分: 3
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class FontToDotMatrix {
private JComponent ui = null;
Shape[] shapes = new Shape[10];
JComboBox fonts;
PixelArray[] pixelArrays = new PixelArray[10];
FontToDotMatrix() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
String[] fontFamilies = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fonts = new JComboBox(fontFamilies);
ui.add(fonts, BorderLayout.PAGE_START);
JPanel digitPanel = new JPanel(new GridLayout(2, 5, 4, 4));
ui.add(digitPanel);
digitPanel.setBackground(Color.RED);
for (int ii = 0; ii < 10; ii++) {
PixelArray pixelArray = new PixelArray();
pixelArrays[ii] = pixelArray;
digitPanel.add(pixelArray);
}
ActionListener listener = (ActionEvent e) -> {
for (int ii = 0; ii < 10; ii++) {
pixelArrays[ii].updatePixels(getLitPixels("" + ii));
}
};
fonts.addActionListener(listener);
fonts.setSelectedItem("Monospaced");
}
private Shape moveShapeToCenter(Shape shape) {
int w = 50;
int h = 70;
Rectangle2D b = shape.getBounds2D();
double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
return move.createTransformedShape(shape);
}
private boolean[][] getLitPixels(String digit) {
Font font = new Font(fonts.getSelectedItem().toString(), Font.BOLD, 70);
Shape shape = getShapeOfCharacter(font, digit);
Rectangle2D rect = shape.getBounds2D();
double h = rect.getHeight();
double ratio = 70d / h;
AffineTransform scale = AffineTransform.getScaleInstance(ratio, ratio);
shape = moveShapeToCenter(scale.createTransformedShape(shape));
boolean[][] bools = new boolean[5][7];
for (int yy = 0; yy < 7; yy++) {
for (int xx = 0; xx < 5; xx++) {
Point point = new Point((xx * 10) + 5, (yy * 10) + 5);
bools[xx][yy] = shape.contains(point);
}
}
return bools;
}
public JComponent getUI() {
return ui;
}
private Shape getShapeOfCharacter(Font font, String digit) {
BufferedImage bi = new BufferedImage(
1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, digit);
return gv.getOutline();
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
FontToDotMatrix o = new FontToDotMatrix();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
class PixelArray extends JPanel {
JLabel[][] labels = new JLabel[5][7];
PixelArray() {
setLayout(new GridLayout(7, 5));
BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
ImageIcon icon = new ImageIcon(bi);
for (int yy = 0; yy < labels[0].length; yy++) {
for (int xx = 0; xx < labels.length; xx++) {
JLabel l = new JLabel(icon);
labels[xx][yy] = l;
l.setOpaque(true);
add(l);
}
}
}
public void updatePixels(boolean[][] bools) {
for (int xx = 0; xx < labels.length; xx++) {
for (int yy = 0; yy < labels[0].length; yy++) {
JLabel l = labels[xx][yy];
if (bools[xx][yy]) {
l.setBackground(Color.WHITE);
} else {
l.setBackground(Color.BLACK);
}
}
}
}
}
英文:
> Is there a better way to create dot matrix digits?
Don't know if 'better' (depends on whether effort or accuracy is the primary consideration) but there is a way to calculate the array based on the Shape
of the digit.
Here is the result for a (bold) version of the default Monospaced font on this machine.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class FontToDotMatrix {
private JComponent ui = null;
Shape[] shapes = new Shape[10];
JComboBox fonts;
PixelArray[] pixelArrays = new PixelArray[10];
FontToDotMatrix() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
String[] fontFamilies = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fonts = new JComboBox(fontFamilies);
ui.add(fonts, BorderLayout.PAGE_START);
JPanel digitPanel = new JPanel(new GridLayout(2, 5, 4, 4));
ui.add(digitPanel);
digitPanel.setBackground(Color.RED);
for (int ii = 0; ii < 10; ii++) {
PixelArray pixelArray = new PixelArray();
pixelArrays[ii] = pixelArray;
digitPanel.add(pixelArray);
}
ActionListener listener = (ActionEvent e) -> {
for (int ii = 0; ii < 10; ii++) {
pixelArrays[ii].updatePixels(getLitPixels("" + ii));
}
};
fonts.addActionListener(listener);
fonts.setSelectedItem("Monospaced");
}
private Shape moveShapeToCenter(Shape shape) {
int w = 50;
int h = 70;
Rectangle2D b = shape.getBounds2D();
double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
return move.createTransformedShape(shape);
}
private boolean[][] getLitPixels(String digit) {
Font font = new Font(fonts.getSelectedItem().toString(), Font.BOLD, 70);
Shape shape = getShapeOfCharacter(font, digit);
Rectangle2D rect = shape.getBounds2D();
double h = rect.getHeight();
double ratio = 70d / h;
AffineTransform scale = AffineTransform.getScaleInstance(ratio, ratio);
shape = moveShapeToCenter(scale.createTransformedShape(shape));
boolean[][] bools = new boolean[5][7];
for (int yy = 0; yy < 7; yy++) {
for (int xx = 0; xx < 5; xx++) {
Point point = new Point((xx * 10) + 5, (yy * 10) + 5);
bools[xx][yy] = shape.contains(point);
}
}
return bools;
}
public JComponent getUI() {
return ui;
}
private Shape getShapeOfCharacter(Font font, String digit) {
BufferedImage bi = new BufferedImage(
1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, digit);
return gv.getOutline();
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
FontToDotMatrix o = new FontToDotMatrix();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
class PixelArray extends JPanel {
JLabel[][] labels = new JLabel[5][7];
PixelArray() {
setLayout(new GridLayout(7, 5));
BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
ImageIcon icon = new ImageIcon(bi);
for (int yy = 0; yy < labels[0].length; yy++) {
for (int xx = 0; xx < labels.length; xx++) {
JLabel l = new JLabel(icon);
labels[xx][yy] = l;
l.setOpaque(true);
add(l);
}
}
}
public void updatePixels(boolean[][] bools) {
for (int xx = 0; xx < labels.length; xx++) {
for (int yy = 0; yy < labels[0].length; yy++) {
JLabel l = labels[xx][yy];
if (bools[xx][yy]) {
l.setBackground(Color.WHITE);
} else {
l.setBackground(Color.BLACK);
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论