【问题标题】:paint method draws outside jFrame if first coord 0,0如果第一个坐标为 0,0,则paint方法在 jFrame 之外绘制
【发布时间】:2012-12-20 10:46:46
【问题描述】:

在这种情况下,第一个坐标应该是 0,0 而不是 8,30。我在做什么错(我正在使用 NetBeans)

import java.awt.Color;
import java.awt.Graphics;
public class TEST extends javax.swing.JFrame {

@Override
public void paint(Graphics g){
    super.paint(g);
    g.setColor(Color.blue);
    g.drawRect(8, 30, 200, 200);
    repaint();
}}

【问题讨论】:

  • g 是框架的图形上下文。现在标题栏也是框架的一部分。因此 (0,0) 表示框架的左上角,而不是您所期望的绘图区域的左上角。
  • 框架的装饰占据了框架范围内的空间。不建议直接在框架上绘画 1. 您遇到此问题 2. 框架包含其他组件(内容窗格、菜单、图层和玻璃窗格)。查看this 了解更多信息。您应该使用自定义组件(如JPanel)并将其添加到内容窗格或用它替换框架的内容窗格。

标签: java swing jframe paintcomponent


【解决方案1】:

JPanel 添加到框架并在其中绘制。框架的坐标包括装饰(标题栏、边框等)。它看起来像这样:

public class Test extends JFrame {
    public static void main(String[] args) {
        new Test();
    }
    private Test() {
        add(new MyPanel());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setVisible(true);
    }
    private class MyPanel extends JPanel {
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.blue);
            g.drawRect(8, 30, 200, 200);
        }
    }
}

另外,不要在paint(); 中调用repaint();。这将导致无限循环并冻结整个程序。

【讨论】:

  • "..Test extends JFrame.." 为什么要扩展框架?只需使用一个实例。
  • +1 AndrewThompson,@DoorKnob 也总是在事件调度线程上创建 Swing 组件,并且不要调用 setSize 而不是在 JFrame 上调用 pack()(并覆盖 getPreferredSize()JPanel - 请参阅我的答案更多)。 +1 paintComponent JPanelrepaint() 建议。
  • @AndrewThompson 我只是想让它尽可能地与原始程序相似。我通常不会这样做。
  • @Doorknob 不要提供演示不良做法的 OP 代码,因为他/或她可能认为这是正确的做法,因此学习 不正确 方法,而不是纠正他们的错误为未来的 IMO。
  • 谢谢帮了我很多,虽然我在开始时遇到了一些麻烦,但后来解决了(我在另一个程序中实现了这个)
【解决方案2】:

问题是您的paint(..) 方法没有通过调用getInsets 来考虑JFrame Insets,即docs state

如果该组件上设置了边框,则返回边框的 插图。

这段代码运行良好:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        createAndShowGui();
    }

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

    private void createAndShowGui() {
        JFrame frame = new JFrame() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                g.setColor(Color.blue);
                g.drawRect(0 + getInsets().left, 0 + getInsets().top, 200, 200);
            }
        };
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.pack();
        frame.setVisible(true);
    }
}

但这不是最佳做法。

宁可将JPanel 添加到JFrame 并覆盖JPanelpaintComponent(Graphics g),不要忘记调用super.paintComponent(g) 作为被覆盖方法中的第一个调用,而不是在那里绘制(不要忘记覆盖getPreferredSize() 并返回正确Dimensions 所以JPanel 将适合其绘图/图形内容)这个问题将不再存在,因为JPanel 被添加到 contentPane 上的正确坐标处,如下所示:

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

public class Test {

    public Test() {
        createAndShowGui();
    }

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

    private void createAndShowGui() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
                g2d.setColor(Color.blue);
                g2d.drawRect(0, 0, 200, 200);
            }

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

        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

以上包括Graphics2D 和RenderingHints,即抗锯齿。只是为了一些更好看的图纸:)

【讨论】:

    猜你喜欢
    • 2013-11-29
    • 2011-04-12
    • 2012-02-21
    • 1970-01-01
    • 2010-10-04
    • 2019-05-11
    • 2017-06-27
    • 2020-03-06
    相关资源
    最近更新 更多