Я написал Java7-приложение, которое создает BufferedImage, который нарисован фоновым потоком всякий раз, когда пользователь меняет что-то, что влияет на изображение. Проблема заключается в том, что при отображении изображения правильное изображение отображается только на несколько секунд, затем отображается неустойчивый багаж (в нужном размере) с остатками буфера кадра из системы (см. Изображение на imgur, справа).Отображение Java BufferedImage на MacBook с отображением Retina не работает
http://i.imgur.com/l3O8IjD.jpg
(Вот что он должен выглядеть следующим образом: http://i.imgur.com/AFWZIzz.png)
Как только рисунок нить закончится, BufferedImage будет обращено на компонент JPanel после трансформируются с AffineTransformation, чтобы отразить определенный уровень масштабирования.
Размер BufferedImage определяется фиксированным числом, которое не зависит от разрешения MacBook или JFrame (обычно довольно высокое, что-то вроде 4000x2000). Панель, в которой вызывается BufferedImage, находится внутри ScrollPanel, которая настраивается на размер панели. Не имеет значения, записывается ли BufferedImage поверх или создается новый каждый раз, когда новая версия рисуется потоком.
Я тестировал инструмент на окнах, MacBook без дисплея сетчатки и три MacBook с дисплеем сетчатки, на всех машинах без дисплея сетчатки, инструмент отлично работает. Есть идеи?
Редактировать: так работает программа: Класс HexaVisExplorer.java - это графический интерфейс JFrame, созданный с помощью NetBeans проекта. Он содержит ScrollPane и VisualizationPanel.java, который является содержимым ScrollPane, и всякий раз, когда пользователь изменяет свойство, влияющее на результирующее изображение, ActionListener для компонента вызывает метод в VisualizationPanel. Там свойство задано и поток инициализируется и запускается, что на основе свойств, установленных в VisualizationPanel.java, нарисует новый BufferedImage. Когда это будет сделано, новый BufferedImage будет сохранен в VisualizationPanel.java, который затем будет перекрашен с переопределенной paintComponent(), где изображение будет преобразовано с использованием java.awt.geom.AffineTransform ation для эффективное масштабирование. Наконец, видовой экран scrollpane изменяется, чтобы отобразить новый размер изображения. Вот код:
Класс HexavisExplorer.java
public class HexaVisExplorer extends javax.swing.JFrame {
private VisualizationPanel visualizationPanel;
private javax.swing.JScrollPane jScrollPane1;
public HexaVisExplorer() {
//...Example where a component listener calls a method in VisualizationPanel.java to set a property
polygonBorderCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
visualizationPanel.setPolygonBorders(polygonBorderCheckbox.isSelected());
}
});
//...
}
}
Класс VisualizationPanel.java. recalculate() создает новый VisualizationThread.java, который генерирует BufferedImage в вопросе, используя свойства в VisualizationPanel.java. Когда Пересчитать является finisehd,
public class VisualizationPanel extends JPanel {
private boolean polygonBorders;
//here be more property class variables and getter/setter for them
public void setPolygonBorders(boolean polygonBorders) {
this.polygonBorders = polygonBorders;
recalculate();
this.revalidate();
this.repaint();
}
public void recalculate(){
vt = new VisualizationThread(this);
vt.execute();
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
dataTransformation.setToScale(transform_factor, transform_factor);
g2d.transform(dataTransformation);
g2d.drawImage(toDraw, 0, 0, null);
this.setSize((int) Math.ceil(transform_factor * maxwidth), (int) Math.ceil(transform_factor * maxheight));
this.setPreferredSize(new Dimension((int) Math.ceil(transform_factor * maxwidth), (int) Math.ceil(transform_factor * maxheight)));
this.revalidate();
hx.modifyVisPanelViewport(this);
}
}
VisualizationThread.java принимает VisualizationPanel, читает его свойства и вычисление нового BufferedImage на его основе. Когда это сделано, вызывается done(), который затем устанавливает новый BufferedImage для рисования на VisualizationPanel и его рецензирование.
public class VisualizationThread extends SwingWorker<Object, Object> {
private VisualizationPanel vp;
private BufferedImage toDraw;
@Override
protected Object doInBackground() throws Exception {
// The bufferedImage gets drawn on here.
}
@Override
protected void done() {
vp.setToDraw(toDraw);
vp.setPreferredSize(new Dimension(toDraw.getWidth(), toDraw.getHeight()));
vp.repaint();
vp.revalidate();
}
}
Вот что он должен выглядеть следующим образом:
Показать код, без этого мы не действительно имеют необходимую нам информацию, чтобы помочь – StormeHawke
вы используете 'AffineTransformOp'? – trashgod
dataTransformation - java.awt.geom.AffineTransform, поэтому я не использую AffineTransformOp. Я добавил код, надеюсь, теперь вы сможете понять лучше! – jurib