问题
Perhaps there are some of you using NASA's worldwind in WWJ form. I just started and set up everything in NetBeans, so that the latest WWJ runs there with jogl and co. I tested it with basic demo code.
My aim is to display a graph on the WWJ canvas, that will be updated regularly and will be animated in this way. It will be a 2D graph of a dataset, that will be computed in the background and the WWJ programm has to read and display it.
Do you have some tips and EASY examples/tutorials for how I can do that?
Hi, I was able to insert a jfreechart chart, but I haven't been able to "update" the chart yet, could you help me?
package screensaver;
import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.render.ScreenImage;
import gov.nasa.worldwind.render.Size;
import gov.nasa.worldwind.view.firstperson.BasicFlyView;
import gov.nasa.worldwind.view.firstperson.FlyToFlyViewAnimator;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
///
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
import java.awt.image.BufferedImage;
public class FullScreenTest{
public static double test = 0;
/**
* The animated view
*/
public static BasicFlyView view;
/**
* The ScreenSaver entry point, should run in windowed mode
* with interactivity or fullscreen mode depending on flags
* http://boinc.berkeley.edu/trac/wiki/ScreensaverEnhancements
* @param args
*/
public static void main(String[] args) {
view = new BasicFlyView();
Frame frame = new Frame("WorldwindFull");
final WorldWindowGLCanvas worldWindowGLCanvas = new WorldWindowGLCanvas();
worldWindowGLCanvas.setModel(new BasicModel());
worldWindowGLCanvas.setView(view);
worldWindowGLCanvas.addKeyListener(new java.awt.event.KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
});
RenderableLayer creditsLayer = new RenderableLayer();
creditsLayer.setName("Credits");
try {
creditsLayer.addRenderables(createCredits());
} catch (IOException ioEx) {
ioEx.printStackTrace();
}
worldWindowGLCanvas.getModel().getLayers().add(creditsLayer);
////
RenderableLayer chartsLayer = new RenderableLayer();
chartsLayer.setName("Charts");
try {
chartsLayer.addRenderables(createCharts());
} catch (IOException ioEx) {
ioEx.printStackTrace();
}
worldWindowGLCanvas.getModel().getLayers().add(chartsLayer);
frame.add(worldWindowGLCanvas);
frame.setSize(640, 480);
frame.setUndecorated(true);
int size = frame.getExtendedState();
size |= Frame.MAXIMIZED_BOTH;
frame.setExtendedState(size);
frame.setVisible(true);
worldWindowGLCanvas.requestFocus();
setUpTimer();
}
/**
* Static method to produce credits for all involved
* organisations
* @return
* @throws IOException
*/
public static List<ScreenImage> createCredits() throws IOException
{
List<ScreenImage> allCredits = new ArrayList<ScreenImage>();
ScreenImage creditWWC = new ScreenImage();
creditWWC.setImageSource(ImageIO.read(
new File("src/images/worldwindcentral.gif")));
//TODO: More flexible out of code layout policy
creditWWC.setScreenOffset(new Offset(0.10, 0.90, AVKey.FRACTION, AVKey.FRACTION));
creditWWC.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION));
ScreenImage creditRKN = new ScreenImage();
creditRKN.setImageSource(ImageIO.read(
new File("src/images/logo_selfnet1.png")));
//TODO: More flexible out of code layout policy
creditRKN.setScreenOffset(new Offset(0.50, 0.90, AVKey.FRACTION, AVKey.FRACTION));
creditRKN.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION));
allCredits.add(creditWWC);
allCredits.add(creditRKN);
return allCredits;
}
public static List<ScreenImage> createCharts() throws IOException
{
// create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2-test);
dataset.setValue("Category 2", 27.9+test);
dataset.setValue("Category 3", 79.5);
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true, // legend?
true, // tooltips?
false // URLs?
);
//chart.createBufferedImage(100, 100);
// create and display a frame...
//ChartFrame frame1 = new ChartFrame("First", chart);
//frame1.pack();
//frame1.setVisible(true);
//frame1.createImage(100, 100);
final BufferedImage image = chart.createBufferedImage(400, 300);
List<ScreenImage> allCharts = new ArrayList<ScreenImage>();
ScreenImage chart1 = new ScreenImage();
chart1.setImageSource(image);
//TODO: More flexible out of code layout policy
chart1.setScreenOffset(new Offset(0.17, 0.60, AVKey.FRACTION, AVKey.FRACTION));
chart1.setSize(new Size(Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION,Size.MAINTAIN_ASPECT_RATIO, 0.05,
AVKey.FRACTION));
allCharts.add(chart1);
return allCharts;
}
/**
* The globe auto-rotate animator
* @param pos
*/
public static void moveToLocation(Position pos) {
if (pos == null) {
return;
}
double elevation = view.getGlobe().getElevation(pos.getLatitude(),
pos.getLongitude());
FlyToFlyViewAnimator animator = FlyToFlyViewAnimator.
createFlyToFlyViewAnimator(view, view.getEyePosition(),
new Position(pos.latitude, pos.longitude, elevation),
view.getHeading(), view.getHeading(), view.getPitch(),
view.getPitch(), view.getEyePosition().getElevation(),
view.getEyePosition().getElevation(), 10000, 0);
view.addAnimator(animator);
animator.start();
view.firePropertyChange(AVKey.VIEW, null, view);
}
/**
* Convenience timer set-up to periodically rotate the globe
*/
public static void setUpTimer()
{
int delay = 5000; // delay for 5 sec.
int period = 10000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Position pos = new Position(Angle.fromDegrees(
180*new Random().nextFloat()-90.0),
Angle.fromDegrees(
360*new Random().nextFloat()-180.0),
0.0);
moveToLocation(pos);
Random rn = new Random();
int n = 10 - 0 + 1;
int i = rn.nextInt() % n;
FullScreenTest.test = 0 + i;
System.out.println(FullScreenTest.test);
}
}, delay, period);
}
}
回答1:
So you added a renderable layer called creditsLayer which displays an image. A simple (maybe a bit crude) way to update the image is to dispose the layer (creditsLayer.dispose()
) and re-add it with another image and after worldWindowGLCanvas.redraw()
. As the screensaver won't update too often this might be acceptable. Or you can have different layers for each image you have and enable/disable them as you need and redraw the canvas. HTH
来源:https://stackoverflow.com/questions/5859286/2d-graph-animation-on-worldwindjava-canvas