Question

I want to know how to change the font of the text that appears in the context menu originated from right clicking at the icon that's all the way to the left in the titlebar of JFrames that use the default look and feel for decoration (JFrame.setDefaultLookAndFeelDecorated(true);).

I searched around and found nothing. I thought that I could use what I learned about changing the font of the titlebar's title, but that didn't worked.

Thanks in advance.

Was it helpful?

Solution

After some more messing around, I finally made it! I like Java so much that it makes me a bit sad how hard it is to do stuff like this. Anyway, I found a method here to recursively change the font of all components from a JFileChooser, but it doesn't work on the JPopupMenu (now I know the name) that pops up from the titlebar's icon. So I messed around with that method, used some casting, and was able to change the JMenuItems' font:

public static void setSubComponentFont (Component comp[], Font font) {
    for (int x = 0; x < comp.length; x++) {
        if (comp[x] instanceof Container) {
            setSubComponentFont(((Container)comp[x]).getComponents(), font);
        }  
        try {
            //comp[x].setFont(font);
            if (comp[x].toString().contains("JMenu")) {
                for (Component y : ((JMenu)comp[x]).getPopupMenu().getComponents()) {
                    if (y.toString().contains("JMenu")) {
                        y.setFont(font);
                    }
                }
            }
        } catch (Exception ex) {}
    }
}

I was inspired to use .toString().contains() by this thread.

I also did this with nested loops, so the path to the menu items can be seen:

for (Component a : frame.getLayeredPane().getComponents()) {
    System.out.println(a.toString());
    if (a.toString().contains("MetalTitlePane")) {
        for (Component b : ((Container)a).getComponents()) {
            System.out.println(b.toString());
            if (b.toString().contains("SystemMenuBar")) {
                for (Component c : ((Container)b).getComponents()) {
                    System.out.println(c.toString());
                    for (Component d : ((JMenu)c).getPopupMenu().getComponents()) {
                        System.out.println(d.toString());
                        if (d.toString().contains("JMenu")) {
                            d.setFont(font);
                        }
                    }
                }
            }
        }
    }
}

Every System.out.println() gives a hint to what should go on the following if condition, so they should be used one at a time. This doesn't work for the JFileChooser's title font though. When I have time I'll either look further into it or ask another question.

So, if someone else needs it like I did, here it is. As a tip, System.out.println() and .toString() are your friends! That's how I learned what was contained in each object, and what path I needed to take to get to the objects of interest.

Thanks anyway!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top