gpt4 book ai didi

java - Swing Graphics 对象未在 JLabel 中绘制图像

转载 作者:行者123 更新时间:2023-12-03 21:00:44 25 4
gpt4 key购买 nike

我正在创建一个 Java 程序,它通过 TCP 套接字连接在 map 的二维图像上接收和绘制 GPS 坐标。构造函数创建 JFrame 和图形组件,然后启动一个 SwingWorker 线程来处理从套接字获取坐标,然后绘制一个椭圆来表示 map 上的修复。

我总是能够通过连接接收数据,但程序无法可靠地在图像上绘制点。

任何建议,谢谢!

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

import connectivity.TelitSocketServer;
import calculations.PlottingMath;
import objects.ElephantFix;

@SuppressWarnings("serial")
public class Gui
{
protected JFrame mainWindow;

protected JPanel mapArea = new JPanel();

private ReceiveFix rfix;

public Gui()
{
// TODO Auto-generated constructor stub

mainWindow = new JFrame();

// Load map image
Image map = null;
try
{
File mapImage = new File("map_images/AWE_PLOT.JPG");
map = ImageIO.read(mapImage);

} catch (Exception e)
{
System.out.println(e.toString());
}



JLabel label = new JLabel(new ImageIcon(map));
mapArea.add(label);


// Map Image Dimensions

mainWindow.getContentPane().add(mapArea, "Center");

mainWindow.setSize(471, 670);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setTitle("ElePlotter");
mainWindow.setVisible(true);

rfix = new ReceiveFix();
rfix.execute();

}

public static void main(String args[])
{
new Gui();

}

private class ReceiveFix extends SwingWorker<Void, ElephantFix>
{

@Override
protected Void doInBackground()
{
// Start the server
String fix = "";

TelitSocketServer currentConnection = new TelitSocketServer();
try
{
// Wait for client to connect
currentConnection.intializeConnection();

while (true)
{
// Parse and convert received GPS fix into arc radians
fix = currentConnection.readLine();

String[] split = fix.split(" ");


double latWholeDegrees = Double.parseDouble(split[0]
.substring(0, 3));
double longWholeDegrees = Double.parseDouble(split[1]
.substring(0, 3));

double latMinutes = Double.parseDouble(split[0]
.substring(3)) * .166667;
double longMinutes = Double.parseDouble(split[1]
.substring(3)) * .166667;


double lat = latWholeDegrees - latMinutes / 10;
double lon = longWholeDegrees + longMinutes / 10;

publish(new ElephantFix(lat, lon));
}

} catch (Exception e)
{

e.printStackTrace();
}

// Return null if somehow unable to publish node data
return null;

}


@Override
protected void process(List<ElephantFix> fixes)
{
int x, y;
// Get the most recently published node
ElephantFix aFix = fixes.get(fixes.size() - 1);



// Translate lat/long into map X/Y pixel
x = PlottingMath.getCurrentPixelX(aFix.getLatitude(),
aFix.getLongitude());
y = PlottingMath.getCurrentPixelY(aFix.getLatitude(),
aFix.getLongitude());


// Plot on image
Graphics g = mapArea.getGraphics();

g.setColor(Color.RED);

g.fillOval(x, y, 15, 15);

// mapArea.validate();
//
// mapArea.repaint();
//
// Gui.this.repaint();

}
}

}

最佳答案

mapArea.getGraphics(); 并不是 Swing 中自定义绘画的完成方式。

先看看 Performing Custom Painting了解更多详情。

将组件添加到容器可确保子组件始终绘制在容器上...

JLabel label = new JLabel(new ImageIcon(map));
mapArea.add(label);

你把它倒过来了。将 labelmapArea 添加到同一个容器中可能会更好

您需要克服的下一个问题是您需要让绘画组件驻留在标签的顶部。

为此你可以...

用例子更新

有多种方法可以实现这一点,您可以使用多个组件作为图层,您可以在图层上添加其他组件或执行自定义绘画。

这并不像听起来那么容易。大多数布局管理器不考虑共享同一空间的两个组件。您还必须管理层之间的连接,因此如果 map 位于最低层的中心,但可用空间大于或小于 map ,偏移量开始漂移……困惑……

一个更简单的解决方案是使用单个组件并将所有内容渲染到它上面,例如......

Map

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestMap {

public static void main(String[] args) {
new TestMap();
}

public TestMap() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

MapPane pane = new MapPane();
pane.dropPinAt(174, 147);

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(pane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class MapPane extends JPanel {

private BufferedImage img;
private BufferedImage pin;
private List<Point> pins;

public MapPane() {
pins = new ArrayList<>(25);
try {
img = ImageIO.read(getClass().getResource("/Map.jpg"));
pin = ImageIO.read(getClass().getResource("/Pin.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();

int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;

g2d.drawImage(img, x, y, this);

for (Point p : pins) {
// Offset the pin x/y
// to allow the point to land on the desired location
p.x -= 6;
p.y -= 64;
System.out.println(p);
g2d.drawImage(pin, p.x, p.y, this);

}

g2d.dispose();
}
}

protected void dropPinAt(int x, int y) {
pins.add(new Point(x, y));
}
}

}

关于java - Swing Graphics 对象未在 JLabel 中绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22624354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com