JFrame с несколькими слоями - PullRequest
3 голосов
/ 23 апреля 2010

У меня есть окно с двумя слоями: статический фон и передний план, который содержит движущиеся объекты.Моя идея - нарисовать фон только один раз (потому что он не изменится), поэтому я делаю изменяющуюся панель прозрачной и добавляю ее поверх статического фона.Вот код для этого:

public static void main(String[] args) {
    JPanel changingPanel = new JPanel() {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(100, 100, 100, 100);
        }
    };
    changingPanel.setOpaque(false);

    JPanel staticPanel = new JPanel();
    staticPanel.setBackground(Color.BLUE);
    staticPanel.setLayout(new BorderLayout());
    staticPanel.add(changingPanel);

    JFrame frame = new JFrame();
    frame.add(staticPanel);
    frame.setSize(800, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

Этот фрагмент кода дает мне правильное изображение, которое я хочу, но каждый раз, когда я перекрашиваю changingPanel, staticPanel также перекрашивается (что явно противвся идея покрасить статическую панель всего один раз).Может кто-нибудь показать мне, что не так?

К вашему сведению Я использую javax.swing.Timer для пересчета и перекрашивания изменяющейся панели 24 раза каждую секунду.

Ответы [ 3 ]

7 голосов
/ 23 апреля 2010

Когда вы перекрашиваете прозрачный компонент поверх другого, вы все равно «пачкаете» нижний компонент, вызывая его перекрашивание.Если вы не перекрасите нижний слой, вы получите эффект смазывания изображения поверх него.

Единственная доступная здесь оптимизация - это не восстановление изображения, используемого на нижнем уровне.Растр по-прежнему необходимо рисовать в графическом буфере каждый раз, когда изменяется слой выше.

3 голосов
/ 23 апреля 2010

Именно так и работает картина. Swing должен искать первый компонент с непрозрачным фоном. Затем он рисует этот компонент и детей, чтобы убедиться, что все рисование выполнено правильно.

Даже если у вас есть движущийся компонент, SWing все равно нужно «очистить» последнюю позицию компонента, что означает, что он должен по крайней мере перекрасить эту область панели фона, прежде чем перекрасить компонент, который был перемещен. *

Чтобы сделать рисование более эффективным, дочерняя панель должна быть непрозрачной. Я не знаю, почему вы изменили настройку по умолчанию.

2 голосов
/ 23 апреля 2010

Очень простой способ - использовать jxlayer . Реализуйте AbstractLayerUI и добавьте это к вашему компоненту. См. здесь , чтобы начать.

...