如何连续更新JPanel? [英] How can I update JPanel continuously?

查看:125
本文介绍了如何连续更新JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小问题,我正在编写一个gps跟踪应用程序以一次跟踪多个对象.数据通过串行接口输入,据我所知,这很好.问题是我需要不断更新创建和显示地图的JPanel.

I've got a slight problem, I'm writing a gps tracking app to track several objects at once. The data comes in over a serial interface, this is coming in fine from what I can tell. The issue is that I need to continually update the JPanel where the map is created and displayed.

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变量,它将连续打印,但是在这里只打印一次.

This is what I have and it's happy to display the point once but won't update. If I print out the 1Lat variable in the serial method it continually prints, however it only does it once here.

我找到的很多答案都涉及到按数组设置标记,但是在这种情况下将不起作用,因为我要跟踪的对象可能在任何地方.

A lot of the answers I've found refer to setting markers by arrays, however that won't work in this case as the objects I'm tracking could be anywhere.

任何帮助将不胜感激:)

Any help would be greatly appreciated :)

推荐答案

是否可以使用辅助线程而不使用ArrayList?如果这样做,我将冒丢失数据的风险.

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 中,您对方法可以publish()结果可用.尤其要注意:"publish()的多次调用所产生的结果通常是对process()的单次调用所累积的".在您的process()中,只需遍历List<Coordinate>,更新routerepaint() map.

Not necessarily. In a SwingWorker, your implementation of the doInBackground() method can publish() results as they become available. Note in particular that "Results from multiple invocations of publish() are often accumulated for a single invocation of process()." In your process(), simply loop through the List<Coordinate>, update the route and repaint() the 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 http://stackoverflow.com/a/37193636/230513
 */
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);
    }
}

剩下的是多路线管理.

这篇关于如何连续更新JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