0

我正在使用图形 2D 在 jpanel 上绘制线条作为缓冲图像,我想将点存储为对,即起点的 x 和 y 坐标作为一对,终点的 x 和 y 坐标作为另一个一对。由于将有几行,我想将所有这些对存储为一个列表(或者可能 2 - 一个用于起点,一个用于终点),并且能够在行移动并且点发生变化时更新它们并检查是否给定的点在列表中。我该怎么做?这可能吗?

我看过有一个 Pair 类,但我不知道它是如何工作的,以及我是否可以有一个 Pairs 列表。我也看过使用地图和数组列表,但它们似乎都没有我正在寻找的功能(或者我可能只是不知道)。

目前,我只是在画线,但没有存储点。这是完成所有绘图的类:

package floorplan;

/**
*
* @author xodkx
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.event.MouseListener;

public class Floor extends JPanel implements MouseListener, MouseMotionListener
{


  private static final int WIDTH = Integer.parseInt(JOptionPane.showInputDialog("Please    
  enter the width of your room"));
  private static final int LENGTH = Integer.parseInt(JOptionPane.showInputDialog("Please   
  enter the width of your room"));
  private static final Color BACKGROUND = Color.WHITE;
  private static final Color INITIAL_COLOUR = Color.BLACK;
  private static final Framework INITIAL_FRAMEWORK = Framework.FLEXIBLEWALL;

  private MouseState state = MouseState.IDLE;
  private Framework frameworkType = INITIAL_FRAMEWORK;
  private Color colour = INITIAL_COLOUR;



  private Point start = null; // START POINT
  private Point end = null; // END POINT


  private BufferedImage bufImage = null;


  public Floor()
  {
    setPreferredSize(new Dimension(LENGTH,WIDTH));
    setBackground(Color.white);
    setBorder(BorderFactory.createLineBorder (Color.black, 5));

    this.addMouseListener(this);
    this.addMouseMotionListener(this);

 }

 public void setColor(Color color)
 {
    colour = color;

 }

 public void setFramework(Framework framework)
 {
    frameworkType = framework;
 }

 @Override
 public void paintComponent(Graphics g)
 {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,   
     RenderingHints.VALUE_ANTIALIAS_ON);

    if(bufImage == null)
    {
        int h = this.getHeight();
        int w = this.getWidth();
        bufImage = (BufferedImage)this.createImage(h,w);
        Graphics2D gc = bufImage.createGraphics();
        gc.setColor(BACKGROUND);
        gc.fillRect(0, 0, w, h);
    }


    g2.drawImage(bufImage,null,0,0);

    drawGrid(g2);

    if(state == MouseState.DRAGGING)
    {
        createComponent(g2);
    }
 }

 public void drawGrid(Graphics g2)
 {
    int gridDivisions = 20;
    int divisionSize = WIDTH/gridDivisions;
    int grid = WIDTH*LENGTH;

    g2.setColor(Color.lightGray);

    for(int i=1; i<grid; i++)
    {
        int x = i * divisionSize;
        g2.drawLine(x,0,x,getSize().height);
    }

    for(int i=1; i<grid; i++)
    {
        int y = i*divisionSize;
        g2.drawLine(0,y,getSize().width,y);
    }
 }


 public void createComponent(Graphics2D g2)
 {
     g2.setColor(colour);

    switch (frameworkType)
    {
        case FLEXIBLEWALL:
            g2.setStroke(new BasicStroke(5));
            g2.drawLine(start.x, start.y, end.x,end.y);
            break;

        case VERTICALWALL:
            g2.setStroke(new BasicStroke(5));
            end.x = start.x;
            g2.drawLine(start.x,start.y,end.x,end.y);
            break;

        case HORIZONTALWALL:
            g2.setStroke(new BasicStroke(5));
            end.y = start.y;
            g2.drawLine(start.x,start.y,end.x,end.y);

        case DOOR:
            g2.setStroke(new BasicStroke(5));
            g2.drawLine(start.x, start.y, end.x,end.y);
            break;

        case WINDOW:
            g2.setStroke(new BasicStroke(5));
            g2.drawLine(start.x, start.y, end.x,end.y);
            break;


        default:
            g2.drawString("test", 10, 20);
            break;
     }
 }

 public void clear() 
 {

    bufImage.flush();
    bufImage = null;
    repaint();
 }


 @Override
 public void mousePressed(MouseEvent e)
 {
    state = MouseState.DRAGGING;
    start = e.getPoint();
    end = start;
 }

 @Override

 public void mouseDragged(MouseEvent e)
 {

    state = MouseState.DRAGGING;
    end = e.getPoint();
    this.repaint();

 }

  @Override
  public void mouseReleased(MouseEvent e)
 {
    end = e.getPoint();
    if(state == MouseState.DRAGGING)
    {
        state = MouseState.IDLE;
        createComponent(bufImage.createGraphics());
        this.repaint();
    }
 }

 public void updateLocation(MouseEvent e)
 {

 }


 @Override
 public void mouseClicked(MouseEvent e)
 {

 }

 @Override
 public void mouseEntered(MouseEvent e)
 {

 }

 @Override
 public void mouseExited(MouseEvent e)
 {

 }



 @Override
 public void mouseMoved(MouseEvent e)
 {

 }

}
4

3 回答 3

3

使用java.awt.geom.Line2D. 您可以将其放入列表或任何其他集合中。它有equals()hashCode()

您可以使用Line2D.Float需要更少空间的Line2D.Double哪个在计算中更方便。

如果您有数十万条这样的行,那么情况就会改变。然后它变得不那么舒服了。因为 aint[]是最节省内存的,但这是另一个问题。

于 2013-02-18T12:49:49.183 回答
0
package util;

public final class Pair<S,T> {
 public S first;
 public T second;

 public Pair(S first, T second) {
    super();
    this.first = first;
    this.second = second;
 }

 public S getFirst() {
    return first;
 }

 public T getSecond() {
    return second;
 }

 public void setFirst(S first) {
    this.first = first;
 }

 public void setSecond(T second) {
    this.second = second;
 }


 @Override
 public int hashCode() {
     final int prime = 31;
     int result = 1;
     result = prime * result + ((first == null) ? 0 : first.hashCode());
     result = prime * result + ((second == null) ? 0 : second.hashCode());
     return result;
 }

 @Override
 public boolean equals(Object obj) {
     if (this == obj)
         return true;
     if (obj == null)
         return false;
     if (getClass() != obj.getClass())
         return false;
     Pair<?,?> other = (Pair<?,?>) obj;
     if (first == null) {
         if (other.first != null)
             return false;
     } else if (!first.equals(other.first))
         return false;
     if (second == null) {
         if (other.second != null)
             return false;
     } else if (!second.equals(other.second))
         return false;
     return true;
 }

 @Override
 public String toString() {
     return "<"+first+","+second+">";
 }

}
于 2013-02-18T12:52:05.893 回答
-1

首先,您可以将所有点存储在一个列表中,因此偶数位置的点将是线段的起点,奇数位置的点将是终点:

List <Point> points = Arrays.asList (
    new Point (100, 100), new Point (200, 100),  // First line segment
    new Point (200, 100), new Point (200, 200),  // Second line segment
    new Point (200, 200), new Point (100, 100)); // Third line segment

此外,您可以将点数组存储在列表中,因此每个数组将代表一条曲线,其中原因曲线可能仅包含一个段:

List <Point []> points = Arrays.asList (
    new Point [] {new Point (100, 100), new Point (200, 100)},  // First line segment
    new Point [] {new Point (200, 100), new Point (200, 200)},  // Second line segment
    new Point [] {new Point (200, 200), new Point (200, 100), new Point (100, 100)); // Curve of third and fourth segments

当然,您可以声明自己的类来存储两个点,如下所示:

public class TwoPoints
{
    public final Point begin;
    public final Point end;

    public TwoPoints (int x1, int y1, int x2, int y2)
    {
        this (new Point (x1, y1), new Point (x2, y2));
    }

    public TwoPoints (Point begin, Point end)
    {
        this.begin = begin;
        this.end = end;
    }
}

您绝对可以将此类的对象存储在列表中:

List <TwoPoints> lines = Arrays.asList (
    new TwoPoints (100, 100, 100, 200),  // First line segment
    new TwoPoints (100, 200, 200, 200),  // Second line segment
    new TwoPoints (200, 200, 100, 100)); // Third line segment
于 2013-02-18T12:56:19.553 回答