Рисование в Java с использованием Canvas

Я хочу рисовать в Java Canvas, но не могу заставить его работать, потому что я не знаю, что я делаю. Вот мой простой код:

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

public class Program
{
    public static void main(String[] args)
    {
        JFrame frmMain = new JFrame();
        frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmMain.setSize(400, 400);

        Canvas cnvs = new Canvas();
        cnvs.setSize(400, 400);

        frmMain.add(cnvs);
        frmMain.setVisible(true);

        Graphics g = cnvs.getGraphics();
        g.setColor(new Color(255, 0, 0));
        g.drawString("Hello", 200, 200);
    }
}

Ничего не появляется в окне.

Я ошибаюсь, думая, что Canvas - это бумага, а Graphics - мой карандаш? Это так работает?

4 ответа

Решение

Предложения:

  • Не используйте Canvas, поскольку вы не должны смешивать AWT с компонентами Swing без необходимости.
  • Вместо этого используйте JPanel или JComponent.
  • Не получайте ваш графический объект, позвонив getGraphics() на компоненте, поскольку полученный объект Graphics будет временным.
  • Ничья в JPanel's paintComponent() метод.
  • Все это хорошо объясняется в нескольких уроках, которые легко найти. Почему бы не прочитать их сначала, прежде чем пытаться угадать это?

Основные учебные ссылки:

Вы должны переопределить свой холст paint(Graphics g) метод и выполнить свой рисунок там. Смотрите документацию по paint().

Как говорится, операция по умолчанию - очистить холст, поэтому ваш вызов графического объекта холста не выполняется так, как вы ожидаете.

Почему бы первый способ не сработал. Создается объект Canvas, устанавливается размер и графические элементы. Я всегда нахожу это странным. Также, если класс расширяет JComponent, вы можете переопределить

paintComponent(){
  super...
}

и тогда вы не сможете создать экземпляр этого класса внутри другого класса, а затем просто вызвать NewlycreateinstanceOfAnyClass.repaint();

Я испробовал этот подход для некоторых игровых программ, над которыми я работал, и, похоже, он не работает так, как я думаю.

Дуг Хауф

Следующее должно работать:

public static void main(String[] args)
{
    final String title = "Test Window";
    final int width = 1200;
    final int height = width / 16 * 9;

    //Creating the frame.
    JFrame frame = new JFrame(title);

    frame.setSize(width, height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setVisible(true);

    //Creating the canvas.
    Canvas canvas = new Canvas();

    canvas.setSize(width, height);
    canvas.setBackground(Color.BLACK);
    canvas.setVisible(true);
    canvas.setFocusable(false);


    //Putting it all together.
    frame.add(canvas);

    canvas.createBufferStrategy(3);

    boolean running = true;

    BufferStrategy bufferStrategy;
    Graphics graphics;

    while (running) {
        bufferStrategy = canvas.getBufferStrategy();
        graphics = bufferStrategy.getDrawGraphics();
        graphics.clearRect(0, 0, width, height);

        graphics.setColor(Color.GREEN);
        graphics.drawString("This is some text placed in the top left corner.", 5, 15);

        bufferStrategy.show();
        graphics.dispose();
    }
}
Другие вопросы по тегам