【问题标题】:java JFrame graphicsjava JFrame图形
【发布时间】:2012-10-25 19:01:40
【问题描述】:

我在 JFrame 构造函数中有以下简单代码

    super(name);
    setBounds(0,0,1100,750);
    setLayout(null);


    setVisible(true);

    g = this.getGraphics();
    int[] x =new int[]{65,  122,  77,  20, };
    int[] y =new int[]{226,  258, 341,  310};
    g.setColor(Color.RED);  
    g.drawPolygon (x, y, x.length);
    System.out.println(g);

我在控制台上得到的输出为:

sun.java2d.SunGraphics2D[font=java.awt.Font[family=Dialog,name=Dialog,style=plain,size=12],color=java.awt.Color[r=255,g=0, b=0]]

但是在 JFrame 上没有绘制红色多边形,而只是空白的 JFrame。

为什么??

【问题讨论】:

  • 这不是在 JFrame 上绘制的正确方法。您应该继承 JPanel 并覆盖 paintComponent(Graphics),然后在传递的图形对象上进行绘制。

标签: java swing graphics jframe paint


【解决方案1】:
  • 不要在JFrame 中覆盖paint(..)

  • 而是添加 custom JPanel 覆盖 paintComponent(Graphics g)JFrame

  • 不要使用Null/AbsoluteLayoutuse an appropriate LayoutManager

  • 不要在JFrame 实例上调用setBounds(..)(不是说它不允许,但看不到它与此应用程序相关)

  • 不要忘记使用EDT 来创建和更改 GUI 组件:

    javax.swing.SwingUtilities.invokeLater(new Runnable() {
                @Override
               public void run() {
                    Test test = new Test();
               }
    });
    

然后你会做这样的事情:

public class Test {

    /**
     * Default constructor for Test.class
     */
    public Test() {
        initComponents();
    }

    public static void main(String[] args) {

        /**
         * Create GUI and components on Event-Dispatch-Thread
         */
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test test = new Test();
            }
        });
    }

    /**
     * Initialize GUI and components (including ActionListeners etc)
     */
    private void initComponents() {
        JFrame jFrame = new JFrame();
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jFrame.add(new MyPanel());

        //pack frame (size JFrame to match preferred sizes of added components and set visible
        jFrame.pack();
        jFrame.setVisible(true);
    }
}

class MyPanel extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int[] x = new int[]{65, 122, 77, 20};
        int[] y = new int[]{226, 258, 341, 310};
        g.setColor(Color.RED);
        g.drawPolygon(x, y, x.length);
    }

    //so our panel is the corerct size when pack() is called on Jframe
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }
}

产生:

【讨论】:

  • +1,很好的例子。唯一好奇的是关于 setBounds 的评论?使用 setLocation 和 setSize 有什么区别?
  • @MadProgrammer +1 谢谢...至于setBounds(..) 我没有具体证据,但我认为它是setSize()setLocation() 的合并。我对setLocation() 没有问题(除了位置可能不在屏幕上),但setSize() 有一些已知问题,例如由于给定尺寸不正确而隐藏组件等,在设置高度和宽度使用setBounds(x,y,width,height)。虽然我愿意接受批评:)
  • 就我个人而言,我没有特别的问题,pack 和 setLocationRelativeXxx 通常在日常使用中更有用,恕我直言,尽管有时需要/希望直接指定位置大小。它会毫无理由地“阻止”以这种方式使用绝对定位,但这只是我。只是想了解您的观点;)
  • @MadProgrammer,+1 非常正确,没有问题,我编辑了帖子以显示更改,OP 和其他人可以看到 cmets
  • 嘿,我在 Jpanel msu-footprints.org/2011/Aditya/map.jpg 中添加以下图像,然后添加多边形 int[] x = new int[]{65, 122, 77, 20}; int[] y = new int[]{226, 258, 341, 310}; g.setColor(Color.RED); g.drawPolygon(x, y, x.length); 多边形应该与构建 GER 重合,但有点偏移。我的教授说坐标没问题。我如何放置图像位置有什么问题吗?
【解决方案2】:

您最好覆盖paint(Graphics g)paintComponent(Graphics g),而不是您尝试的方法。添加下面的行并删除代码中setVisible 之后的行。

public void paint(Graphics g) {
  int[] x =new int[]{65,  122,  77,  20};
  int[] y =new int[]{226,  258, 341,  310};
  g.setColor(Color.RED);  
  g.drawPolygon (x, y, x.length);
}

【讨论】:

  • 不要使用getGraphics(),此方法用于打印或保存图形到文件
  • 但是paint方法在启动时会自动运行。我想以编程方式决定何时绘制。
  • 然后放一个标志,只有在标志决定的时候才在油漆下绘制东西。
  • 你真的不应该重写顶级容器的绘制方法。除此之外,它不是双缓冲的,最好覆盖从 JComponent 扩展的东西
  • 确实如此。但是,我显示了错误的部分在哪里。从这一点来看,事情肯定会有所改善。
猜你喜欢
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
相关资源
最近更新 更多