Прозрачный JPopupMenu внутри прозрачного окна - альтернатива?
Я не уверен, возможно ли это, но есть ли способ безопасно разрешить всплывающие окна, даже если родительский контейнер также является прозрачным?
Если нет, то какой разумной альтернативой будет использование или расширение вместо JPopupMenu
?
Примечание: полупрозрачный относится к компоненту, не имеющему "фона", аналогично эффекту setOpaque(false);
, Благодарю.
Из форума ответ пользователя camickr в 2009 году:
Я не знаю, изменилась ли прозрачность в 1.6.0_10. До этого я считаю, что прозрачность может быть достигнута только в легких компонентах (т.е. Swing делает всю картину). JFrame, JWindow и JDialog не легки, потому что они используют компоненты ОС.
В случае всплывающего окна он легкий, когда полностью содержится в родительском фрейме. Но облегченное всплывающее окно не может быть нарисовано за пределами рамки, поэтому в качестве всплывающего окна используется JWindow (я полагаю), которое не может быть прозрачным.
SSCCE: показ прозрачного JWindow поверх прозрачного JFrame
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);
}
}
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