如何持续更新 JPanel?
How can I update JPanel continuously?
我遇到了一个小问题,我正在编写一个 gps 跟踪应用程序来同时跟踪多个对象。数据通过串行接口传入,据我所知,这很好。问题是我需要不断更新创建和显示地图的 JPanel。
public JPanel mapDisplay(){
JPanel mapPanel = new JPanel();
mapPanel.setSize(560, 540);
Coordinate start = new Coordinate (-34.9286, 138.6);
trackMap.addMapMarker(new MapMarkerDot(1Lat, 1Lon));
trackMap.setDisplayPosition(start,8);
System.out.println(1Lat);
mapPanel.add(trackMap);
mapPanel.setVisible(true);
return mapPanel;
}
这就是我所拥有的,很高兴显示一次但不会更新。如果我在串行方法中打印出 1Lat 变量,它会不断打印,但它只在这里打印一次。
我找到的很多答案都涉及通过数组设置标记,但是在这种情况下这不起作用,因为我正在跟踪的对象可能在任何地方。
任何帮助将不胜感激:)
Is it possible to use a worker thread and not use an ArrayList
? I would run the risk of missing data if I do.
不一定。在 SwingWorker
中,您对 doInBackground()
方法的实施可以 publish()
结果可用。请特别注意 "Results from multiple invocations of publish()
are often accumulated for a single invocation of process()
." 在您的 process()
中,只需循环遍历 List<Coordinate>
,更新 route
和 repaint()
map
.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.MapPolygonImpl;
/**
* @see
*/
public class MapWorkerTest {
private final List<Coordinate> route = new ArrayList<>();
private void display() {
JFrame f = new JFrame("MapWorker");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMapViewer map = new JMapViewer() {
@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
@Override
public String getToolTipText(MouseEvent e) {
Coordinate c = (Coordinate) getPosition(e.getX(), e.getY());
return c.getLat() + " " + c.getLon();
}
};
map.setToolTipText("");
Coordinate start = new Coordinate(-34.9286, 138.6);
route.add(start);
MapPolygonImpl poly = new MapPolygonImpl(route);
poly.setColor(Color.blue);
map.addMapPolygon(poly);
map.setDisplayPosition(start, 10);
f.add(map);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
new MapWorker(map, start).execute();
}
private class MapWorker extends SwingWorker<Void, Coordinate> {
private final JMapViewer map;
private Coordinate last;
public MapWorker(JMapViewer map, Coordinate start) {
this.map = map;
this.last = start;
}
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
last = new Coordinate(last.getLat() + 0.0025, last.getLon() + 0.01);
publish(last);
Thread.sleep(1000);
}
return null;
}
@Override
protected void process(List<Coordinate> chunks) {
for (Coordinate c : chunks) {
route.add(c);
}
map.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new MapWorkerTest()::display);
}
}
多条路线管理留作练习。
我遇到了一个小问题,我正在编写一个 gps 跟踪应用程序来同时跟踪多个对象。数据通过串行接口传入,据我所知,这很好。问题是我需要不断更新创建和显示地图的 JPanel。
public JPanel mapDisplay(){
JPanel mapPanel = new JPanel();
mapPanel.setSize(560, 540);
Coordinate start = new Coordinate (-34.9286, 138.6);
trackMap.addMapMarker(new MapMarkerDot(1Lat, 1Lon));
trackMap.setDisplayPosition(start,8);
System.out.println(1Lat);
mapPanel.add(trackMap);
mapPanel.setVisible(true);
return mapPanel;
}
这就是我所拥有的,很高兴显示一次但不会更新。如果我在串行方法中打印出 1Lat 变量,它会不断打印,但它只在这里打印一次。
我找到的很多答案都涉及通过数组设置标记,但是在这种情况下这不起作用,因为我正在跟踪的对象可能在任何地方。
任何帮助将不胜感激:)
Is it possible to use a worker thread and not use an
ArrayList
? I would run the risk of missing data if I do.
不一定。在 SwingWorker
中,您对 doInBackground()
方法的实施可以 publish()
结果可用。请特别注意 "Results from multiple invocations of publish()
are often accumulated for a single invocation of process()
." 在您的 process()
中,只需循环遍历 List<Coordinate>
,更新 route
和 repaint()
map
.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.MapPolygonImpl;
/**
* @see
*/
public class MapWorkerTest {
private final List<Coordinate> route = new ArrayList<>();
private void display() {
JFrame f = new JFrame("MapWorker");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMapViewer map = new JMapViewer() {
@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
@Override
public String getToolTipText(MouseEvent e) {
Coordinate c = (Coordinate) getPosition(e.getX(), e.getY());
return c.getLat() + " " + c.getLon();
}
};
map.setToolTipText("");
Coordinate start = new Coordinate(-34.9286, 138.6);
route.add(start);
MapPolygonImpl poly = new MapPolygonImpl(route);
poly.setColor(Color.blue);
map.addMapPolygon(poly);
map.setDisplayPosition(start, 10);
f.add(map);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
new MapWorker(map, start).execute();
}
private class MapWorker extends SwingWorker<Void, Coordinate> {
private final JMapViewer map;
private Coordinate last;
public MapWorker(JMapViewer map, Coordinate start) {
this.map = map;
this.last = start;
}
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
last = new Coordinate(last.getLat() + 0.0025, last.getLon() + 0.01);
publish(last);
Thread.sleep(1000);
}
return null;
}
@Override
protected void process(List<Coordinate> chunks) {
for (Coordinate c : chunks) {
route.add(c);
}
map.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new MapWorkerTest()::display);
}
}
多条路线管理留作练习。