【问题标题】:Drawing on a JPanel inside a JFrame using fillRect - rectangle sizing and position issues?使用 fillRect 在 JFrame 内的 JPanel 上绘图 - 矩形大小和位置问题?
【发布时间】:2017-02-05 03:21:31
【问题描述】:

编辑:修正代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;


public class JumpingBall extends JPanel{
@Override
public Dimension getPreferredSize()
{
    return new Dimension(300,300);
}


public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D rectangle = (Graphics2D) g;
    rectangle.setColor(Color.BLACK);
    rectangle.fillRect(0,270,300,30);
}


public static void main(String[] args) {
    JFrame frame = new JFrame("Jumping Ball");


    frame.getContentPane().add(new JumpingBall());
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
}
}

我已经为自己设定了编写一些代码的任务,这些代码简单地使球在用户命令下从地板上跳下来。第 1 步是创建一个窗口和一个地板 - 我注意到我添加地板的位置往往不在屏幕上,并发现 here 该 frame.setSize(x,y) 包含边框,您应该在其中嵌入一个 JPanel取而代之的是框架和大小。但是,在尝试进行这些更改时,无论变量如何,我的 rectangle.fillRect(x,y,width,height) 似乎都显示为一个小的方形顶部中心。为什么会发生这种情况?

代码:

    import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;

public class JumpingBall extends JPanel{
    public void paint(Graphics g){
        Graphics2D rectangle = (Graphics2D) g;
        rectangle.setColor(Color.BLACK);
        rectangle.fillRect(0,0,300,30);
    }

public static void main(String[] args) {
    JFrame frame = new JFrame("Jumping Ball");
    JPanel panel = new JPanel();

    panel.setPreferredSize(new Dimension(300,300));
    panel.add(new JumpingBall());

    frame.getContentPane().add(panel);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
}
}

Here's a screenshot of my failed floor.

【问题讨论】:

  • 1) 对于任何 JComponent 或任何扩展它的东西,public void paint(Graphics g){ Graphics2D rectangle = (Graphics2D) g; 应该改为 public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D rectangle = (Graphics2D) g;。 2) 请参阅Detection/fix for the hanging close bracket of a code block 了解我无法再费心修复的问题。 3)JumpingBall 也应该@Override getPreferredSize() 方法返回一个合适的大小作为提示给父容器的布局管理器(panel)。

标签: java swing jframe jpanel


【解决方案1】:

当您进行自定义绘画时:

  1. 您应该重写 paintComponent() 而不是 paint() 并调用 super.paintComponent(g) 作为第一条语句以确保背景被清除。

  2. 重写类的getPreferredSize() 方法以返回面板的大小,以便布局管理器可以在那里完成工作。所以在你的情况下应该是 (300, 300)。

在您的代码中,您不应设置任何组件的首选大小。布局管理器的工作是确定组件的首选大小。

panel.setPreferredSize(new Dimension(300,300));

您当前设置了容纳跳球的面板的首选尺寸。这无济于事,因为尚未设置跳球的首选尺寸。您会看到一个 (10, 10) 正方形,因为面板的 FlowLayout 决定了您的跳球面板的首选尺寸仅为 (10, 10)。

此外,无需创建单独的面板。您可以直接将 JumpingBall 面板添加到框架中。

【讨论】:

  • 感谢您的帮助,我想我已经相应地调整了所有内容并了解了覆盖和设置框架/面板尺寸。我在上面的固定代码中进行编辑,如果有任何明显的我遗漏或从更有经验的编码角度来看仍然存在问题,请随时告诉我!
  • 我注意到您添加了另一条评论,暗示我错过了第一点并提供了一些推荐阅读,但现在似乎已经消失了 - 它仍然相关吗?
  • @Jonathan,我打算建议您阅读 Custom Painting 上的 Swing 教程中的部分以获取更多一般信息和示例。查看示例时,您还可以注意到 GUI 是如何使用SwingUtiltities.invokeLater() 创建的。这是为了确保我们在Event Dispatch Thread (EDT) 上更新了 GUI。您还可以阅读Concurrency in Swing 部分了解有关 EDT 的更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 2013-01-17
  • 1970-01-01
  • 2011-12-05
相关资源
最近更新 更多