Google Tag Manager

Showing posts with label JMenuItem. Show all posts
Showing posts with label JMenuItem. Show all posts

2024/02/29

Paint JMenuItem selection rollover with rounded rectangle

Code

class BasicRoundMenuItemUI extends BasicMenuItemUI {
  @Override protected void paintBackground(
      Graphics g, JMenuItem menuItem, Color bgColor) {
    ButtonModel m = menuItem.getModel();
    Color oldColor = g.getColor();
    int menuWidth = menuItem.getWidth();
    int menuHeight = menuItem.getHeight();
    if (menuItem.isOpaque()) {
      if (m.isArmed() || (menuItem instanceof JMenu && m.isSelected())) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(
          RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // g2.clearRect(0, 0, menuWidth, menuHeight);
        g2.setPaint(menuItem.getBackground());
        g2.fillRect(0, 0, menuWidth, menuHeight);
        g2.setColor(bgColor);
        g2.fillRoundRect(2, 2, menuWidth - 4, menuHeight - 4, 8, 8);
        g2.dispose();
      } else {
        g.setColor(menuItem.getBackground());
        g.fillRect(0, 0, menuWidth, menuHeight);
      }
      g.setColor(oldColor);
    } else if (m.isArmed() || (menuItem instanceof JMenu && m.isSelected())) {
      g.setColor(bgColor);
      g.fillRoundRect(2, 2, menuWidth - 4, menuHeight - 4, 8, 8);
      g.setColor(oldColor);
    }
  }
}

References

2023/08/31

Hide the check icon on the JRadioButtonMenuItem and reduce the text offset

Code

UIManager.put(PRE + "minimumTextOffset", 10);
UIManager.put(PRE + "afterCheckIconGap", 0);
UIManager.put(PRE + "checkIconOffset", 0);
Icon checkIcon = getCheckIcon();
int height = checkIcon == null ? 22 : checkIcon.getIconHeight();
UIManager.put(PRE + "checkIcon", new EmptyIcon());
Dimension d = new Dimension(100, height);
JPopupMenu popup = new JPopupMenu();
ButtonGroup bg = new ButtonGroup();
Arrays.asList(
    makeMenuItem("0.5 pt", .5f, d),
    makeMenuItem("0.75 pt", .75f, d),
    makeMenuItem("1 pt", 1f, d),
    makeMenuItem("1.5 pt", 1.5f, d),
    makeMenuItem("2.25 pt", 2.25f, d),
    makeMenuItem("3 pt", 3f, d)
).forEach(m -> {
  popup.add(m);
  bg.add(m);
});
// ...
private static JMenuItem makeMenuItem(String txt, float width, Dimension d) {
  float px = width * Toolkit.getDefaultToolkit().getScreenResolution() / 72f;
  return new JRadioButtonMenuItem(txt, new LineIcon(new BasicStroke(px), d)) {
    @Override protected void init(String text, Icon icon) {
      super.init(text, icon);
      setHorizontalTextPosition(LEADING);
      setHorizontalAlignment(TRAILING);
    }

    @Override protected void paintComponent(Graphics g) {
      if (isSelected()) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setPaint(new Color(0xAA_64_AA_FF, true));
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.dispose();
      }
      super.paintComponent(g);
    }
  };
}

References

2021/03/31

Add header and footer in the JComboBox dropdown list

Add the header created by JLabel and the clickable footer created by JMenuItem in the drop-down list of JComboBox

Code

class HeaderFooterComboPopup extends BasicComboPopup {
  protected transient JLabel header;
  protected transient JMenuItem footer;

  public HeaderFooterComboPopup(JComboBox combo) {
    super(combo);
  }

  @Override protected void configurePopup() {
    super.configurePopup();
    configureHeader();
    configureFooter();
    add(header, 0);
    add(footer);
  }

  protected void configureHeader() {
    header = new JLabel("History");
    header.setBorder(BorderFactory.createEmptyBorder(4, 5, 4, 0));
    header.setMaximumSize(new Dimension(Short.MAX_VALUE, 20));
    header.setAlignmentX(1f);
  }

  protected void configureFooter() {
    int modifiers = InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
    footer = new JMenuItem("Show All Bookmarks");
    footer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, modifiers));
    footer.addActionListener(e -> {
      Window w = SwingUtilities.getWindowAncestor(getInvoker());
      JOptionPane.showMessageDialog(w, "Bookmarks");
    });
  }
}

References

2014/10/29

JMenuItem accelerator text alignment

Code

RightAcc

