Почему что-то нарисовано на экране? - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь сделать простой 7-сегментный дисплей и протестировать его. Я хочу сделать простую анимацию, которая отображает числа в порядке с разделением числа на 1 секунду, и это должно выполняться бесконечно, но я не могу понять,Как нарисовать сам дисплей (Реализация анимации, без анимации, я знаю, как печатать числа один за другим).

PD: Я даю вам весь исходный код только для вас, чтобы иметь его, если кому-то нужноэто, но «анимация» находится в строке 120, где я определяю поток для запуска анимации.

Исходный код:

public class MainWindow extends JFrame {

private JPanel contentPane;
private CustomRectangle custRect = null;
private JButton btnCancel;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainWindow frame = new MainWindow();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */

public MainWindow() {
    getContentPane().setBackground(Color.BLACK);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setUndecorated(true);
    setSize(400, 400);
    contentPane = new JPanel();
    contentPane.setLayout(null);
    custRect = new CustomRectangle(getContentPane().getSize());
    getContentPane().add(custRect);
    getContentPane().add(getBtnCancel(), BorderLayout.SOUTH);
}

private Color complementaryColor(Color background) {
    int alpha = background.getAlpha();
    int red = background.getRed();
    int blue = background.getBlue();
    int green = background.getGreen();

    // find compliments
    red = (~red) & 0xff;
    blue = (~blue) & 0xff;
    green = (~green) & 0xff;

    return new Color(red, green, blue, alpha);
}

private JButton getBtnCancel() {
    if (btnCancel == null) {
        btnCancel = new JButton("Cancel");
        btnCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        btnCancel.setBackground(null);
        btnCancel.setBorder(null);
        btnCancel.setForeground(complementaryColor(getContentPane().getBackground()));
        btnCancel.setFocusPainted(false);
    }
    return btnCancel;
}

private class CustomRectangle extends JComponent {

    private byte[] nums = new byte[] { 0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B };

    private double mainWidth = 0.0;
    private double mainHeight = 0.0;
    private Graphics2D g2d = null;

    public CustomRectangle(Dimension size) {
        mainWidth = size.getWidth();
        mainHeight = size.getHeight();
    }

    public byte[] getNums() {
        return nums;
    }

