У меня популярная проблема. Я много читал об этом, но до сих пор не могу решить. Я кодирую что-то вроде логотипа MSW (интерпретатор графики Turtle), и я хочу сохранить свое изображение (нарисованное в классе, расширяющем JPanel). Проблема в том, что сохраненное изображение пустое (только белый фон, ничего лишнего, никаких фигур).

Из сообщений на StackOverflow я заметил, что рисование на JPanel неверно, и я должен использовать BufferedImage, но я не знаю, как применить этот совет к моему исходному коду. Пожалуйста, помогите мне оторваться от земли. Большое спасибо! :)

Мой класс расширяет JPanel:

public class TurtlePanel extends JPanel {

    public TurtlePanel() {
        super();
        this.setPreferredSize(new Dimension(481, 481));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

}

Создание панели:

public class PanelView {

    private JPanel panel;
    private MainWindowView mainView;


    public PanelView(MainWindowView mainView) {
        this.mainView = mainView;
        createView();
    }

    private void createView() {
        panel = new TurtlePanel();
        panel.setBounds(280, 30, 481, 481);
        panel.setBackground(Color.WHITE);
        panel.setVisible(true);
        mainView.mainWindow.add(panel);
    }

    public JPanel getPanel() {
        return this.panel;
    }

}

Как я рисую фигуры (это работает, фигуры отображаются на моей панели):

private void drawCircle(double radius) {
    if(Math.signum(radius) == -1)
        throw new NumberFormatException();

    if(turtleModel.isShown()) {
        Graphics2D g = ((Graphics2D) panelView.getPanel().getGraphics());
        g.setColor(turtleModel.getPenColor());
        g.draw(new Ellipse2D.Double(turtleModel.getPosX() - radius, turtleModel.getPosY() - radius, 2*radius, 2*radius));
    }
}

Как я пытаюсь сохранить свое изображение:

try {
    BufferedImage image = new BufferedImage(panelView.getPanel().getWidth(), panelView.getPanel().getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics graphics = image.getGraphics();
    panelView.getPanel().paint(graphics);
    ImageIO.write(image, ext, new File(path));
} 
catch(IOException exc) {
    exc.printStackTrace();
}

Еще раз спасибо за помощь! Если Вам нужна дополнительная информация, дайте мне знать. Ваше здоровье!

-2
bargro 3 Сен 2014 в 22:41

2 ответа

Лучший ответ

Вызов paint (graphics) не копирует содержимое вашей текущей панели. На самом деле это не так, как должно было работать.

Обычно вы добавляете компоненты Swing в JPanel, а вызов paintComponents () вызывает paint () всех компонентов, содержащихся в вашей JPanel.

Вы не должны рисовать напрямую, вместо этого вы можете изменить TurtlePanel, чтобы он владел списком действий, которые он должен выполнить с объектом Graphics, и переопределить его метод paint (), чтобы он всегда мог распечатать его весь контент из нового нового объекта Graphics.

Очевидно, что для профессиональной архитектуры вы можете подумать о более подходящем подходе.

0
JSlain 3 Сен 2014 в 23:10
Большое спасибо! Теперь я, наверное, знаю, как исправить свой рисунок.
 – 
bargro
3 Сен 2014 в 23:15

Рисование на JPanel - это прекрасно. Если вы часто перерисовываете, и эти перерисовки рисуют одно и то же, тогда вы можете захотеть кэшировать свою графику в BufferedImage.

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

Упрощенный способ исправить это - создать более абстрактный метод, который рисует то, что вы хотите визуализировать, на переданном объекте Graphics. Затем как метод paintComponent JPanel (используйте из него объект Graphics), так и код сохранения изображение (объект Graphics из изображения) может вызывать один и тот же метод.

0
NESPowerGlove 3 Сен 2014 в 23:12
Благодарю вас! Вы правы - мой способ рисования сломан.
 – 
bargro
3 Сен 2014 в 23:17