public static void paintAccText(
  Graphics g, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr,
  Color disabledForeground, Color acceleratorForeground,
  Color acceleratorSelectionForeground) {
  if (!lh.getAccText().equals("")) {
    ButtonModel model = lh.getMenuItem().getModel();
    g.setFont(lh.getAccFontMetrics().getFont());
    if (!model.isEnabled()) {
      // *** paint the accText disabled
      if (disabledForeground != null) {
        g.setColor(disabledForeground);
        SwingUtilities2.drawString(
          lh.getMenuItem(), g, lh.getAccText(),
          lr.getAccRect().x,
          lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
      } else {
        g.setColor(lh.getMenuItem().getBackground().brighter());
        SwingUtilities2.drawString(
          lh.getMenuItem(), g, lh.getAccText(),
          lr.getAccRect().x,
          lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
        g.setColor(lh.getMenuItem().getBackground().darker());
        SwingUtilities2.drawString(
          lh.getMenuItem(), g, lh.getAccText(),
          lr.getAccRect().x - 1,
          lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1);
      }
    } else {
      // *** paint the accText normally
      if (model.isArmed() ||
          (lh.getMenuItem() instanceof JMenu && model.isSelected())) {
        g.setColor(acceleratorSelectionForeground);
      } else {
        g.setColor(acceleratorForeground);
      }
      SwingUtilities2.drawString(
        lh.getMenuItem(), g, lh.getAccText(),
        //lr.getAccRect().x, // ++++++++++++++++++++
        lh.getViewRect().x + lh.getViewRect().width
        - lh.getMenuItem().getIconTextGap() - lr.getAccRect().width,
        // ++++++++++++++++++++
        lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
    }
  }
}

EastAcc

public static void paintAccText(
private static JMenuItem makeMenuItem2(JMenuItem mi) {
  final JLabel label = new JLabel(MenuItemUIHelper.getAccText(mi, "+"));
  label.setOpaque(true);
  JMenuItem item = new JMenuItem(mi.getText()) {
    @Override public void updateUI() {
      super.updateUI();
      if (getUI() instanceof WindowsMenuItemUI) {
        setUI(new WindowsMenuItemUI() {
          @Override protected void installDefaults() {
            super.installDefaults();
            acceleratorForeground = UIManager.getColor("MenuItem.background");
            acceleratorSelectionForeground = acceleratorForeground;
          }
        });
      }
    }
  };

  GridBagConstraints c = new GridBagConstraints();
  item.setLayout(new GridBagLayout());
  c.gridheight = 1;
  c.gridwidth  = 1;
  c.gridy = 0;
  c.gridx = 0;
  c.insets = new Insets(0, 0, 0, 4);

  c.weightx = 1d;
  c.fill = GridBagConstraints.HORIZONTAL;
  item.add(Box.createHorizontalGlue(), c);
  c.gridx = 1;
  c.fill = GridBagConstraints.NONE;
  c.weightx = 0d;
  c.anchor = GridBagConstraints.EAST;
  item.add(label, c);

  item.setMnemonic(mi.getMnemonic());
  item.setAccelerator(mi.getAccelerator());
  return item;
}

References

2014/09/29

Change a layout of a JPopupMenu to use their iconic menu items

Code

JPopupMenu popup = new JPopupMenu();
GridBagConstraints c = new GridBagConstraints();
popup.setLayout(new GridBagLayout());
c.gridheight = 1;

c.weightx = 1.0;
c.weighty = 0.0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.CENTER;

c.gridwidth = 1;
c.gridy = 0;
c.gridx = 0; popup.add(makeButton("\u21E6"), c);
c.gridx = 1; popup.add(makeButton("\u21E8"), c);
c.gridx = 2; popup.add(makeButton("\u21BB"), c);
c.gridx = 3; popup.add(makeButton("\u2729"), c);

c.gridwidth = 4;
c.gridx = 0;
c.insets = new Insets(2, 0, 2, 0);
c.gridy = 1; popup.add(new JSeparator(), c);
c.insets = new Insets(0, 0, 0, 0);
c.gridy = 2; popup.add(new JMenuItem("aaaaaaaaaa"), c);
c.gridy = 3; popup.add(new JPopupMenu.Separator(), c);
c.gridy = 4; popup.add(new JMenuItem("bbbb"), c);
c.gridy = 5; popup.add(new JMenuItem("ccccccccccccccccccccc"), c);
c.gridy = 6; popup.add(new JMenuItem("dddddddddd"), c);

// ...
final Icon icon = new SymbolIcon(symbol);
JMenuItem b = new JMenuItem() {
  private final Dimension d = new Dimension(icon.getIconWidth(), icon.getIconHeight());
  @Override public Dimension getPreferredSize() {
    return d;
  }
  @Override public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Dimension cd = getSize();
    Dimension pd = getPreferredSize();
    int offx = (int) (.5 + .5 * (cd.width  - pd.width));
    int offy = (int) (.5 + .5 * (cd.height - pd.height));
    icon.paintIcon(this, g, offx, offy);
  }
};
b.setOpaque(true);

References

2013/11/25

Cut copy paste buttuns in the JMenuItem

Code

private static JMenuItem makeEditMenuItem(final JComponent edit) {
  JMenuItem item = new JMenuItem("Edit") {
    @Override public Dimension getPreferredSize() {
      Dimension d = super.getPreferredSize();
      d.width += edit.getPreferredSize().width;
      d.height = Math.max(edit.getPreferredSize().height, d.height);
      return d;
    }

    @Override protected void fireStateChanged() {
      setForeground(Color.BLACK);
      super.fireStateChanged();
    }
  };
  item.setEnabled(false);

  GridBagConstraints c = new GridBagConstraints();
  item.setLayout(new GridBagLayout());
  c.anchor  = GridBagConstraints.LINE_END;
  c.weightx = 1d;

  c.fill = GridBagConstraints.HORIZONTAL;
  item.add(Box.createHorizontalGlue(), c);
  c.fill = GridBagConstraints.NONE;
  item.add(edit, c);

  return item;
}

private static JPanel makeEditButtonBar(List<AbstractButton> list) {
  int size = list.size();
  JPanel p = new JPanel(new GridLayout(1, size, 0, 0)) {
    @Override public Dimension getMaximumSize() {
      return super.getPreferredSize();
    }
  };
  for (AbstractButton b: list) {
    b.setIcon(new ToggleButtonBarCellIcon());
    p.add(b);
  }
  p.setBorder(BorderFactory.createEmptyBorder(4, 10, 4, 10));
  p.setOpaque(false);
  return p;
}

private static AbstractButton makeButton(String title, Action action) {
  JButton b = new JButton(action);
  b.addActionListener(new ActionListener() {
    @Override public void actionPerformed(ActionEvent e) {
      JButton b = (JButton) e.getSource();
      Container c = SwingUtilities.getAncestorOfClass(JPopupMenu.class, b);
      if (c instanceof JPopupMenu) {
        ((JPopupMenu) c).setVisible(false);
      }
    }
  });
  b.setText(title);
  b.setVerticalAlignment(SwingConstants.CENTER);
  b.setVerticalTextPosition(SwingConstants.CENTER);
  b.setHorizontalAlignment(SwingConstants.CENTER);
  b.setHorizontalTextPosition(SwingConstants.CENTER);
  b.setBorder(BorderFactory.createEmptyBorder());
  b.setContentAreaFilled(false);
  b.setFocusPainted(false);
  b.setOpaque(false);
  b.setBorder(BorderFactory.createEmptyBorder());
  return b;
}

References

2012/07/04

Translucent JPopupMenu

Code

class TranslucentPopupMenu extends JPopupMenu {
  private static final Color ALPHA_ZERO = new Color(0x0, 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();
    if (UIManager.getBorder("PopupMenu.border") == null) {
      setBorder(new BorderUIResource(BorderFactory.createLineBorder(Color.GRAY)));
    }
  }

  @Override public JMenuItem add(JMenuItem menuItem) {
    menuItem.setOpaque(false);
    // menuItem.setBackground(ALPHA_ZERO);
    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 instanceof JWindow) {
          System.out.println("Heavy weight");
          JWindow w = (JWindow) p;
          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();
    //super.paintComponent(g);
  }
}

References

2009/08/12

JMenuBar Background Image

Code

public JMenuBar createMenubar() {
  final TexturePaint texture = makeTexturePaint();
  JMenuBar mb = new JMenuBar() {
    @Override protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setPaint(texture);
      g2.fillRect(0, 0, getWidth(), getHeight());
      g2.dispose();
    }
  };
  mb.setOpaque(false);
  String[] menuKeys = {"File", "Edit", "Help"};
  for (String key: menuKeys) {
    JMenu m = createMenu(key);
    if (m != null) {
      mb.add(m);
    }
  }
  return mb;
}

private JMenu createMenu(String key) {
  JMenu menu = new JMenu(key) {
    @Override protected void fireStateChanged() {
      ButtonModel m = getModel();
      if (m.isPressed() && m.isArmed()) {
        setOpaque(true);
      } else if (m.isSelected()) {
        setOpaque(true);
      } else if (isRolloverEnabled() && m.isRollover()) {
        setOpaque(true);
      } else {
        setOpaque(false);
      }
      super.fireStateChanged();
    };
  };
  if ("Windows XP".equals(System.getProperty("os.name"))) {
    menu.setBackground(new Color(0x0, true)); // XXX: Windows XP lnf?
  }
  menu.add("JMenuItem1");
  menu.add("JMenuItem2");
  menu.add("JMenuItem3");
  return menu;
}

References