有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何使用JavaSwing创建点阵数字

如何为时钟项目生成5 x 7点阵式数字

这是我要找的一个例子

Dot Matrix Digits

我手动编码每个数字中每个点的位置

是否有更好的方法创建点阵数字

更好的意思是更容易代码,更容易验证,使用现有字体或其他组件,或者其他有经验的Swing开发者可能认为是一个重要的考虑因素。p>

这个问题的其余部分是反对者的背景,他们声称我在阐述我的问题时没有付出足够的努力

因为我提供了这个问题的答案,所以我没有在问题中发布虚假的坏代码。当然,当人们表现出他们的努力时,我们很感激。在我看来,答案中的代码和文本应该是对问题的补充

几天前,当我写这篇文章时,有人提出了一个关于用点阵数字制作时钟的问题。发布问题的人提供了代码和他们创建的图片。此人创建了一个BufferedImage,在那里他们硬编码了他4 x 7点阵数字中每个方点的位置

我对这个人在他的BufferedImage上所做的大量工作印象深刻,所以我去了我的Eclipse,想知道如何概括他所做的工作

当我不在的时候,人们评论并结束了他的问题。当我带着我的答案回来时,那个人已经删除了他的问题

因为我有一个我认为很好的答案,所以我寻找一个合适的问题。当我找不到合适的问题时,我创建了一个问题

当然,我更关注我的答案,而不是我的问题。我真傻,我认为这个答案会为这个问题提供背景

嗯,我希望这个解释能让我更清楚地了解为什么我认为这个话题足够重要,可以提出一个问题并寻求答案


共 (2) 个答案

  1. # 1 楼答案

    不幸的是,您必须对每个数字中每个点的位置进行编码

    但是,您可以灵活地执行此操作

    这就是我的意思。5x7点阵数字可以表示为二维int数组。它也可以表示为boolean数组,但0和1值的矩阵更容易直观验证

    举个例子。这里有一个编码零位的方法。你可以看到,它们创建了一个易于验证的视觉轮廓

        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;
        }
    

    我花了大约15分钟来编码所有的点阵数字矩阵

    可以使用稀疏矩阵对点阵数字进行编码。不幸的是,这种想法导致更多的代码在视觉上更难验证

    下面是一个点阵数字2编码为稀疏坐标矩阵的示例

        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;
        }
    

    在我们对所有的数字矩阵进行编码之后,我们将创建一个矩阵数组

        private int[][][] matrices;
    

    最左边的索引是数字,从0到9。第二个索引是数字矩阵的行。第三个索引是数字矩阵的列

    最后,我们扩展了JPanel并覆盖paintComponent方法来实际绘制点阵数字

        @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);
                    }
                }               
            }
        }
    

    下面是一个完整的可运行示例,演示如何通过扩展JPanel来创建点阵数字面板,并使用多个点阵数字面板来创建所需的GUI

    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. # 2 楼答案

    Is there a better way to create dot matrix digits?

    不知道是否“更好”(取决于是否努力或准确性是首要考虑因素),但有一种方法可以基于数字的Shape计算数组

    以下是这台机器上默认单间距字体(粗体)版本的结果

    enter image description here

    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);
                    }
                }
            }
        }
    }