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

Имам подклас на JFrame (съдържа JButton, Title и Jpanel) и добавих JPanel към него. Jpanel заема централната част на контура. Искам да направя JPanel прозрачен (трябва да вижда през прозореца Frame).

Тъй като го правя за 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)


Използвайте метода WindowUtils.setWindowTransparent() на JNA, за да започнете с напълно прозрачен прозорец. Всички пиксели, рисувани в този прозорец, ще имат запазен алфа компонент.

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

Едно от решенията е да се избегне ротацията. Добавете това, за да коригирате дейността само за портретна ориентация в манифеста.

android:screenOrientation="portrait"
- 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 и в неговия метод за рисуване рисувах fillrect с градиентна боя (чиято стойност на непрозрачност е 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