【问题标题】:Window frame covering graphics content覆盖图形内容的窗框
【发布时间】:2012-06-21 04:48:28
【问题描述】:

这是我在这里的第一篇文章,我有一个问题似乎真的很无聊,但这在过去一个小时左右一直困扰着我。

我正在制作一个带有 JPanel 的简单 JFrame,但 Windows 7 边框似乎挡住了我对面板部分的查看。例如,如果我在坐标 0,0 处画一个小正方形,它不会出现,我怀疑它在窗框后面。

我尝试过使用 pack、setsize、setpreferred size、setresizable 和不同的布局,但我无法让它显示前 20 个像素左右!

这就是我所拥有的:

public RedSunGame() {
super("Red Sun");

rs = new JPanel(new BorderLayout(), true);
rs.setPreferredSize(new Dimension(WIDTH, HEIGHT));
add(rs, "Center");

setPreferredSize(new Dimension(WIDTH, HEIGHT));
pack();
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

编辑:

感谢您的所有回复,抱歉缺少信息:)

我正在使用我在书中看到的双缓冲策略。 gameRender 和paintScreen 处于标准游戏循环中。我的 RedSunGame 类扩展了 JFrame。除了上述之外,您可以要求的所有相关代码:

private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private JPanel rs;
private Graphics2D g2d;
private Image dbImage;

private void gameRender() {
//create buffer
if (dbImage == null){
  dbImage = createImage(WIDTH, HEIGHT);
  g2d = (Graphics2D)dbImage.getGraphics();
}
//clear screen
g2d.setColor(Color.white);
g2d.fillRect(0, 0, WIDTH, HEIGHT);

g2d.setColor(Color.blue);
g2d.setFont(font);
g2d.drawString("FPS: " + FPS, 0, HEIGHT);
g2d.fillRect(30, 30, 10, 10);
}

private void paintScreen() {
Graphics g;
try {
  g = getGraphics();
  if ((g != null) && (dbImage != null))
    g.drawImage(dbImage, 0, 0, null);
  Toolkit.getDefaultToolkit().sync();
  g.dispose();
}
catch (Exception e)
{ System.out.println("Graphics context error: " + e);  }
}

根据我当前的设置,它看起来像这样。 http://i.imgur.com/qaabC.png

如果我有 g2d.fillRect(30, 30, 10, 10) 会发生这种情况,唯一的变化是坐标 30,30 而不是 0,0。它肯定隐藏在顶部的边界后面。 http://i.imgur.com/uzfFe.png

此外,将其设置为 BorderLayout.CENTER 在任何这些情况下似乎都没有区别。

(对不起,它不会让新用户发布图片)

编辑: 我想到了。我是直接画到 JFrame 上的。 @Guillaume Polet 我明白为什么你不应该覆盖 JFrames 的paint 方法,因为它绘制到框架而不是实际显示内容的面板!谢谢

【问题讨论】:

  • 截图比文字解释得更清楚...
  • 您发布的代码未显示您绘制小方块的位置。
  • 只是一个建议,永远不要尝试使用setXxXSize(...) 方法,因为许多Layout Managers 不尊重用户定义的大小值。让关注的Layout Manager 关心组件的大小。只需将组件添加到 BorderLayout 的 CENTER 即可解决您的问题,如每个答案中所述:-)

标签: java swing user-interface jpanel


【解决方案1】:

这里是一个示例代码,展示了如何实现您的目标。尝试找出与您的代码的差异以找出问题所在:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RedSunGame {

    private static final int SQUARE_SIZE = 20;
    private JPanel rs;
    private JFrame frame;

    private void initUI() {
        frame = new JFrame("Red Sun");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        rs = new JPanel(new BorderLayout()) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.YELLOW);
                g.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
            }

            @Override
            public Dimension getPreferredSize() {
                Dimension preferredSize = super.getPreferredSize();
                // Let's make sure that we have at least our little square size.
                preferredSize.width = Math.max(preferredSize.width, SQUARE_SIZE);
                preferredSize.height = Math.max(preferredSize.height, SQUARE_SIZE);
                return preferredSize;
            }
        };
        frame.add(rs);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                RedSunGame redSunGame = new RedSunGame();
                redSunGame.initUI();
            }
        });
    }
}

【讨论】:

  • 如果我像你一样在我的代码中覆盖paintComponent,它会工作并在角落绘制一个黄色方块,但由于某种原因它不适用于我创建的缓冲区。有什么想法吗?
  • 你的代码有很多问题。我不知道你是否覆盖了 JFrame 的 paint 方法,但如果你这样做了:不要! ;-),在 ContentPane 或其他子组件上执行此操作。现在,对于您的代码,您几乎不应该调用getGraphics,也不应该持有对Graphics 的引用。您可以使用作为 paintXXX() 方法的参数提供的那个,或者创建自己的(例如在 BufferedImage 上,您可以调用 createGraphics,绘制然后处置图形)。至于双缓冲,在 Swing 中默认是开启的,所以不要再自己做第二次了。
【解决方案2】:

验证 WIDTH 和 HEIGHT 是否 > 0。

试试这个:

//add(rs, "center");
add(rs, BorderLayout.CENTER);

【讨论】:

    【解决方案3】:

    您可能会得到答案,但对于 java swing 的新手,我建议您应该使用 Net-beans IDE。它以图形方式添加和布置 GUI,您无需编写任何手写代码。这是一个很好的起点,如下所述:

    http://docs.oracle.com/javase/tutorial/uiswing/learn/index.html

    【讨论】:

    • 我建议完全相反:首先“手动”掌握 Swing,然后在您知道自己在做什么时使用 GUI 构建器。在 SO 上出现的许多问题都与使用 GUI 构建器的人有关,并且根本不了解 Swing 在做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2019-03-12
    相关资源
    最近更新 更多