【问题标题】:Java JMenuBar repainting backgroundJava JMenuBar 重绘背景
【发布时间】:2014-09-03 14:25:21
【问题描述】:

最近我一直在用 java 和 swing 进行实验,但遇到了一个问题

我有一个带有随机生成背景的“欢迎屏幕”。

我重写了paintComponent 并让它根据当前JPanel 的分辨率绘制背景。不是花哨的东西,只是椭圆形

但是当我使用菜单时,菜单的背景被重新绘制。

椭圆的大小和位置取决于屏幕分辨率。 有什么办法解决吗?

注意:欢迎面板是 JPanel

【问题讨论】:

  • 你的代码在哪里?在问题中发布您的代码,请参阅How to create a Minimal, Complete, and Verifiable example
  • 您真正需要哪部分代码?只是一个带有 randoms() 的 paintComponent 方法
  • 一个最小的、完整的和可验证的示例,以便我们可以编译和运行它...
  • @LittleJacod DavidPostill 试图告诉您的是创建一个新项目(原始项目的副本)并删除所有不必要的代码,例如 actionListeners、颜色等(如果不需要,但在这种情况下,它们是必需的),但仍然会重现该问题。以便我们可以复制粘贴它并实际看到您看到的问题并更能够为您提供帮助。
  • @Frakcool 我能理解他在说什么,我的这是 3 类代码,它并不难理解我在说什么......而且我没有发布任何代码就得到了答案。这个人是怎么得到的?

标签: java swing jpanel repaint jmenubar


【解决方案1】:

这是因为 PopUpMenu 下的区域在关闭 popUp 后会重绘,而其他区域不会。

您可以在关闭 popUp 后重新绘制面板,如下所示:

import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;


public class TestFrame extends JFrame {

    public TestFrame() {
        init();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void init() {
        DrawPanel p = new DrawPanel();
        add(p);

        JMenuBar bar = new JMenuBar();
        JMenu menu = new JMenu("menu");
        JPopupMenu popupMenu = menu.getPopupMenu();
        popupMenu.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {

            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
                repaint();
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent arg0) {

            }
        });
        bar.add(menu);
        menu.add(new JMenuItem("item"));
        setJMenuBar(bar);
    }


    public static void main(String args[]) {
        new TestFrame();
    }


    private class DrawPanel extends JPanel{

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100,100);
        }

        @Override
        protected void paintComponent(Graphics arg0) {
            super.paintComponent(arg0);

            Random r = new Random();
            int nextInt = r.nextInt(20);
            arg0.drawOval(nextInt, nextInt, 20, 20);
        }
    }
}

【讨论】:

  • 感谢您的工作。但它又重新粉刷了整个窗口,但我想没有其他办法
  • 你可以用省略号重绘目标JPanel
  • 这不是一个正确的解决方案。请看我的扩展答案!
【解决方案2】:

在位图上绘制您的背景,然后将其复制到paintComponent() 方法中。绘制事件可以“随时”发生,在这种情况下,您的随机源会生成新值。

另一种解决方案:创建一个方法getRandom(),它创建一个具有相同种子的Random 对象,并使用它。例如:

  protected long seed = 0L;

  protected void initRandom() { // call this in constructing time
      seed = Calendar.getInstance().getTimeInMillis();
  }

  protected Random getRandom() { // call this at the start of the painting method
      return new Random(seed);
  }

这会为所有窗口实例创建新种子,并始终如一地使用它。任何重绘都不会产生不良影响。

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 2014-09-05
    • 2014-12-19
    • 2019-11-03
    相关资源
    最近更新 更多