JavaSwing-如何在画布中绘制新线并将其添加到现有线中?
我已经在JavaSwing中绘制了哥本哈根的地图,但是我希望能够在地图上绘制新的线条,然后将它们添加到现有的线条中,我从缓冲读取器中获取这些线条。我曾尝试将新绘制的线条添加到临时线条的arraylist中,但这似乎不起作用-我再也无法在画布上绘制了。有人能帮忙吗JavaSwing-如何在画布中绘制新线并将其添加到现有线中?,java,swing,Java,Swing,我已经在JavaSwing中绘制了哥本哈根的地图,但是我希望能够在地图上绘制新的线条,然后将它们添加到现有的线条中,我从缓冲读取器中获取这些线条。我曾尝试将新绘制的线条添加到临时线条的arraylist中,但这似乎不起作用-我再也无法在画布上绘制了。有人能帮忙吗 public class Model extends Observable implements Iterable<Line2D>, Serializable { private List<Line2D>
public class Model extends Observable implements Iterable<Line2D>, Serializable {
private List<Line2D> lines;
private List<Line2D> tmpLines;
public Model() {
lines = new ArrayList<>();
tmpLines = new ArrayList<>();
}
public Model(String filename) {
readFromFile(filename);
}
public void add(Line2D line) {
lines.add(line);
dirty();
}
public void dirty() {
setChanged();
notifyObservers();
}
public void readFromFile(String filename) {
lines = new ArrayList<>();
tmpLines = new ArrayList<>();
try {
BufferedReader b = new BufferedReader(new FileReader(filename));
for (String line = b.readLine(); line != null; line = b.readLine() ) {
String[] tokens = line.split(" ");
if (tokens[0].equals("LINE")) {
double x1 = Double.parseDouble(tokens[1]);
double y1 = Double.parseDouble(tokens[2]);
double x2 = Double.parseDouble(tokens[3]);
double y2 = Double.parseDouble(tokens[4]);
lines.add(new Line2D.Double(x1, y1, x2, y2));
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
@Override
public Iterator<Line2D> iterator() {
return lines.iterator();
}
public Line2D removeLastFromTmpLines() {
Line2D line = tmpLines.remove(tmpLines.size() - 1);
dirty();
return line;
}
public Line2D removeLastFromLines() {
Line2D line = lines.remove(lines.size() - 1);
dirty();
return line;
}
public void addTmpLinesToLines() {
lines.addAll(tmpLines);
dirty();
}
public void addToTmpLines(Line2D line2D) {
tmpLines.add(line2D);
dirty();
}
public List<Line2D> getTmpLines() {
return tmpLines;
}
}
public class MouseController extends MouseAdapter {
private Model model;
private CanvasView canvas;
private Point2D lastMousePosition;
public MouseController(CanvasView c, Model m) {
canvas = c;
model = m;
canvas.addMouseListener(this);
canvas.addMouseWheelListener(this);
canvas.addMouseMotionListener(this);
}
@Override
public void mouseDragged(MouseEvent e) {
Point2D currentMousePosition = e.getPoint();
if (canvas.inDrawingMode()) {
Point2D origin = model.removeLastFromTmpLines().getP1();
model.addToTmpLines(new Line2D.Double(origin, canvas.toModelCoords(currentMousePosition)));
}
else {
double dx = currentMousePosition.getX() - lastMousePosition.getX();
double dy = currentMousePosition.getY() - lastMousePosition.getY();
canvas.pan(dx, dy);
}
lastMousePosition = currentMousePosition;
}
@Override
public void mousePressed(MouseEvent e) {
lastMousePosition = e.getPoint();
if (canvas.inDrawingMode()) {
model.addToTmpLines(new Line2D.Double(
canvas.toModelCoords(lastMousePosition),
canvas.toModelCoords(lastMousePosition)));
}
}
public void mouseMoved(MouseEvent e) {
Point2D modelCoords = canvas.toModelCoords(e.getPoint());
//System.out.println("Screen: [" + e.getX() + ", " + e.getY() + "], "+"Model: [" + modelCoords.getX() + ", " + modelCoords.getY() + "]");
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double factor = pow(1.1, e.getWheelRotation());
canvas.zoom(factor, -e.getX(), -e.getY());
}
}
public类模型扩展了Observable实现,可移植、可序列化{
私有列表行;
私人名单;
公共模型(){
行=新的ArrayList();
tmpLines=新的ArrayList();
}
公共模型(字符串文件名){
readFromFile(文件名);
}
公共空白添加(Line2D线){
行。添加(行);
脏的();
}
公共空间{
setChanged();
通知观察员();
}
public void readFromFile(字符串文件名){
行=新的ArrayList();
tmpLines=新的ArrayList();
试一试{
BufferedReader b=新的BufferedReader(新文件读取器(文件名));
对于(字符串行=b.readLine();行!=null;行=b.readLine()){
String[]tokens=line.split(“”);
if(标记[0]。等于(“行”)){
double-x1=double.parseDouble(令牌[1]);
double y1=double.parseDouble(令牌[2]);
double x2=double.parseDouble(令牌[3]);
double y2=double.parseDouble(令牌[4]);
添加(新的Line2D.Double(x1,y1,x2,y2));
}
}
}
catch(filenotfounde异常){
e、 printStackTrace();
}
捕获(IOE异常){
e、 printStackTrace();
}
}
/**
*返回{@code T}类型元素的迭代器。
*
*@返回一个迭代器。
*/
@凌驾
公共迭代器迭代器(){
返回行。迭代器();
}
public Line2D RemoveLastFromtPlines(){
Line2D line=tmpLines.remove(tmpLines.size()-1);
脏的();
回流线;
}
public Line2D removeLastFromLines(){
Line2D line=lines.remove(lines.size()-1);
脏的();
回流线;
}
public void addTmpLinesToLines(){
行。添加所有(tmpLines);
脏的();
}
公共void addToTemplines(Line2D Line2D){
tmpLines.add(line2D);
脏的();
}
公共列表getTemplines(){
返回tmpLines;
}
}
公共类MouseController扩展了MouseAdapter{
私有模型;
私人画布;
私人鼠标位置;
公共鼠标控制器(CanvasView c,m型){
canvas=c;
模型=m;
canvas.addMouseListener(本);
canvas.addMouseWheelListener(此);
canvas.addMouseMotionListener(此);
}
@凌驾
公共无效鼠标标记(鼠标事件e){
Point2D currentMousePosition=e.getPoint();
if(canvas.inDrawingMode()){
Point2D origin=model.removeLastFromTmpLines().getP1();
model.addToTemplines(新的Line2D.Double(origin、canvas.toModelCoords(currentMousePosition));
}
否则{
double dx=currentMousePosition.getX()-lastMousePosition.getX();
double dy=currentMousePosition.getY()-lastMousePosition.getY();
canvas.pan(dx,dy);
}
lastMousePosition=currentMousePosition;
}
@凌驾
公共无效鼠标按下(MouseEvent e){
lastMousePosition=e.getPoint();
if(canvas.inDrawingMode()){
model.AddToTemplines(新的Line2D.Double(
canvas.toModelCoords(lastMousePosition),
canvas.toModelCoords(lastMousePosition));
}
}
public void mouseMoved(MouseEvent e){
Point2D modelCoords=canvas.toModelCoords(e.getPoint());
//System.out.println(“屏幕:[“+e.getX()+”,“+e.getY()+”],“+”模型:[“+modelCoords.getX()+”,“+modelCoords.getY()+”);
}
@凌驾
已移动公共无效鼠标滚轮(鼠标滚轮事件e){
双因素=功率(1.1,即getWheelRotation());
缩放(factor,-e.getX(),-e.getY());
}
}
老实说,我不太理解代码,因为我看不到绘制方法,所以我看不到对数组的处理。我支持在列表中添加行,并使用迭代器方法将它们返回到paint方法
我支持在按下鼠标按钮时添加点,而不是线:
model.addToTmpLines(new Line2D.Double(
canvas.toModelCoords(lastMousePosition),
canvas.toModelCoords(lastMousePosition)));
点,因为坐标相同。然后,拖动鼠标时,删除最后一条线(点),并从点的起始坐标添加一条新线到实际鼠标位置。是这样吗?但是,您什么时候将tmp列表中的行传递到真实列表中?您不需要一个mousererelease方法来将tmp列表中的行传递到实际列表吗?迭代器方法只返回列表行,因此我支持不绘制最后一行,即正在拖动的行,因为实际的新行位于tmpLines列表中,并且不会返回
但是我认为我没有看到整个画面,所以我的评论可能没有用…当你更新模型时,你必须重新绘制视图。我正在视图类中更新模型。我解决了我的问题,现在可以在画布上画画了。但是,当我试图将添加的行保存到现有行时,会得到一个NullPointerException。您知道这可能是什么原因吗?好的,使用ex.printStackTrace查看引发异常的行,并使用调试器查看哪个变量为null。如果使用addTmpLinesToLines方法,则averything看起来不错,因为创建了两个列表,但问题可能出在调用dirty()后激发的方法中。例如,printStackTrace非常适合于此