JMenuBar 从应用程序中单独打开 Window

JMenuBar Opens In Separate Window from Application

正在开发 Java 应用程序,该应用程序打开 window 并允许用户在 window 上绘图,就像 canvas 一样。

我刚刚添加了一个 JMenuBar,它最终将允许用户使用不同的绘图工具。问题是 JMenuBar 在与 "canvas" window 分开的 window 中打开,我希望 JMenuBar 成为同一 [=] 的一部分29=].

我该如何解决这个问题并让它发生?

这是创建菜单栏的方法:

// Create JFrame with MenuBar Components
public static void initializeMenu() {
    frame = new JFrame();

    // JMenu Bar
    menuBar = new JMenuBar();
    menuBar.setBackground(Color.GRAY);

    // JMenu
    fileMenu = new JMenu("File");
    editMenu = new JMenu("Edit");
    menuBar.add(fileMenu);
    menuBar.add(editMenu);

    // JMenu Items
    jItem = new JMenuItem("Save");
    fileMenu.add(jItem);

    // Make JMenuBar Visible in Application
    frame.setJMenuBar(menuBar);
    frame.pack();
    frame.setVisible(true);

}

以及主要方法:

// Main method
    public static void main(String[] args) {
        Paint paint = new Paint();
        paint.setSize(800, 500);
        paint.setVisible(true);
        paint.setLayout(new FlowLayout());
        initializeMenu();

    }

尝试从 initializeMenu 返回 JMenuBar 的实例并将其应用于 Paint class

public static JMenuBar initializeMenu() {
    // JMenu Bar
    menuBar = new JMenuBar();
    menuBar.setBackground(Color.GRAY);

    // JMenu
    fileMenu = new JMenu("File");
    editMenu = new JMenu("Edit");
    menuBar.add(fileMenu);
    menuBar.add(editMenu);

    // JMenu Items
    jItem = new JMenuItem("Save");
    fileMenu.add(jItem);

    return menuBar;    
}

然后应用它 Paint class...

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Paint paint = new Paint();
            paint.setJMenuBar(initializeMenu());        
            paint.setLayout(new FlowLayout());
            paint.setSize(800, 500);
            paint.setVisible(true);
        }
    });
}

就我个人而言,我更喜欢 pack 而不是 setSize,它通常会产生满足您需求的可视区域(假设您正在使用布局管理 API正确)

已更新...

你打破了油漆链

public class Paint extends JFrame implements ... {

    //...

    // Method for different drawing stencils
    public void paint(Graphics g) {
        if (p != null) {
            g.setColor(c);
            switch (shapeType) {
                case 0:
                    g.drawOval(p.x - w / 2, p.y - h / 2, w, h);
                    break;
                case 1:
                    g.drawRect(p.x - w / 2, p.y - h / 2, w, h);
                    break;

            }

        }

        // Resets application window surface to white (clears the canvas)
        if (Refresh == true) {
            g.setColor(Color.white);
            g.fillRect(0, 0, 1500, 1500);

        }
        g.drawImage(key, 0, 0, this);

        if (widthincrease == true) {
            w += 1;
        }
        if (heightincrease == true) {
            h += 1;
        }
        if (widthdecrease == true) {
            w -= 1;

            if (w < 1) {
                w = 50;
            }
        }

        if (heightdecrease == true) {
            h -= 1;

            if (h < 1) {
                h = 50;
            }
        }

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        repaint();
    }

    public void update(Graphics g) {
        paint(g);
    }
}

基本上,通过覆盖 paint,但从不调用 super.paint,您已经阻止了框架绘制它的内容。

首先,您应该避免重写 paint 顶级容器,这只是一个例子,但是 JFrame 上面还有很多其他组件。

这些可以(并且将会)覆盖任何你想在框架上绘制的东西。

框架有边框,在框架区域内绘制,通过覆盖 paint,您可以在这些边框下绘制,请参阅 How to get the EXACT middle of a screen, even when re-sized 以了解我正在谈论的示例。

相反,创建一个从 JPanel 扩展的自定义 class 并重写它的 paintComponent 方法,移动 "painting" 与此 [=63] 代码相关的其余部分=](不要忘记在进行任何自定义绘画之前调用 super.paintComponent)。

有关详细信息,请参阅 Performing Custom Painting

避免 KeyListener,严重的是,它只是一种绘画,而是使用键绑定 API,请参阅 How to Use Key Bindings 了解更多详细信息