首先,一些背景。我正在使用Java构建我的第一个GUI应用程序,但我不确定如果我以正确的方式进行操作,因为我不熟悉GUI类。最终目标是根据开放街道地图数据构建可调整大小的可缩放滚动地图。JPanel重新调整大小重绘几次,有时根本没有
我现在所拥有的是JPanel的一个子类,我在JFrame中调用LinePanel,并使用Graphics对象绘制表示道路的线条。这对于检查我是否正确地解析和解释数据的目的是正确的,但它似乎不够和天真。我已经遇到了一个问题,JPanel在重新调整大小后重新绘制了几次,导致地图出错,直到我的应用程序需要癫痫警告。
这是我现在的代码:
package map;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MapDisplay {
private JFrame frame;
private LinePanel jpanel;
public MapDisplay(Map map) {
this.frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
jpanel.repaint();
}
});
jpanel = new LinePanel(map);
frame.add(jpanel, BorderLayout.CENTER);
}
public void display() {
frame.setSize(710, 935);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jpanel.repaint();
}
class LinePanel extends JPanel {
private static final long serialVersionUID = 1965018056953712219L;
private Map map;
private int width;
private int height;
private int latAsY(double lat) {
return height
- (int) (height * (lat - map.getMinLat())/(map
.getMaxLat() - map.getMinLat()));
}
private int lonAsX(double lon) {
return (int) (width * (lon - map.getMinLong())/(map.getMaxLong() - map
.getMinLong()));
}
private void recalculateDimensions() {
double mapRatio = (map.getMaxLat() - map.getMinLat())
/(map.getMaxLong() - map.getMinLong());
double panelRatio = this.getHeight()/(double) this.getWidth();
if (mapRatio > panelRatio) {
width = (int) (this.getHeight()/mapRatio);
height = this.getHeight();
} else {
width = this.getWidth();
height = (int) (mapRatio * this.getWidth());
}
}
public LinePanel(Map map) {
super();
this.map = map;
}
public void repaint() {
if (map != null) {
recalculateDimensions();
Graphics2D g = (Graphics2D) this.getGraphics();
if (g != null) {
g.setStroke(new BasicStroke(2));
g.clearRect(0, 0, jpanel.getWidth(), jpanel.getHeight());
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
g.setColor(Color.BLACK);
for (String wayId : map.getWays()) {
Way way = map.getWay(wayId);
Node prev = null;
for (String nodeId : way.getNodes()) {
Node cur = map.getNode(nodeId);
if (prev != null) {
int y1 = latAsY(prev.getLatitude());
int x1 = lonAsX(prev.getLongitude());
int y2 = latAsY(cur.getLatitude());
int x2 = lonAsX(cur.getLongitude());
g.drawLine(x1, y1, x2, y2);
}
prev = cur;
}
}
}
}
}
}
}
我打电话重新绘制调整大小,因为它不会自动做到这一点,我做错了又一个迹象。我也用g.fillRect手动清除了JPanel,因为在重绘图之前调用super.repaint()会导致没有任何东西出现...
本质上,我只想从更高级的Java程序员那里得到一些指导,应该全力以赴。如果我走在正确的道路上,随意推动我朝着正确的方向前进,而不是让我走上新的道路,但我怀疑是这样。
谢谢,我知道我必须做一些完全错误的事情。我刚刚发现了其他一些问题,其他问题的做法与思维练习类似,没有人正在纠正它们。 – 2015-03-19 02:50:55
为了能够进一步解决它,我们需要看到一个[runnable示例](https://stackoverflow.com/help/mcve),它演示了您的问题。这不是代码转储,而是您正在做的事情的一个例子,它突出了您遇到的问题。这会导致更少的混淆和更好的响应 – MadProgrammer 2015-03-19 02:54:28
只是好奇,为什么paintComponent更适合重绘? – 2015-03-19 02:55:35