I'd like to customize the look of JPopupMenu
so i made a custom class extending the JPopupMenu class on i overrode the paintComponent
method as i would do for any component i need to customize.
public class CustomPopupMenu extends JPopupMenu {
@Override
public paintComponent(Graphics g) {
//custom draw
}
}
The only problem i have right know is that i'm not able to make the JPopupMenu
transparent. I though setOpaque(false)
would be enough, i was wrong.
How can i make a JPopupMenu
transparent?
jpopupmenu is a window?
yes JPopup is container, for example
code for Java6 (have to change imports for Java7)
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TranslucentWindow extends JFrame {
private static final long serialVersionUID = 1L;
private JMenuItem m_mniInsertRow;
private JMenuItem m_mniInsertScrip;
private JMenuItem m_mniDeleterRow;
private JMenuItem m_mniDeleteExpiredScrip;
private JMenuItem m_mniSetAlert;
public TranslucentWindow() {
super("Test translucent window");
setLayout(new FlowLayout());
add(new JButton("test"));
add(new JCheckBox("test"));
add(new JRadioButton("test"));
add(new JProgressBar(0, 100));
JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
panel.add(new JLabel("Very long textxxxxxxxxxxxxxxxxxxxxx "));
add(panel);
final JPopupMenu popupMenu = new JPopupMenu();
m_mniInsertRow = new JMenuItem("Insert a Row");
m_mniInsertRow.setOpaque(false);
m_mniInsertScrip = new JMenuItem("Insert a Scrip");
m_mniInsertScrip.setOpaque(false);
m_mniDeleterRow = new JMenuItem("Delete a Row");
m_mniDeleterRow.setOpaque(false);
m_mniDeleteExpiredScrip = new JMenuItem("Delete a Expired Scrip");
m_mniDeleteExpiredScrip.setOpaque(false);
m_mniSetAlert = new JMenuItem("Set Alert");
m_mniSetAlert.setOpaque(false);
popupMenu.add(m_mniInsertRow);
popupMenu.add(m_mniInsertScrip);
popupMenu.addSeparator();
popupMenu.add(m_mniDeleterRow);
popupMenu.add(m_mniDeleteExpiredScrip);
popupMenu.add(new JSeparator());
popupMenu.add(m_mniSetAlert);
panel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
int x = e.getX();
int y = e.getY();
popupMenu.show(e.getComponent(), x, y);
}
}
});
setSize(new Dimension(400, 300));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Window w = new TranslucentWindow();
w.setVisible(true);
com.sun.awt.AWTUtilities.setWindowOpacity(w, 0.7f);
}
});
}
}
EDIT
interesting support for Translucency
and Nimbus L&F
, especially Painter
reproducing quite correct Color
(Gradiend too on movement over the screen), ligth version with important changes for JPopupMenu, still from Java6
image
from code
import com.sun.java.swing.Painter;
import java.awt.*;
import javax.swing.*;
public class TranslucentWindow extends JFrame {
private static final long serialVersionUID = 1L;
private JPopupMenu popupMenu = new JPopupMenu();
private JMenuItem m_mniInsertRow = new JMenuItem("Insert a Row");
private JMenuItem m_mniInsertScrip = new JMenuItem("Delete a Row");
private JMenuItem m_mniDeleterRow = new JMenuItem("Insert a Scrip");
private JMenuItem m_mniDeleteExpiredScrip = new JMenuItem("Delete a Expired Scrip");
private JMenuItem m_mniSetAlert = new JMenuItem("Set Alert");
public TranslucentWindow() {
super("Test translucent window");
setLayout(new FlowLayout());
add(new JButton("test"));
add(new JCheckBox("test"));
add(new JRadioButton("test"));
add(new JProgressBar(0, 100));
JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, getWidth(), getHeight());
}
};
panel.add(new JLabel("Very long textxxxxxxxxxxxxxxxxxxxxx "));
panel.setComponentPopupMenu(popupMenu);
add(panel);
m_mniInsertRow.setOpaque(false);
m_mniInsertScrip.setOpaque(false);
m_mniDeleterRow.setOpaque(false);
m_mniDeleteExpiredScrip.setOpaque(false);
m_mniSetAlert.setOpaque(false);
popupMenu.add(m_mniInsertRow);
popupMenu.add(m_mniInsertScrip);
popupMenu.addSeparator();
popupMenu.add(m_mniDeleterRow);
popupMenu.add(m_mniDeleteExpiredScrip);
popupMenu.add(new JSeparator());
popupMenu.add(m_mniSetAlert);
setSize(new Dimension(400, 300));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
UIManager.getLookAndFeelDefaults().put("nimbusOrange", (new Color(127, 255, 191)));
UIManager.getLookAndFeelDefaults().put("PopupMenu[Enabled].backgroundPainter",
new FillPainter(new Color(127, 255, 191)));
break;
}
}
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Window w = new TranslucentWindow();
w.setVisible(true);
com.sun.awt.AWTUtilities.setWindowOpacity(w, 0.7f);
}
});
}
static class FillPainter implements Painter<JComponent> {
private final Color color;
FillPainter(Color c) {
color = c;
}
@Override
public void paint(Graphics2D g, JComponent object, int width, int height) {
g.setColor(color);
g.fillRect(0, 0, width - 1, height - 1);
}
}
}
The problem with a popup menu is that it may be realized as a top-level container (Window), and a window is opaque, no matter what value you set with setOpaque(), its opaque. But windows can be made translucent, too.
You can hack it by forcing the use of a heavyweight popup and brutally altering its opacity. Try this as a starting base for experiments (Java7):
import java.awt.Window;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class TranslucentPopup extends JPopupMenu {
{
// need to disable that to work
setLightWeightPopupEnabled(false);
}
@Override
public void setVisible(boolean visible) {
if (visible == isVisible())
return;
super.setVisible(visible);
if (visible) {
// attempt to set tranparency
try {
Window w = SwingUtilities.getWindowAncestor(this);
w.setOpacity(0.667F);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Note that it will not make submenus translucent!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With