JPopUpMenu 不调用paintComponent

问题描述 投票:0回答:1

我正在使用 Swing 制作 UI,并制作了一个

JPopupMenu
添加到顶部栏的
JMenu
,但
paintComponent()
函数从未被调用。我在网上看到我不能有
0,0
的大小,这是默认的,当我更改它时仍然没有调用paintComponent。我正在使用
java 17

public class PopUpMenu extends JPopupMenu {

    public PopUpMenu() {
        setBackground(UI.tertiaryColor);
        setForeground(UI.tertiaryColor);
    }

    @Override
    protected void paintComponent(Graphics g) {
        System.out.println("painting");
        super.paintComponent(g);
        g.setColor(UI.tertiaryColor);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(UI.tertiaryColor);

        g2.fillRect(0, 0, (int) getPreferredSize().getWidth(), (int) getPreferredSize().getHeight());
    }

}
public class Menu extends JMenu {

    Color highlite = new Color(0x3e90ff);
    int xOffSetText = 5;

    public Menu(String text) {
        super(text);
        init();
    }

    public Menu(String text, int xOffSetText) {
        super(text);
        this.xOffSetText = xOffSetText;
        init();
    }

    private void init() {
        setFont(UI.getFont(16));
        setBackground(UI.mainColor);
        setForeground(UI.textColor);
        setPreferredSize(new Dimension((int) getPreferredSize().getWidth(), 25));

        setContentAreaFilled(false);
        setBorderPainted(false);
        setSelected(false);
        PopUpMenu popUpMenu = new PopUpMenu();
        setComponentPopupMenu(popUpMenu);
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(UI.mainColor);

        Graphics2D g2 = (Graphics2D) g;

        if (getModel().isSelected()) {
            g2.setColor(highlite);
        } else {
            g2.setColor(UI.mainColor);
        }

        g2.fillRect(0, 0, getWidth(), getHeight());

        if (getModel().isSelected()) {
            g2.setColor(UI.mainColor);
        } else {
            g2.setColor(UI.textColor);
        }
        g2.drawString(getText(), xOffSetText, 20);
    }
}

编辑:我将

popupMenu
中与
JMenu
相关的所有功能实现到我自己的
Menu
类中。它确实调用了
paintComponent
函数,但不绘制任何东西。这些是我的新课程:

package org.example.uiComponents;

import org.example.UI;

import javax.swing.*;
import java.awt.*;

public class PopUpMenu extends JPopupMenu {

    public PopUpMenu() {
        setBackground(Color.white);
        setForeground(Color.white);
        System.out.println("popup");
    }

    @Override
    protected void paintComponent(Graphics g) {
        System.out.println("painting123....");
        g.setColor(UI.tertiaryColor);
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(UI.tertiaryColor);

        g2.fillRect((int) getAlignmentX(), (int) getAlignmentY(), (int) getPreferredSize().getWidth(), (int) getPreferredSize().getHeight());
    }

}
public class Menu extends JMenu {

    Color highlite = new Color(0x3e90ff);
    int xOffSetText = 5;
    PopUpMenu popupMenu = null;

    public Menu(String text) {
        super(text);
        init();
    }

    public Menu(String text, int xOffSetText) {
        super(text);
        this.xOffSetText = xOffSetText;
        init();
    }

    private void init() {
        setFont(UI.getFont(16));
        setBackground(UI.mainColor);
        setForeground(UI.textColor);
        setPreferredSize(new Dimension((int) getPreferredSize().getWidth(), 25));

        setContentAreaFilled(false);
        setBorderPainted(false);
        setSelected(false);
        PopUpMenu popUpMenu = new PopUpMenu();
        //setComponentPopupMenu(popUpMenu);
    }


    private void ensurePopupMenuCreated() {
        if (popupMenu == null) {
            this.popupMenu = new PopUpMenu();
            popupMenu.setInvoker(this);
            popupListener = createWinListener(popupMenu);
        }
    }

    @Override
    public void updateUI() {
        setUI((MenuItemUI)UIManager.getUI(this));

        if ( popupMenu != null )
        {
            popupMenu.setUI((PopupMenuUI)UIManager.getUI(popupMenu));
        }

    }

    /**
     * Returns true if the menu's popup window is visible.
     *
     * @return true if the menu is visible, else false
     */
    @Override
    public boolean isPopupMenuVisible() {
        ensurePopupMenuCreated();
        return popupMenu.isVisible();
    }

    /**
     * The window-closing listener for the popup.
     *
     * @see JMenu.WinListener
     */
    protected JMenu.WinListener popupListener;

    /**
     * Sets the location of the popup component.
     *
     * @param x the x coordinate of the popup's new position
     * @param y the y coordinate of the popup's new position
     */
    @Override
    public void setMenuLocation(int x, int y) {
        setMenuLocation(x, y);
        if (popupMenu != null)
            popupMenu.setLocation(x, y);
    }

