在JFrame上绘制画布 [英] Drawing Canvas on JFrame

查看:556
本文介绍了在JFrame上绘制画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用Canvas绘制简单的形状,在这个类中我设置了绘画

I'm trying to draw simple shapes with Canvas, in this class I've set the painting

public class Game extends Canvas{
    //FIELDS
    public int WIDTH  = 1024;
    public int HEIGHT = WIDTH / 16 * 9;

    //METHODS
    public void start(){
        Dimension size = new Dimension (WIDTH, HEIGHT);
        setPreferredSize(size);
        paint(null);
    }

    public void paint(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(0, 0, WIDTH, HEIGHT);
        g.setColor(Color.BLACK);
        g.fillOval(100, 100, 30, 30);
    }
}


$ b

And in this the Window

public class MainW {


    public static void main(String[] args) {
        Game ga = new Game();
        JFrame frame = new JFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.add(ga);
        frame.setVisible(true);
        ga.start();

    }

}

但JFrame不适应Canvas。我必须手动调整窗口大小以查看对象。我如何包装它,使JFrame自动包含画布?

It works, but the JFrame is not adapting to the Canvas. I have to manually resize the window to see the objects. How can I pack it so that JFrame automatically encompasses the Canvas?

编辑:
这真的很奇怪。虽然frame.pack()确实很重要,但还不够。
我做的是更改start方法并将其转换为一个构造函数,如:

That's really weird. While frame.pack() is indeed essential, it's not enough. What I did was change the start method and turn it into a constructor, like that:

    public class Game extends Canvas{
        //FIELDS
        public int WIDTH  = 1024;
        public int HEIGHT = WIDTH / 16 * 9;

        //METHODS
        public void Game(){
        Dimension size = new Dimension (WIDTH, HEIGHT);
        setPreferredSize(size);
    }

然后,从另一个类,Eclipse抱怨直接调用构造函数ga.Game),所以我按照它的提示,改为:

then, from the other class, Eclipse complained about calling the constructor directly(E.G. ga.Game), so I followed it's tip and changed to:

    public static void main(String[] args) {
        Game ga = new Game();
        JFrame frame = new JFrame ();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.add(ga);
        frame.setVisible(true);
        ga.getName();

    }

这种方式我实现了我的想法,不知道为什么我不能调用构造函数。

This way I achieve what I have in mind but I really don't know why I can't call the constructor.

推荐答案

我不知道你是什么但是你不应该调用 paint ,特别是不能通过 null

I don't know what it is you're trying to do, but you should NEVER be calling paint and especially not pass it null.

首先,请查看执行自定义绘画 a>和在AWT和Swing中绘画了解有关绘画工作原理的详细信息。

Start by taking a look at Performing Custom Painting and Painting in AWT and Swing for details about how painting works.

为了获得窗口大小给你的组件,你需要提供一些重要的信息。

In order to get the window to size to you component, you need to provide it some important information.

Window#pack 是您要查找的方法,除非您提供适当的大小调整提示,否则它不会帮助您。

While Window#pack is the method you are looking for, it will not help you unless you provide appropriate sizing hints.

在这种情况下,您需要覆盖组件的 getPreferredSize 方法,并提供适当的大小值。 Window#pack 将使用此值来确定需要的大小才能容纳它。

In this case, you need to override the getPreferredSize method of you component and provide an appropriate size value. Window#pack will use this value to determine what size it needs to be in order to accommodate it.

img src =https://i.stack.imgur.com/RAXhe.pngalt =输入图片说明here>>

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestPaint {

    public static void main(String[] args) {
        new TestPaint();
    }

    public TestPaint() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GREEN);
            g.fillRect(0, 0, WIDTH, HEIGHT);
            g.setColor(Color.BLACK);
            g.fillOval(100, 100, 30, 30);
        }
    }
}

油漆链非常重要你应该避免在所有海岸断裂。确保你总是调用 super.paintXxx 或准备一些严重的奇怪

The paint chain is very important and you should avoid breaking it at all coasts. Make sure you always call super.paintXxx or be prepared for some serious weirdness

也可能想读一读的我应该避免使用set(Preferred | Maximum | Minimum)Java Swing中的方法大小?

这篇关于在JFrame上绘制画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