4

I am trying to create a custom JPopupMenu that has a different color and rounded borders. I tried the following code but there had been no changes to the way the PopupMenu look.

JButton button = new JButton("Test");
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e){
        TPopupMenu popup = new TPopupMenu();
        JMenuItem item1 = new JMenuItem("Item 1");
        JMenuItem item2 = new JMenuItem("Item 2");
        popup.add(item1);
        popup.add(item2);
    }
}

Custom PopupMenu

public class TPopupMenu extends JPopupMenu{

    public TPopupMenu(){
        super();
        super.setOpaque(false);
        init();
    }
    
    private void init(){
        setBackground(Color.green);
    }
    
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        
        g.setColor(Color.pink);
        
        int w = getWidth();
        int h = getHeight();
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTILIAS_ON);
        
        g2.fillRoundRect(0,0,w-1, h-1, 10, 10);
        g2.drawRoundRect(0,0,w-1, h-1, 10, 10);
        
        g2.setBackground(Color.red);
        g2.setColor(Color.green);
    }

}

This is what i am hoping for my rounded popup menu to look like:

enter image description here

Am i doing something wrong in my paintComponent method?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Cherple
  • 725
  • 3
  • 10
  • 24

1 Answers1

2

Your popup is never visible, call the show​(Component invoker, int x, int y) method to display the JPopupMenu class.

Displays the popup menu at the position x,y in the coordinate space of the component invoker...

      JPopupMenu popup = new JPopupMenu();
      JMenuItem item = new JMenuItem("Item");
      popup.add(item);
      popup.show(frame, frame.getWidth()/2, frame.getHeight()/2);

or you can also call the JPopupMenu.setVisible(boolean b) method.

see JPopupMenu#show, JPopupMenu#setVisible


To customize

For rounded border, you can use new LineBorder(Color.black, 2, true). LineBorder doc

If you want big customization, i recommend you to use/write a look and feel. See tutorial|uiswing

Here is my test:

    public class Test {
    
        private static void createAndShowGUI() {
            JFrame frame = new JFrame("HelloWorldSwing");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            JButton button = new JButton("Test");
    
            JPopupMenu popup = new JPopupMenu();
            popup.setBorder(new LineBorder(Color.black, 2, true));
    
            {
                JMenuItem item = new JMenuItem("Cut");
                item.setForeground(Color.ORANGE);
                popup.add(item);
            }
    
            {
                JMenuItem item = new JMenuItem("Copy");
                item.setBackground(Color.RED);
                popup.add(item);
            }
    
            {
                JMenuItem item = new JMenuItem("Paste");
                popup.add(item);
            }
    
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    popup.show(frame, frame.getWidth() / 2, frame.getHeight() / 2);
                    System.out.println("perfome");
                }
            });
    
            frame.getContentPane().add(button);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    
    }

enter image description here

JTorleon
  • 108
  • 1
  • 9