    /**
     * Appends a menu item to the end of this menu.
     * Returns the menu item added.
     *
     * @param menuItem the <code>JMenuitem</code> to be added
     * @return the <code>JMenuItem</code> added
     */
    @Override
    public JMenuItem add(JMenuItem menuItem) {
        ensurePopupMenuCreated();
        return popupMenu.add(menuItem);
    }

    /**
     * Appends a component to the end of this menu.
     * Returns the component added.
     *
     * @param c the <code>Component</code> to add
     * @return the <code>Component</code> added
     */
    @Override
    public Component add(Component c) {
        ensurePopupMenuCreated();
        popupMenu.add(c);
        return c;
    }

    /**
     * Adds the specified component to this container at the given
     * position. If <code>index</code> equals -1, the component will
     * be appended to the end.
     * @param     c   the <code>Component</code> to add
     * @param     index    the position at which to insert the component
     * @return    the <code>Component</code> added
     * @see       #remove
     * @see java.awt.Container#add(Component, int)
     */
    @Override
    public Component add(Component c, int index) {
        ensurePopupMenuCreated();
        popupMenu.add(c, index);
        return c;
    }

    /**
     * Appends a new separator to the end of the menu.
     */
    @Override
    public void addSeparator()
    {
        ensurePopupMenuCreated();
        popupMenu.addSeparator();
    }

    /**
     * Inserts a new menu item with the specified text at a
     * given position.
     *
     * @param s the text for the menu item to add
     * @param pos an integer specifying the position at which to add the
     *               new menu item
     * @exception IllegalArgumentException when the value of
     *                  <code>pos</code> &lt; 0
     */
    @Override
    public void insert(String s, int pos) {
        if (pos < 0) {
            throw new IllegalArgumentException("index less than zero.");
        }

        ensurePopupMenuCreated();
        popupMenu.insert(new JMenuItem(s), pos);
    }

    /**
     * Inserts the specified <code>JMenuitem</code> at a given position.
     *
     * @param mi the <code>JMenuitem</code> to add
     * @param pos an integer specifying the position at which to add the
     *               new <code>JMenuitem</code>
     * @return the new menu item
     * @exception IllegalArgumentException if the value of
     *                  <code>pos</code> &lt; 0
     */
    @Override
    public JMenuItem insert(JMenuItem mi, int pos) {
        if (pos < 0) {
            throw new IllegalArgumentException("index less than zero.");
        }
        ensurePopupMenuCreated();
        popupMenu.insert(mi, pos);
        return mi;
    }

    /**
     * Inserts a new menu item attached to the specified <code>Action</code>
     * object at a given position.
     *
     * @param a the <code>Action</code> object for the menu item to add
     * @param pos an integer specifying the position at which to add the
     *               new menu item
     * @return the new menu item
     * @exception IllegalArgumentException if the value of
     *                  <code>pos</code> &lt; 0
     */
    @Override
    public JMenuItem insert(Action a, int pos) {
        if (pos < 0) {
            throw new IllegalArgumentException("index less than zero.");
        }

        ensurePopupMenuCreated();
        JMenuItem mi = new JMenuItem(a);
        mi.setHorizontalTextPosition(JButton.TRAILING);
        mi.setVerticalTextPosition(JButton.CENTER);
        popupMenu.insert(mi, pos);
        return mi;
    }

    /**
     * Inserts a separator at the specified position.
     *
     * @param       index an integer specifying the position at which to
     *                    insert the menu separator
     * @exception   IllegalArgumentException if the value of
     *                       <code>index</code> &lt; 0
     */
    @Override
    public void insertSeparator(int index) {
        if (index < 0) {
            throw new IllegalArgumentException("index less than zero.");
        }

        ensurePopupMenuCreated();
        popupMenu.insert( new JPopupMenu.Separator(), index );
    }

    /**
     * Removes the specified menu item from this menu.  If there is no
     * popup menu, this method will have no effect.
     *
     * @param    item the <code>JMenuItem</code> to be removed from the menu
     */
    @Override
    public void remove(JMenuItem item) {
        if (popupMenu != null)
            popupMenu.remove(item);
    }

    /**
     * Removes the menu item at the specified index from this menu.
     *
     * @param       pos the position of the item to be removed
     * @exception   IllegalArgumentException if the value of
     *                       <code>pos</code> &lt; 0, or if <code>pos</code>
     *                       is greater than the number of menu items
     */
    @Override
    public void remove(int pos) {
        if (pos < 0) {
            throw new IllegalArgumentException("index less than zero.");
        }
        if (pos > getItemCount()) {
            throw new IllegalArgumentException("index greater than the number of items.");
        }
        if (popupMenu != null)
            popupMenu.remove(pos);
    }

