Как добавить непрозрачные компоненты в прозрачный JFrame в java 1.5?

У меня есть подкласс JFrame (он содержит JButton, Title и Jpanel), и я добавил к нему JPanel. Jpanel занимает центральную часть границы. Я хочу сделать JPanel прозрачным (он должен видеть сквозь окно фрейма).

Поскольку я делаю это для Java 1.5, я использовал JFrame.setOpacity (0.0f), чтобы установить прозрачность Jframe. При этом все компоненты JFrame (т.е. кнопка, заголовок и jPanel) используют одинаковый альфа-уровень. Но я хочу, чтобы прозрачным был только JPanel.

Я экспериментировал с JLayeredPane, изменяя Z-порядок с тем же результатом.

Я открыт для использования внешних библиотек, таких как JNA (JNA windowsUtil также делает то же самое, что и метод setOpacity ()), и использую классы java7 или java6 в качестве внешних библиотек для моего приложения.

Я даже без посторонней помощи ответил на некоторые ранее заданные вопросы:

Непрозрачные компоненты в прозрачных окнах Java

Java: прозрачная Windows с непрозрачными компонентами?

Перекрасьте полупрозрачный каркас / панель / компонент. < / а>


person E V    schedule 14.05.2012    source источник
comment
Если вы используете утилиты JNA, вы можете получить желаемый эффект, установив альфа-маску в окне, указывающую желаемый уровень непрозрачности, а затем поместив непрозрачные биты в тяжелый компонент внутри исходное окно. Будет ли это работать, во многом зависит от того, как прозрачность каскадирует вниз по иерархии окон на данной платформе.   -  person technomage    schedule 15.05.2012
comment
Кстати, утилиты JNA обеспечивают установку глобального альфа-канала, битовой маски окна и альфа-маски. Последнее, скорее всего, сработает для того, что вы пытаетесь сделать. Вы вряд ли получите код java [67] для работы с более ранней JVM.   -  person technomage    schedule 15.05.2012


Ответы (2)


Используйте метод JNA WindowUtils.setWindowTransparent(), чтобы начать с полностью прозрачного окна. Любые пиксели, нарисованные в этом окне, сохранят свой альфа-компонент.

JFrame f = ...
WindowUtils.setWindowTransparent(f, true);
// ensure JPanel content pane doesn't paint its (solid) background
f.getContentPane().setOpaque(false);
// Any other added components will be painted normally
f.getContentPane().add(new JButton("I'm opaque"));

Это должно привести к желаемым результатам.

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

person technomage    schedule 16.05.2012
comment
Спасибо за то, что помогли мне ... Но я боюсь, что вышеуказанный не работает. Как вы знаете, JButton - легкий объект, он берет альфа-значение из окна своего предка. - person E V; 17.05.2012
comment
Я видел ваш пост: rabbit-hole.blogspot.in /2007/04/alpha-mask-transparency.html. Вы можете дать мне ссылку на исходный код этой статьи. И не могли бы вы предоставить информацию о том, что на самом деле делает маскировка в JNA. - person E V; 17.05.2012
comment
Этот код включен в проект JNA. Обычно LAF кнопки закрашивает область содержимого кнопки и оставляет рисование фона на усмотрение родителя. Если ваша кнопка не полностью закрашивает область содержимого, вам нужно либо изменить ее так, чтобы она отображалась, либо использовать для нее setOpaque (true) (чтобы получить bg по умолчанию), либо дать ей родительский элемент, который закрашивает фон. - person technomage; 17.05.2012
comment
В JNA WindowUtils есть три функции. setWindowMask включает (закрашивает) или выключает (полностью прозрачно) пиксели. setWindowAlpha применяет альфа-значение ко всему окну (и его содержимому). setWindowTransparent совмещает все рисование с окном с его предоставленным альфа-компонентом. - person technomage; 17.05.2012

Вот небольшой пример с двумя ярлыками. Один полностью непрозрачен, а другой полупрозрачен. Это также может работать с JPanel, но для демонстрационных целей это более наглядно с JLabel:

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

import com.sun.awt.AWTUtilities;

public class Test3 {

    protected static void initUI() {
        JFrame frame = new JFrame("test");
        frame.setUndecorated(true);
        AWTUtilities.setWindowOpaque(frame, false);
        JLabel label = new JLabel("Hello NOT transparent label");
        label.setOpaque(true);
        label.setBackground(new Color(255, 0, 0));
        JLabel transLabel = new JLabel("Hello transparent label");
        transLabel.setOpaque(true);
        transLabel.setBackground(new Color(255, 0, 0, 50));
        frame.setLocationByPlatform(true);
        frame.getContentPane().add(label);
        frame.getContentPane().add(transLabel, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                initUI();
            }
        });
    }
}
person Guillaume Polet    schedule 14.05.2012
comment
Спасибо за ответ. Как я уже сказал, я хотел создать приложение для java1.5 (у которого нет метода AWTUtilities.setWindowOpaque), поэтому попытался использовать класс jre1.6u10 в качестве моей библиотеки зависимостей, но у него есть проблемы с дублированием классов из jre1.5. Итак, можете ли вы мне помочь, если есть какие-то альтернативы ... - person E V; 14.05.2012
comment
@ user1371881 Думаю, вам не повезло. См. Также этот пост: stackoverflow.com/questions/1416869/ - person Guillaume Polet; 14.05.2012
comment
Я уже видел этот пост ... и попытался со своей стороны избавиться от зависимостей, изменив имена классов, но есть много изменений в jre1.6u10 по сравнению с jre1.5. Итак, я отказался от этого процесса и стал искать альтернативы нативным библиотекам, таким как JNA (что на самом деле бесполезно). Есть несколько веб-сайтов для захвата экрана, например www.screencast-o-matic.com, которые делают то же самое даже с jre1.5. Так что должен быть какой-то способ - person E V; 14.05.2012
comment
Каким образом JNA не помогала? См. twall.github.com/jna. /3.4.0/javadoc/com/sun/jna/platform/. Затем вам нужно явно нарисовать каждый компонент с желаемым уровнем непрозрачности (вы можете сделать это, создав подкласс JPanel и переопределив его методы рисования, чтобы закрасить в буфер, а затем нарисовать этот буфер в исходном графическом контексте с желаемым уровнем прозрачности). - person technomage; 15.05.2012
comment
@technomage я использовал подкласс JPanel в качестве contentPane JFrame, и в его методе рисования я рисовал заливку градиентной краской (значение непрозрачности которой равно 1.0). Но дело в том, что contentPane принимает уровень непрозрачности своего родителя window.BTW, что вы имели в виду, переопределив его методы рисования, чтобы рисовать в буфер, а затем рисовать этот буфер в исходном графическом контексте с желаемым уровнем прозрачности. Я не понял, что рисовать в буфер. contentPane? Если ошибаюсь, поправьте меня и помогите, если мне не хватает каких-либо знаний об использовании JNA. - person E V; 16.05.2012
comment
@technomag Я использовал альфа-значение непрозрачности 0,5 через WindowUtils jna для моего JFrame. Я хочу, чтобы компоненты (кнопки) contentPane Jframe были непрозрачными. Но они говорят об уровне непрозрачности jFrame. - person E V; 16.05.2012