【问题标题】:Background is not painted背景未绘制
【发布时间】:2019-12-20 04:57:50
【问题描述】:

我想为乒乓球游戏创建一个简单的游戏菜单。在背景中,有一个球在边缘反弹只是为了看起来不错。现在我想将按钮添加到这个菜单屏幕。但随后不再绘制背景。所以我想画一个活的背景,但按钮应该仍然留在前面。这个实时背景是通过循环实现的。下面是 GUI 类和 DrawStartMenuClass。

我听说过 Layers,但每个人都在 NetBeans 中使用某种工具来使用它们,而我得到了 eclipse,所以我没有那个机会。我想您可以将按钮和背景放在不同的容器中,但我又不确定该怎么做。欢迎任何帮助。


public class GUI {



    public GUI() {

        //Frame erzeugen
        Var.frame = new JFrame("Pong");
        Var.frame.setSize(Var.dimension);
        Var.frame.setVisible(true);
        Var.frame.setResizable(true);
        Var.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Var.frame.setLocationRelativeTo(null);

        //Komponenten erzeugen
        Var.start = new JButton("Start");
        Var.optionen = new JButton("Optionen");
        Var.modus = new JButton("Modus");
        Var.skins = new JButton("Skins");
        Var.beenden = new JButton("Beenden");

        //Komponenten anpassen
        Var.start.setBounds((Var.screenWidth / 2) - (Var.buttonWidth / 2), 400, Var.buttonWidth, 50);
        Var.optionen.setBounds((Var.screenWidth / 2) - (Var.buttonWidth / 2), 500, Var.buttonWidth, 50);
        Var.modus.setBounds((Var.screenWidth / 2) - (Var.buttonWidth / 2), 600, Var.buttonWidth, 50);
        Var.skins.setBounds((Var.screenWidth / 2) - (Var.buttonWidth / 2), 700, Var.buttonWidth, 50);
        Var.beenden.setBounds((Var.screenWidth / 2) - (Var.buttonWidth / 2), 800, Var.buttonWidth, 50);

        //Komponenten hinzufügen
        Var.frame.getContentPane().add(new DrawStartMenue());
        Var.frame.add(Var.start);
        Var.frame.add(Var.optionen);
        Var.frame.add(Var.modus);
        Var.frame.add(Var.skins);
        Var.frame.add(Var.beenden);

    }

}

package main;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JPanel;


public class DrawStartMenue extends JPanel{

    private static final long serialVersionUID = 1L;
    private GridLayout experimentLayout = new GridLayout(6,1);


    public Graphics2D g2d;

    public void paint(Graphics g) {

        //Objekt g zum Zeichnen erzeugen
        super.paintComponent(g);
        g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);


        //Hintergrund
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0,  0,  Var.screenWidth,  Var.screenHeight);
        g2d.setColor(Color.WHITE);
        g2d.setStroke(new BasicStroke(8));
        g2d.drawRect(Var.whiteRectX1, Var.whiteRectY1 , Var.whiteRectWidth, Var.whiteRectHeight);

        //Ball im Hintergrund
        for(int i = 0; i < Var.ballList.size(); i++) {
            g2d.fillOval(Var.ballList.get(i).ballX, Var.ballList.get(i).ballY,
                         Var.ballList.get(i).ballWidth, Var.ballList.get(i).ballHeight);
        }

        //Schriftzug
        drawCenteredString(g, "PONG", Var.rect, new Font("NO CONTINUE", Font.PLAIN, 230));
        repaint();


    }

【问题讨论】:

标签: java swing button background


【解决方案1】:
    Var.frame.getContentPane().add(new DrawStartMenue());
    Var.frame.add(Var.start);
    Var.frame.add(Var.optionen);
    Var.frame.add(Var.modus);
    Var.frame.add(Var.skins);
    Var.frame.add(Var.beenden);

JFrame 的默认布局是BorderLayout。当您在未指定约束的情况下将组件添加到框架时,该组件将添加到CENTER。 CENTER 只能添加一个组件。所以只有添加的最后一个是可见的。

如果你想要背景上的按钮,那么你需要将按钮添加到背景面板,而不是框架:

    JPanel background = new DrawStartMenue();
    Var.frame.add(background, BorderLayout.CENTER);
    background.add(Var.start);
    background.add(Var.optionen);
    background.add(Var.modus);
    background.add(Var.skins);
    background .add(Var.beenden);

代码的其他问题:

  1. 自定义绘画是通过覆盖 paintComopnent(...) 而不是 paint(...) 来完成的。
  2. 切勿在绘画方法中调用 repaint()。 Swing 将决定何时重新绘制组件。
  3. 应在框架可见之前将组件添加到框架中。
  4. 不要尝试 setBounds(...) 组件。 Swing 旨在与布局管理器一起使用。使用适合您所需布局的布局管理器。

编辑:

所以你知道如何:

  1. 向面板添加组件
  2. 在面板上进行自定义绘画。

所以要结合这两个概念,您修改 SwingPaintDemo2 代码如下:

//f.add(new MyPanel());
JPanel panel = new MyPanel();
panel.add( new JButton("Testing") );
f.add(panel);

所以知道你知道基础知识,你就可以在你的真实代码中使用这些知识。

别忘了,你永远不应该在绘画方法中调用 repaint。我已经向您展示了如何使用 Swing Timer 制作动画。