    @Override
    public void paintComponent(Graphics g) {
        g2d = (Graphics2D) g;

        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minutes = calendar.get(Calendar.MINUTE);
        int seconds = calendar.get(Calendar.SECOND);

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Thread th = new Thread() {
            public void run() {
                while(true) {
                    for(int i = 0; i < nums.length; i++)
                            generalCall(nums[i]);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };th.start();
    }

    public void generalCall(byte val) {
        drawAHoursHigh(val);
        drawBHoursHigh(val);
        drawCHoursHigh(val);
        drawDHoursHigh(val);
        drawEHoursHigh(val);
        drawFHoursHigh(val);
        drawGHoursHigh(val);

    }
    private Color getColor(byte val, int shift) {
        int r = 255;
        int g = 0;
        int b = 0;
        int a = 255 * (val >> shift) & 1;

        System.out.println("R: " + r + " G: " + g + " B: " + b + " Alpha: " + a);

        if (a == 0)
            return new Color(15, 15, 15);
        else
            return new Color(r, g, b);
    }

    private void drawAHoursHigh(byte val) {
        System.out.print("A: ");
        Shape a = new RoundRectangle2D.Double(60, 20, 78, 18, 10, 10);
        g2d.setColor(getColor(val, 6));
        g2d.fill(a);
        g2d.draw(a);
    }

    private void drawBHoursHigh(byte val) {
        System.out.print("B: ");
        Shape b = new RoundRectangle2D.Double(140, 40, 18, 98, 10, 10);
        g2d.setColor(getColor(val, 5));
        g2d.fill(b);
        g2d.draw(b);
    }

    private void drawCHoursHigh(byte val) {
        System.out.print("C: ");
        Shape c = new RoundRectangle2D.Double(140, 160, 18, 98, 10, 10);
        g2d.setColor(getColor(val, 4));
        g2d.fill(c);
        g2d.draw(c);
    }

    private void drawDHoursHigh(byte val) {
        System.out.print("D: ");
        Shape d = new RoundRectangle2D.Double(60, 260, 78, 18, 10, 10);
        g2d.setColor(getColor(val, 3));
        g2d.fill(d);
        g2d.draw(d);
    }

    private void drawEHoursHigh(byte val) {
        System.out.print("E: ");
        Shape e = new RoundRectangle2D.Double(40, 160, 18, 98, 10, 10);
        g2d.setColor(getColor(val, 2));
        g2d.fill(e);
        g2d.draw(e);
    }

    private void drawFHoursHigh(byte val) {
        System.out.print("F: ");
        Shape f = new RoundRectangle2D.Double(40, 40, 18, 98, 10, 10);
        g2d.setColor(getColor(val, 1));
        g2d.fill(f);
        g2d.draw(f);
    }

    private void drawGHoursHigh(byte val) {
        System.out.print("G: ");
        Shape g = new RoundRectangle2D.Double(60, 140, 78, 18, 10, 10);
        g2d.setColor(getColor(val, 0));
        g2d.fill(g);
        g2d.draw(g);
    }
}
}

1 Ответ

0 голосов
/ 22 октября 2018

Сначала прочитайте:

для получения дополнительной информации о том, как рисование работает в Swing.

Далее читайте:

чтобы лучше понять проблему параллелизма в Swing - короткой версии, Swing НЕ является потокобезопасным и является однопоточным.Это вызывает ряд проблем, когда вы хотите выполнить повторяющиеся действия, которые обновляют пользовательский интерфейс.

Затем перейдите к чтению Как использовать Swing Timers для возможного решения.

Давайте начнем выявлять основные проблемы ...

Это ...

contentPane = new JPanel();
contentPane.setLayout(null);

, как правило, плохая идея, но вы все равно ее не используете, так что это просто белый шум

Это ...

custRect = new CustomRectangle(getContentPane().getSize());

ошибочно, потому что в то время, когда вы запрашиваете размер его contentPane, оно не было реализовано или расположение на экране, поэтому его результат равен 0x0.Вы все равно не должны полагаться на это, и если вы хотите узнать размер контейнера, запросите его, когда он вам действительно нужен.

Далее ...

private Graphics2D g2d = null;

Вам следуетникогда не поддерживайте ссылку на любой графический контекст, который вы не создали.В Swing контекст разделяется между всеми нарисованными компонентами, что означает, что он может быть грязным, с другим содержимым или обрезанным, чтобы исключить область, которую вы хотите нарисовать.

И, наконец, ....

@Override
public void paintComponent(Graphics g) {
    g2d = (Graphics2D) g;

    Calendar calendar = Calendar.getInstance();
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minutes = calendar.get(Calendar.MINUTE);
    int seconds = calendar.get(Calendar.SECOND);

    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Thread th = new Thread() {
        public void run() {
            while(true) {
                for(int i = 0; i < nums.length; i++)
                        generalCall(nums[i]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };th.start();
}

?

paintComponent будет вызываться всякий раз, когда Swing решит, что ваш компонент необходимо перекрасить, при первом понимании это может быть несколько раз подряд, то естьчисло запущенных Thread с.

Paint должен выполнять одну работу, рисовать текущий контекст компонента, ничего больше.В вашем случае Swing Timer был бы более жизнеспособным и безопасным решением.

И, если его почистить, он может выглядеть примерно так ...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;

public class MainWindow extends JFrame {

    private CustomRectangle custRect = null;
    private JButton btnCancel;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainWindow frame = new MainWindow();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public MainWindow() {
        getContentPane().setBackground(Color.BLACK);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);
        custRect = new CustomRectangle();
        getContentPane().add(custRect);
        getContentPane().add(getBtnCancel(), BorderLayout.SOUTH);
    }

    private Color complementaryColor(Color background) {
        int alpha = background.getAlpha();
        int red = background.getRed();
        int blue = background.getBlue();
        int green = background.getGreen();

        // find compliments
        red = (~red) & 0xff;
        blue = (~blue) & 0xff;
        green = (~green) & 0xff;

        return new Color(red, green, blue, alpha);
    }

    private JButton getBtnCancel() {
        if (btnCancel == null) {
            btnCancel = new JButton("Cancel");
            btnCancel.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });
            btnCancel.setBackground(null);
            btnCancel.setBorder(null);
            btnCancel.setForeground(complementaryColor(getContentPane().getBackground()));
            btnCancel.setFocusPainted(false);
        }
        return btnCancel;
    }

    private class CustomRectangle extends JComponent {

        private byte[] nums = new byte[]{0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B};

        public CustomRectangle() {
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
        }

        public byte[] getNums() {
            return nums;
        }

        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            for (int i = 0; i < nums.length; i++) {
                generalCall(g2d, nums[i]);
            }
        }

        public void generalCall(Graphics2D g2d, byte val) {
            drawAHoursHigh(g2d, val);
            drawBHoursHigh(g2d, val);
            drawCHoursHigh(g2d, val);
            drawDHoursHigh(g2d, val);
            drawEHoursHigh(g2d, val);
            drawFHoursHigh(g2d, val);
            drawGHoursHigh(g2d, val);
        }

        private Color getColor(byte val, int shift) {
            int r = 255;
            int g = 0;
            int b = 0;
            int a = 255 * (val >> shift) & 1;

            System.out.println("R: " + r + " G: " + g + " B: " + b + " Alpha: " + a);

            if (a == 0) {
                return new Color(15, 15, 15);
            } else {
                return new Color(r, g, b);
            }
        }

        private void drawAHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("A: ");
            Shape a = new RoundRectangle2D.Double(60, 20, 78, 18, 10, 10);
            g2d.setColor(getColor(val, 6));
            g2d.fill(a);
            g2d.draw(a);
        }

        private void drawBHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("B: ");
            Shape b = new RoundRectangle2D.Double(140, 40, 18, 98, 10, 10);
            g2d.setColor(getColor(val, 5));
            g2d.fill(b);
            g2d.draw(b);
        }

        private void drawCHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("C: ");
            Shape c = new RoundRectangle2D.Double(140, 160, 18, 98, 10, 10);
            g2d.setColor(getColor(val, 4));
            g2d.fill(c);
            g2d.draw(c);
        }

        private void drawDHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("D: ");
            Shape d = new RoundRectangle2D.Double(60, 260, 78, 18, 10, 10);
            g2d.setColor(getColor(val, 3));
            g2d.fill(d);
            g2d.draw(d);
        }

        private void drawEHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("E: ");
            Shape e = new RoundRectangle2D.Double(40, 160, 18, 98, 10, 10);
            g2d.setColor(getColor(val, 2));
            g2d.fill(e);
            g2d.draw(e);
        }

        private void drawFHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("F: ");
            Shape f = new RoundRectangle2D.Double(40, 40, 18, 98, 10, 10);
            g2d.setColor(getColor(val, 1));
            g2d.fill(f);
            g2d.draw(f);
        }

        private void drawGHoursHigh(Graphics2D g2d, byte val) {
            System.out.print("G: ");
            Shape g = new RoundRectangle2D.Double(60, 140, 78, 18, 10, 10);
            g2d.setColor(getColor(val, 0));
            g2d.fill(g);
            g2d.draw(g);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...