У меня популярная проблема. Я много читал об этом, но до сих пор не могу решить. Я кодирую что-то вроде логотипа 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 ответа
Вызов paint (graphics) не копирует содержимое вашей текущей панели. На самом деле это не так, как должно было работать.
Обычно вы добавляете компоненты Swing в JPanel, а вызов paintComponents () вызывает paint () всех компонентов, содержащихся в вашей JPanel.
Вы не должны рисовать напрямую, вместо этого вы можете изменить TurtlePanel, чтобы он владел списком действий, которые он должен выполнить с объектом Graphics, и переопределить его метод paint (), чтобы он всегда мог распечатать его весь контент из нового нового объекта Graphics.
Очевидно, что для профессиональной архитектуры вы можете подумать о более подходящем подходе.
Рисование на JPanel - это прекрасно. Если вы часто перерисовываете, и эти перерисовки рисуют одно и то же, тогда вы можете захотеть кэшировать свою графику в BufferedImage.
Я не уверен, как выполняется ваш текущий рендеринг, поскольку он, кажется, работает с объектом Graphics, который может быть переменной экземпляра, что странно, потому что вы не хотите экономить на этих объектах Graphics. Скорее всего, у вас проблемы с нестандартным (возможно, сломанным) способом рисования графики.
Упрощенный способ исправить это - создать более абстрактный метод, который рисует то, что вы хотите визуализировать, на переданном объекте Graphics. Затем как метод paintComponent JPanel (используйте из него объект Graphics), так и код сохранения изображение (объект Graphics из изображения) может вызывать один и тот же метод.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.