Прозрачный JPopupMenu внутри прозрачного окна - альтернатива?

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

Если не,what would be wise alternative to use or extend instead of JPopupMenu?

Замечания:Translucent относится к компоненту, не имеющему «фон», подобному эффектуsetOpaque(false);, Благодарю.



От форума ответ пользователяcamickr в 2009:

I don't know if transparency painting has changed in 1.6.0_10. Prior to that I believe transparency can only be achieved in lightweight components (ie. Swing does all the painting). JFrame, JWindow and JDialog are not lightweight because they use OS components.

In the case of a popup, it is lightweight when entirely contained within its parent frame. But a lightweight popup can not be painted outside the bounds of the frame so a JWindow (I believe) is used as the popup, which can't be transparent.

SSCCE: Отображение прозрачного JWindow поверх прозрачного JFrame

<code>import com.sun.awt.AWTUtilities;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class OpaqueWindowSSCCE {

    private int countdown = 5;

    public static void main(String[] args) {
        new OpaqueWindowSSCCE();
    }

    public OpaqueWindowSSCCE() {
        final JFrame frame = new JFrame("OpaqueWindowSSCCE");
        final JWindow window = new JWindow();

        new Timer(1000, new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                if(--countdown == 0){
                    frame.dispose();
                    window.dispose();
                    System.exit(0);
                } else {
                    frame.repaint();
                }
            }

        }).start();

        frame.setContentPane(new JPanel() {

            @Override
            public void paintComponent(Graphics paramGraphics) {
                super.paintComponent(paramGraphics);
                Graphics2D g = (Graphics2D) paramGraphics.create();
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(new Color(50, 50, 50));
                g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
                g.setColor(new Color(180, 180, 180));
                g.drawString("Closing in " + countdown + " seconds", 20, 25);
            }
        });

        window.setContentPane(new JPanel() {

            @Override
            public void paintComponent(Graphics paramGraphics) {
                super.paintComponent(paramGraphics);
                Graphics2D g = (Graphics2D) paramGraphics.create();
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(new Color(180, 180, 180));
                g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);
            }
        });

        frame.setUndecorated(true);

        ((JComponent) frame.getContentPane()).setOpaque(false);
        ((JComponent) window.getContentPane()).setOpaque(false);

        AWTUtilities.setWindowOpaque(frame, false);
        AWTUtilities.setWindowOpaque(window, false);

        window.setAlwaysOnTop(true);

        frame.setBounds(200,200,500,500);
        window.setBounds(600,600,200,200);
        frame.setVisible(true);
        window.setVisible(true);
    }
}
</code>
 nIcE cOw10 мая 2012 г., 07:13
Я думаю, что это может быть достигнуто в данном контексте, что вы делаете, с помощьюJWindow используя эту функциюsetOpacity ().

Ответы на вопрос(1)

Решение Вопроса

Попробуйте эту часть кода, я использовалJWindow хот

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class WindowExample
{
    private JWindow window;
    private JLabel updateLabel;
    private int count = 5;
    private Timer timer;
    private int x;
    private int y;
    private ActionListener timerAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            updateLabel.setText("Closing Window in " + count + " seconds...");
            count--;
            if (count == 0)
            {
                timer.stop();
                window.setVisible(false);
                window.dispose();
            }   
        }
    };

    private void createAndDisplayGUI()
    {
        final JFrame frame = new JFrame("Window Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setUndecorated(true);
        frame.setOpacity(0.5f);
        frame.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent me)
            {
                x = me.getX();
                y = me.getY();
                window = new JWindow();
                JPanel contentPane = new JPanel();
                JLabel positionLabel = new JLabel(
                    "X : " + me.getX() + " Y : " + me.getY());
                updateLabel = new JLabel("TImer");  
                contentPane.setLayout(new BorderLayout(5, 5));
                contentPane.add(updateLabel, BorderLayout.CENTER);
                contentPane.add(positionLabel, BorderLayout.PAGE_END);
                window.setContentPane(contentPane);
                window.setOpacity(0.5f);
                window.setSize(200, 100);
                window.setLocation(x + window.getWidth(), y + window.getHeight());
                window.setVisible(true);
                count = 5;
                timer = new Timer(1000, timerAction);
                timer.start();
            }
        });

        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new WindowExample().createAndDisplayGUI();
            }
        });
    }
}

А вот и вывод:

ПРЕДУПРЕЖДЕНИЕ Я ПОЛУЧАЮ

C:\Mine\JAVA\J2SE>javac -d classes src\OpaqueWindowSSCCE.java
src\OpaqueWindowSSCCE.java:1: warning: AWTUtilities is internal proprietary API and may be removed i
n a future release
import com.sun.awt.AWTUtilities;
                  ^
src\OpaqueWindowSSCCE.java:68: warning: AWTUtilities is internal proprietary API and may be removed
in a future release
        AWTUtilities.setWindowOpaque(frame, false);
        ^
src\OpaqueWindowSSCCE.java:69: warning: AWTUtilities is internal proprietary API and may be removed
in a future release
        AWTUtilities.setWindowOpaque(window, false);
        ^
3 warnings
 nIcE cOw10 мая 2012 г., 08:15
Вы САМЫЙ ДОБРО ПОЖАЛОВАТЬ И ПРОДОЛЖИТЬ УЛЫБАТЬСЯ :-), да, это правда, даже вJPopUpMenu Я думаю, тебе нужно щелкнуть в другом месте, чтобы скрыть предыдущее :-), просто преимуществоJWindow в том, что мы можем добавить к нему все, что захотим, чтобы показать его пользователю: -)
 nIcE cOw10 мая 2012 г., 09:52
@ paranoid-android: Извините за поздний ответ, возникли некоторые проблемы с сервером. Можете ли вы предоставить небольшой рабочий код, который я могу попробовать, если это не большая проблема, было бы здорово: -)
 rtheunissen10 мая 2012 г., 08:11
Спасибо за SSCCE! Понятно, чтоJWindow способен отображать правильно - недостатком является то, что мне придется реализовать отображение и скрытие, чтобы имитировать отображениеJPopupMenu, что не будет слишком сложно.
 rtheunissen10 мая 2012 г., 08:46
Хмм, это не сработает, потому что установка произвольногоOPACITY не проблема здесь. Что бы я хотел, чтобы всплывающее окно вообще не имело фона (чтобы закругленные углы могли быть круглыми). Ключевым моментом, который стоит отметить, является то, чJFrame не непрозрачен, черезAWTUtilities.setWindowOpaque(frame, false);
 rtheunissen10 мая 2012 г., 08:19
Да, ноJPopUpMenu отлично справляется с фокусировкой и должен убедиться, что он работает хорошо. По какой-то причине я не думал оJWindow вообще ... спасибо, я попробую и вернусь к тебе. : D

Ваш ответ на вопрос