    /**
     * Removes the component <code>c</code> from this menu.
     *
     * @param       c the component to be removed
     */
    @Override
    public void remove(Component c) {
        if (popupMenu != null)
            popupMenu.remove(c);
    }

    /**
     * Removes all menu items from this menu.
     */
    @Override
    public void removeAll() {
        if (popupMenu != null)
            popupMenu.removeAll();
    }

    /**
     * Returns the number of components on the menu.
     *
     * @return an integer containing the number of components on the menu
     */
    @Override
    @BeanProperty(bound = false)
    public int getMenuComponentCount() {
        int componentCount = 0;
        if (popupMenu != null)
            componentCount = popupMenu.getComponentCount();
        return componentCount;
    }

    /**
     * Returns the component at position <code>n</code>.
     *
     * @param n the position of the component to be returned
     * @return the component requested, or <code>null</code>
     *                  if there is no popup menu
     *
     */
    @Override
    public Component getMenuComponent(int n) {
        if (popupMenu != null)
            return popupMenu.getComponent(n);

        return null;
    }

    /**
     * Returns an array of <code>Component</code>s of the menu's
     * subcomponents.  Note that this returns all <code>Component</code>s
     * in the popup menu, including separators.
     *
     * @return an array of <code>Component</code>s or an empty array
     *          if there is no popup menu
     */
    @Override
    @BeanProperty(bound = false)
    public Component[] getMenuComponents() {
        if (popupMenu != null)
            return popupMenu.getComponents();

        return new Component[0];
    }

    /**
     * A listener class that watches for a popup window closing.
     * When the popup is closing, the listener deselects the menu.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    @SuppressWarnings("serial")
    protected class WinListener extends WindowAdapter implements Serializable {
        JPopupMenu popupMenu;
        /**
         *  Create the window listener for the specified popup.
         *
         * @param p the popup menu for which to create a listener
         * @since 1.4
         */
        public WinListener(JPopupMenu p) {
            this.popupMenu = p;
        }
        /**
         * Deselect the menu when the popup is closed from outside.
         */
        public void windowClosing(WindowEvent e) {
            setSelected(false);
        }
    }

    /**
     * Returns an array of <code>MenuElement</code>s containing the submenu
     * for this menu component.  If popup menu is <code>null</code> returns
     * an empty array.  This method is required to conform to the
     * <code>MenuElement</code> interface.  Note that since
     * <code>JSeparator</code>s do not conform to the <code>MenuElement</code>
     * interface, this array will only contain <code>JMenuItem</code>s.
     *
     * @return an array of <code>MenuElement</code> objects
     */
    @Override
    @BeanProperty(bound = false)
    public MenuElement[] getSubElements() {
        if(popupMenu == null)
            return new MenuElement[0];
        else {
            MenuElement[] result = new MenuElement[1];
            result[0] = popupMenu;
            return result;
        }
    }

    /**
     * Sets the <code>ComponentOrientation</code> property of this menu
     * and all components contained within it. This includes all
     * components returned by {@link #getMenuComponents getMenuComponents}.
     *
     * @param o the new component orientation of this menu and
     *        the components contained within it.
     * @exception NullPointerException if <code>orientation</code> is null.
     * @see java.awt.Component#setComponentOrientation
     * @see java.awt.Component#getComponentOrientation
     * @since 1.4
     */
    @Override
    public void applyComponentOrientation(ComponentOrientation o) {
        super.applyComponentOrientation(o);

        if ( popupMenu != null ) {
            int ncomponents = getMenuComponentCount();
            for (int i = 0 ; i < ncomponents ; ++i) {
                getMenuComponent(i).applyComponentOrientation(o);
            }
            popupMenu.setComponentOrientation(o);
        }
    }

    /**
     * Sets the orientation for this menu and its associated popup menu
     * determined by the {@code ComponentOrientation} argument.
     *
     * @param o the new orientation for this menu and
     *          its associated popup menu.
     */
    @Override
    public void setComponentOrientation(ComponentOrientation o) {
        super.setComponentOrientation(o);
        if ( popupMenu != null ) {
            popupMenu.setComponentOrientation(o);
        }
    }

    @Override
    public JPopupMenu getPopupMenu() {
        ensurePopupMenuCreated();
        return popupMenu;
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(UI.mainColor);
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;

        if (getModel().isSelected()) {
            g2.setColor(highlite);
        } else {
            g2.setColor(UI.mainColor);
        }

        g2.fillRect(0, 0, getWidth(), getHeight());

        if (getModel().isSelected()) {
            g2.setColor(UI.mainColor);
        } else {
            g2.setColor(UI.textColor);
        }
        g2.drawString(getText(), xOffSetText, 20);
    }
}
java swing jpopupmenu
1个回答
0
投票

我对 MenuItems 使用了一种奇怪的解决方法

© www.soinside.com 2019 - 2024. All rights reserved.