Google Tag Manager

2012/07/04

Translucent JPopupMenu

Code

class TranslucentPopupMenu extends JPopupMenu{
  private static final Color ALPHA_ZERO = new Color(0, true);
  private static final Color POPUP_BACK = new Color(250,250,250,200);
  private static final Color POPUP_LEFT = new Color(230,230,230,200);
  private static final int LEFT_WIDTH = 24;
  @Override public boolean isOpaque() {
    return false;
  }
  @Override public void updateUI() {
    super.updateUI();
    //Test:
    boolean isNimbus = UIManager.getBorder("PopupMenu.border")==null;
    if(isNimbus) {
      //XXX: NimbusLnF not work???
      setBorder(new BorderUIResource(BorderFactory.createLineBorder(Color.GRAY)));
    }
  }
  @Override public JMenuItem add(JMenuItem menuItem) {
    menuItem.setOpaque(false);
    return super.add(menuItem);
  }
  @Override public void show(Component c, int x, int y) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        Window p = SwingUtilities.getWindowAncestor(TranslucentPopupMenu.this);
        if(p!=null && p instanceof JWindow) {
          System.out.println("Heavy weight");
          JWindow w = (JWindow)p;
          //To be exact: 1.6.0_10 <= java.version < 1.7.0
          //if(System.getProperty("java.version").startsWith("1.6.0")) {
          //  w.dispose();
          //  if(com.sun.awt.AWTUtilities.isWindowOpaque(w)) {
          //    com.sun.awt.AWTUtilities.setWindowOpaque(w, false);
          //  }
          //  w.setVisible(true);
          //}else{
          w.setBackground(ALPHA_ZERO);
          //}}
        }else{
          System.out.println("Light weight");
        }
      }
    });
    super.show(c, x, y);
  }
  @Override protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setPaint(POPUP_LEFT);
    g2.fillRect(0,0,LEFT_WIDTH,getHeight());
    g2.setPaint(POPUP_BACK);
    g2.fillRect(LEFT_WIDTH,0,getWidth(),getHeight());
    g2.dispose();
  }
}

References

8 comments:

  1. Hey thats the right way, but what happens if the popup is out of mainframe? Then it will be heave weight and it doesnt work.
    Try to change line
    ((JWindow)p).setBackground(ALPHA_ZERO) with this line
    AWTUtilities.setWindowOpaque( p, false );

    regards
    ZaidoR

    ReplyDelete
  2. Hi, Rene. Thank you for reporting.
    ((JWindow)p).setBackground(ALPHA_ZERO); is new feature since java 1.7.
    if 1.6.0_10 <= java.version < 1.7.0 then we should use(as you say):
    AWTUtilities.setWindowOpaque(p, false);
    I will add a comment in the example code, thanks again.

    ReplyDelete
  3. Hello TERAI Atsuhiro such, I have a little problem I'm really trying to make a JButton that clicking JPopupMenu call me a horn and I can do everything right but I want to address bone up, down, left, right where I want appears the jpopup that's not how hard, and let me know if you can give me a hand on it thanks for your codes, I hope your answer

    ReplyDelete
  4. Hi, HANNIBAL.
    Excuse me, but what does horn and bone mean?

    ReplyDelete
  5. Atsuhiro TERAI excuse me, speak Spanish, necesito llamar a un jpopupmenu con un jbutton y darle la propiedad de que me aparezca el jpopupmenu arriba,abajo,derecha,izquierda espero me puedas entender y ayudar

    ReplyDelete
  6. If I understand your requirement you might be able to use JPopupMenu#show(java.awt.Component, int, int) method.
    Here is a example: PopupMenuLocationTest.java

    ReplyDelete
  7. hola TERAI ATSUHIRO me sirvio tu ayuda gracias,disculpa que te moleste tanto,tengo un problema con un JComboBox,te explico en una clase externa tengo un metodo por el cual genero JComboBox asi:
    public void addComboBox(String[] items, String label,int position)
    {
    JPanel panel_objetos = new JPanel();
    JLabel etiqueta=new JLabel(label); panel_objetos.setLayout(new FlowLayout(FlowLayout.LEFT));
    panel_objetos.setOpaque(false);
    //------------------------------/ Panel_filas_padre.remove(position);
    Panel_filas_padre.updateUI();
    panel_objetos.add(etiqueta);
    //-----------------------------/
    ComboBox=new JComboBox();
    ComboBox.setBorder(new RoundedCornerBorder());

    for(int a=0; a<items.length; a++)
    {
    ComboBox.insertItemAt(items[a],a);

    }

    panel_objetos.add(ComboBox);
    Panel_filas_padre.add(panel_objetos, position);

    }
    de esta forma genero los Jcombobox:
    String items_1={"A","B","C","D","F","G"};
    PANEL.addComboBox(item_1,letras,2);
    //-------------------------------/
    String items_2={"1","2","3","4","5","6"};
    PANEL.addComboBox(item_2,numeros,3);
    //----------------------------------/
    de esta forma los genero y funciona pero al momento de colocar el evento actionPerformed da problemas por que solo funciona con el segundo combobox generado y no con el primer combobox necesito que cada JComboBox funcione su evento y al seleccionar los items de cada uno los retorne como debe de ser,saber alguna forma de poder hacer funcionar los eventos correctamente generando los JComboBox de esta manera,gracias por tu ayuda me a servido de mucho espero tu respuesta.

    ReplyDelete
  8. Hi, HANNIBAL
    A quality of machine translation(English into Japanese and Spanish into Japanese) is difficult.
    So I need easy access to SSCCE(Short, Self Contained, Correct Example), but this blog comment system is totally miscast as paste source code...
    I'm afraid I can't answer the question.

    ReplyDelete