cAMPy
cAMPy

Reputation: 587

Java swing how to set icon in menu on text position

I need to put a red rectangle as a separator in JMenu. It cannot be just a separator instance, it has to be JMenuItem(JSeparator goes all the width of the menu). My issue is that when I set this rectangle as an Icon it (correctly...) moves all the menu components to the right widening whole Menu. I want it to be where text position from the above and the down elements is.

I am trying with html but it paints nothing or just a small vertical black spot.

JMenuItem sep = new JMenuItem();
    sep.setText("<html><hr size=5 style='background:red;'></html>");

enter image description here

Upvotes: 2

Views: 619

Answers (3)

Peter
Peter

Reputation: 1612

Your html is a small vertical spot because you haven't provided a width. By providing a width such as the below you will see your line:

sep.setText("<html><hr style=\"width:100px;\"></html>");

The fact that your line is black despite a color being provided might stem from this bug:

https://bugs.openjdk.java.net/browse/JDK-5059678


Instead of using the hr tag, you could style a component, which would give the added benefit of more flexibility with the width. With the above, your separator would always be 100 px, meaning when a large/small text based item is added to the menu it could look out of place

Would something like this work for what you need?

private JMenuItem createColoredSeparator(Color color){
    JMenuItem separator = new JMenuItem();
    separator.setPreferredSize(new Dimension(5,5));
    separator.setBackground(color);
    separator.setEnabled(false); //make the item unclickable so menu doesn't close
    return separator;
}

Example usage:

JMenu menu = new JMenu("Menu");
menu.add(new JMenuItem("VeryLongMenuItemName"));
menu.add(createColoredSeparator(Color.RED));
menu.add(new JMenuItem("MenuItemName"));

Output:

enter image description here


To make the above not fill the full width with the chosen color, you can add a Border of the default color to conceal a portion of the background with these edits in createColoredSeparator:

separator.setPreferredSize(new Dimension(20,20));   

separator.setBorder(BorderFactory.createLineBorder(UIManager.getColor("MenuItem.background"), 8));

Output:
enter image description here


Update: I didn't know you needed a raised border applied on top of a potential solution. You can achieve that with a CompoundBorder which is covered as part of How to use Borders. This allows you to merge multiple borders together, two at a time with one being applied on the inside and the other on the outside.

Updating to the below:

private JMenuItem createColoredSeparator(Color color){
        JMenuItem separator = new JMenuItem();
        separator.setPreferredSize(new Dimension(50,50)); //Increased to highlight whats happening
        //Imitate the default raised border
        Border raisedBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED,
                UIManager.getColor("MenuItem.background"),UIManager.getColor("MenuItem.background").darker());
        //Merge the borders with the raised border applied outside of the border concealing part of the background
        separator.setBorder(new CompoundBorder(
                raisedBorder, BorderFactory.createLineBorder(UIManager.getColor("MenuItem.background"), 8)));
        separator.setBackground(color);
        separator.setEnabled(false); //make the item un-clickable so menu doesn't close
        return separator;
    }

provides the following:

enter image description here

Upvotes: 2

Sanjeev
Sanjeev

Reputation: 9946

You can create a customized separator by extending JMenuItem

class RedSeparator extends JMenuItem {

    public RedSeparator() {
        setBorder(BorderFactory.createLineBorder(Color.RED));
        setPreferredSize(new Dimension(1,1));
    }
}

You can add separator as a normal JMenuItem

JMenu menu = new JMenu("File");
menu.add(new JMenuItem("Save"));
menu.add(new RedSeparator());
menu.add(new JMenuItem("Exit"));

Hope this helps.

Upvotes: 2

Nikesh Joshi
Nikesh Joshi

Reputation: 825

Try to add css for <hr> like <hr style='height :5px;' /> 

You can increase your height as your need.

Upvotes: 0

Related Questions