【发布时间】:2014-03-04 00:06:34
【问题描述】:
我正在编写一个程序,允许用户在JLabel 上绘制矩形,并显示这些矩形的交集和并集。我已经为该类设置了 GUI,但正在努力寻找一种方法来集成矩形类中的交集和联合方法。我知道这些方法在与 GUI 分开使用时有效。
当我尝试运行程序时,我不断收到IndexOutOfBoundsException,并且绘制的矩形从 gui 中清除。每个矩形的交点在JLabel 上应以不同的颜色显示。我尝试调试程序,由于某种原因,当我创建两个矩形并将它们存储在我的数组列表中时,正在创建许多具有相同特征的矩形对象。
对于 union 方法,应该创建一个包含内部所有矩形的新矩形。
矩形框1:
public class RectangleFrame1 extends JFrame implements ActionListener
{
JPanel buttonPanel;
JButton saveImage;
JButton clearImage;
JCheckBox intersections;
JCheckBox union;
RectangleLabel drawingArea;
boolean intersect = false;
boolean uni = false;
public RectangleFrame1()
{
super();
setTitle("Rectangles");
setSize(600,600);
setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(buttonPanel, BorderLayout.SOUTH);
intersections = new JCheckBox("Draw Intersections");
buttonPanel.add(intersections);
intersections.addActionListener(this);
intersections.setActionCommand("Intersections");
union = new JCheckBox("Draw Union");
buttonPanel.add(union);
union.addActionListener(this);
union.setActionCommand("Union");
saveImage = new JButton("Save Image");
saveImage.setMargin(new Insets(0,0,0,0));
buttonPanel.add(saveImage);
saveImage.addActionListener(this);
saveImage.setActionCommand("Save Image");
clearImage = new JButton("Clear Image");
clearImage.setMargin(new Insets(0,0,0,0));
buttonPanel.add(clearImage);
clearImage.addActionListener(this);
clearImage.setActionCommand("Clear Image");
drawingArea = new RectangleLabel();
drawingArea.setBorder(BorderFactory.createLineBorder(Color.blue));
this.add(drawingArea, BorderLayout.CENTER);
drawingArea.addMouseListener((MouseListener) drawingArea);
drawingArea.addMouseMotionListener((MouseMotionListener) drawingArea);
}
@Override
public void actionPerformed(ActionEvent arg0)
{
switch(arg0.getActionCommand())
{
case "Intersections":
if(intersections.isSelected())
{
intersect = true;
}
else
{
intersect = false;
}
case "Union":
if(union.isSelected())
{
uni = true;
}
else
{
uni = false;
}
case "Clear Image": drawingArea.clearImage();
case "Save Image": drawingArea.saveImage();
}
}
class RectangleLabel extends JLabel implements MouseListener, MouseMotionListener
{
Rectangle rectangle = null;
int x, y, x2, y2;
ArrayList<Rectangle> a = new ArrayList();
int counter;
public RectangleLabel()
{
super();
}
@Override
public void mousePressed(MouseEvent arg0)
{
x = arg0.getX();
y = arg0.getY();
rectangle = new Rectangle(x, y, 0, 0);
}
@Override
public void mouseDragged(MouseEvent arg0)
{
// TODO Auto-generated method stub
x2 = arg0.getX();
y2 = arg0.getY();
if(rectangle.getX() > x2)
{
rectangle.setWidth(x-x2);
}
if(x2 > rectangle.getX())
{
rectangle.setWidth(x2-x);
}
if(y > y2)
{
rectangle.setHeight(y-y2);
}
if(y2 > y)
{
rectangle.setHeight(y2-y);
}
a.add(rectangle);
counter++;
repaint();
}
@Override
public void mouseReleased(MouseEvent arg0)
{
repaint();
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(rectangle != null)
{
for(int i = 0; i < a.size(); i++)
{
float thickness = 2;
((Graphics2D) g).setStroke(new BasicStroke(thickness));
g.setColor(Color.BLUE);
g.drawRect(a.get(i).getX(), a.get(i).getY(), a.get(i).getWidth(), a.get(i).getHeight());
g.setColor(Color.gray);
g.fillRect(a.get(i).getX(), a.get(i).getY(), a.get(i).getWidth(), a.get(i).getHeight());
}
}
if(intersect == true && counter > 0)
{
for(int h = 0; h < counter-1; h++)
{
for(int j = 1; j < counter; j++)
{ if(a.get(h).overlaps(a.get(j)))
{
Rectangle rect = a.get(h).intersect(a.get(j));
g.setColor(Color.RED);
g.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
}
}
}
if(uni == true && counter > 0)
{
for(int h = 0; h < counter - 1; h++)
{
for(int j = 1; j < counter; j++)
{
Rectangle rect = a.get(h).union(a.get(j));
g.setColor(Color.WHITE);
g.drawRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
}
}
}
public void saveImage()
{
BufferedImage image = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D aaaaa = image.createGraphics();
aaaaa.setBackground(Color.WHITE);
aaaaa.clearRect(0, 0, this.getWidth(), this.getHeight());
this.paintAll(aaaaa);
try
{
File output = new File("rectangle.png");
ImageIO.write(image, "Rectangles", output);
}
catch(IOException ie)
{
}
}
public void clearImage()
{
a.clear();
repaint();
}
}
}
矩形:
public class Rectangle
{
private int x,y,width,height;
public Rectangle(int x,int y,int width,int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rectangle(Rectangle a)
{
this.x = a.x;
this.y = a.y;
this.width = a.width;
this.height = a.height;
}
public String toString()
{
return "Start: ("+x+","+y+"), Width: "+width+", Height: "+height+"\n";
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public void setX(int x)
{
this.x = x;
}
public void setY(int y)
{
this.y = y;
}
public void setWidth(int width)
{
this.width = width;
}
public void setHeight(int height)
{
this.height = height;
}
public int area()
{
return width*height;
}
public boolean overlaps(Rectangle a)
{
if ((x>a.x+a.width) || (a.x>x+width) || (y>a.y+a.height) || (a.y>y+height))
{
return false;
}
return true;
}
public Rectangle intersect(Rectangle a)
{
if (!overlaps(a))
return null;
int left,right,top,bottom;
if (x<a.x)
left = a.x;
else
left = x;
if (y<a.y)
bottom = a.y;
else
bottom = y;
if ((x+width)<(a.x+a.width))
right = x+width;
else
right = a.x+a.width;
if ((y+height)<(a.y+a.height))
top = y+height;
else
top = a.y+a.height;
return new Rectangle(left,bottom,right-left,top-bottom);
}
public Rectangle union(Rectangle a)
{
int left,right,top,bottom;
if (x<a.x)
left = x;
else
left = a.x;
if (y<a.y)
bottom = y;
else
bottom = a.y;
if ((x+width)<(a.x+a.width))
right = a.x+a.width;
else
right = x+width;
if ((y+height)<(a.y+a.height))
top = a.y+a.height;
else
top = y+height;
return new Rectangle(left,bottom,right-left,top-bottom);
}
}
【问题讨论】:
-
你在使用什么
Rectangle类?由于java.awt.Rectangle没有setWidth方法 -
是我自己创建的一个矩形类。
-
您可能也想提供,否则我们无法运行代码...
-
是的。完整的堆栈跟踪也很好,并指出其中提到了您发布的内容的哪些行。否则,需要通读大量内容以查找可能的异常情况。
-
除了 union() 方法之外,还有什么令人信服的理由来编写自己的 Rectangle 类吗?我不时提出自己的常见对象实现,只是为了了解事物的工作原理,但在实践中,我总是回到经过验证的真实。
标签: java swing intersection