接下来,如果您不喜欢按钮的位置,则可以在 MyPanel 类上使用不同的布局管理器。如果您需要布局管理器方面的帮助,那么 Swing 教程中还有一个布局管理器部分,其中包含工作示例供您下载和测试。

【讨论】:

  • 所以我尝试使用边框布局,按钮不会出现。然后我在不使用边框布局的情况下尝试了它,然后出现了按钮。他们在错误的地方,但至少他们出现了。我将paint Method 更改为painComponent。另外,如果我不 repaint() 我看不到屏幕上的球动画。我尝试将按钮添加到与背景面板不同的面板中,并将其添加到 JFrame 的内容窗格中。也没有用。我还尝试在最后设置可见的框架。也没有用。 setComponentZOrder 也不起作用。很高兴听到答案。
  • 所以我尝试使用边框布局,但按钮不会出现。 - 我从未建议您更改任何内容以使用边框布局。我说框架的默认布局是BorderLayout。 JPanel 的默认布局是 FlowLayout。您只需将背景面板添加到框架并将按钮添加到背景面板。如果您不喜欢面板的 FlowLayout,请更改布局管理器。 另外,如果我不 repaint() 我看不到球动画 - 动画是通过使用 Swing Timer 完成的。有关完整示例,请参阅:stackoverflow.com/a/54028681/131872。
  • 我想我只是愚蠢地创建了 GUI。我所做的研究都没有帮助解决我遇到的问题。但是感谢您尽力而为。
  • 问题是你还没有发布minimal reproducible example。在你学会走路之前,你正在尝试跑步。您需要做的就是创建一个 JPanel 并将其背景颜色设置为 RED。然后创建一个 JButton 并将该按钮添加到面板中。然后将面板添加到框架中。整个代码将是 10-15 行。然后你有一些东西可以在论坛上发布。无需担心您拥有的所有这些变量。让基础工作。然后用您的自定义 JPanel 替换 JPanel。一步一个脚印。
  • 所以我创建了一个 MRE。但这根本没有帮助。现在我已将 Backgroundcolor 设置为黑色(或红色无关紧要)。按钮出现在背景前面,出现在错误的位置(这不是问题),但至少它们出现了。然而,这当然对我遇到的问题没有帮助,因为我想绘制一个永久变化的“实时”背景。当然 setBackground 方法的参数是颜色而不是面板或组件。所以现在我有了一个颜色的静态背景。
【解决方案2】:

这里是 MRE。我终于让它工作了。但是它在我的项目中不起作用。

package main;

import java.awt.Color;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GUI {

    static JFrame frame;
    static JPanel buttons;
    static JPanel background;
    static JButton test1;
    static JButton test2;

    public static void main(String[] args) {

        frame = new JFrame();
        frame.setResizable(false);
        frame.setSize(600,  400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        //Initzialize Components
        buttons = new JPanel();
        buttons.setBackground(Color.BLACK);

        background = new JPanel();
        background.setBackground(Color.BLACK);

        test1 = new JButton("Test1");
        test2 = new JButton("Test2");


        //Adding the Buttons
        buttons.add(test1);
        buttons.add(test2);

        //Adding panels to JFrame
        frame.add(background);
        //frame.add(buttons);

        background.add(buttons);

        frame.setVisible(true);




    }

}

【讨论】:

  • 该解决方案对我有用。而且似乎这里没有人能够提供不同的。也许我不了解摇摆的基础知识。那可能是因为除了我自己之外没有人教我,这不是特别容易。似乎没有人真正理解我的问题。我知道您可以在自定义绘画时添加按钮。但是我一次重画 120 次,无论我尝试什么,除了将按钮添加到玻璃窗格之外,没有任何效果。如果您有更好的解决方案,我认为您有并启发我。但只是说没有解决方案是可能的并没有帮助。
  • 这可能是因为没有人教我 - 我给了你一个演示基础知识的教程链接。你通过阅读和查看工作代码来学习。 如果您有更好的解决方案我确实为您提供了解决方案。当然,这假设您确实花时间阅读了教程。然后你从教程中下载代码并更改/添加我给你的 4 行代码。我还为您提供了数百个球的动画解决方案。
  • 另一种可能性是将按钮添加到面板并将面板添加到框架的 PAGE_START 并将自定义面板添加到框架的 CENTER。现在按钮将出现在自定义绘制面板的上方(而不是顶部)。再次阅读 How to Use the BorderLayout 上的 Swing 教程以获取工作示例。所有 Swing 基础知识都在教程中。如果你不花时间阅读教程,除了你自己,你没有任何人可以责备。
  • 对不起。我知道我在这一点上遇到了非常愚蠢的事情。但是,如果我使用您建议的方法将带有按钮的面板添加到 PAGE_START 并将自定义面板添加到 CENTER,我只会在框架顶部得到一个灰色的矩形,这当然是按钮应该放置的面板。不仅自定义面板上方的按钮应该保留在后台。它们根本不可见。我确实阅读了关于自定义绘画和 BorderLayout 的教程。但据我所知,它们对解决问题没有帮助。
  • 我只在框架顶部得到一个灰色的矩形 - 证明它!你的minimal reproducible example 在哪里。如果您从不发布您的minimal reproducible example,我们将看不到您真正在做什么。如果您将按钮添加到面板并将面板添加到框架,则将显示按钮。我已经说过它们将在您的自定义面板的“上方”,而不是“顶部”。
猜你喜欢
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
相关资源
最近更新 更多