Прозрачный JFrame с непрозрачным контентом - PullRequest
0 голосов
/ 26 ноября 2018

Моя цель - создать прозрачный JFrame с непрозрачным JPanel, который постоянно рисует квадрат в произвольном месте

private static final int alpha = 255;

public static void main(String[] args) {

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);

    frame.setUndecorated(true);
    frame.setBackground(new Color(255, 255, 255, alpha));

    CustomPanel panel = new CustomPanel();

    panel.setBackground(new Color(255, 255, 255, 0));

    new Timer().schedule(new TimerTask() {

        @Override
        public void run() {

            panel.revalidate();
            panel.repaint();

        }

    }, 0, 1000);

    frame.add(panel);

    frame.setVisible(true);

}

public static class CustomPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.clearRect(0, 0, getWidth(), getHeight());
        g.setColor(new Color(0, 255, 0));
        g.fillRect((int)(Math.random() * 380), (int)(Math.random() * 320), 20, 20);
    }

}

В настоящее время кадр отображается на белом фоне, а квадратнарисовано правильно.

enter image description here

Однако, если я изменю значение переменной alpha, например, на 31, вызов clearRect очистит толькопанель с 31 альфа, и последний кадр все еще будет виден

enter image description here

Слева: 1 итерация вправо: 4 итерации

Как вывидно, что рамка будет нарисована 4 раза, а предыдущий экземпляр все еще будет виден.

Как нарисовать прозрачную рамку без видимой старой рамки?

Моя ОСэто Ubuntu 18.04

1 Ответ

0 голосов
/ 26 ноября 2018

Для прозрачной панели не используйте прозрачный цвет.Swing не рисует фоны с прозрачностью правильно.См. Фон с прозрачностью для получения дополнительной информации.

Однако для полной прозрачности существует простое решение.Просто сделайте панель прозрачной:

//panel.setBackground(new Color(255, 255, 255, 0));
panel.setOpaque( false );

Тогда в коде рисования вы будете использовать:

super.paintComponent(g);
g.setColor(new Color(0, 255, 0));
g.fillRect((int)(Math.random() * 380), (int)(Math.random() * 320), 20, 20);

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

Вместо этого вам нужно, чтобы свойство класса было Цветом для Прямоугольника.Тогда вам нужен метод, такой как setSquareColor(...), когда вы хотите изменить цвет квадрата.

...