2011-05-11 43 views
1

我正在开发Java中的XFDL渲染应用程序。 XFDL是一种表单定义语言,是XML的扩展。在JPanel上绘制错误的线

渲染类使用StAX处理文档并将所需的项目添加到自定义的JPanel中进行显示。我已经成功地将字段(JTextFields)和标签(JLabels)添加到JPanel行成为问题。当用多个页面构建表单时,当我显示表单时,每个页面都会获取表单中最后一页的行。

我已经通过我的代码(如下所示),不能想出这种行为的原因。当我通过时,所有的计数器都会正确递增,以便将行添加到正确的页面,但我总是会在当前页面的标签和字段后面找到最后一行。

我怀疑我误解了Java如何处理绘图的问题,但我不确定是什么。

在此先感谢您的答案和建议。

在XFDL文档线被定义为这样:

<page SID="PAGE1"> 
     <line sid="LINE1"> 
     <itemlocation> 
      <ae> 
       <ae>absolute</ae> 
       <ae>1219</ae> 
       <ae>75</ae> 
      </ae> 
      <ae> 
       <ae>extent</ae> 
       <ae>3</ae> 
       <ae>854</ae> 
      </ae> 
     </itemlocation> 
     </line> 
     ... 
</page> 
<page SID="PAGE2"> 
     <line sid="LINE2"> 
     <itemlocation> 
      <ae> 
       <ae>absolute</ae> 
       <ae>1219</ae> 
       <ae>75</ae> 
      </ae> 
      <ae> 
       <ae>extent</ae> 
       <ae>3</ae> 
       <ae>854</ae> 
      </ae> 
     </itemlocation> 
     </line> 
     ... 
</page> 

当渲染类到达标签下面的方法被称为:

private ArrayList<FormPanel> pages; 

/** 
* Draws a new line on the Panel 
* 
* Start State: Cursor is positioned on the <line> start element. 
* End State: Cursor is positioned on the <line> end element. 
* 
* @throws XMLStreamException 
*/ 
private void addLine() throws XMLStreamException { 
    while(reader.hasNext() && 
      !(reader.isEndElement() && 
        reader.getLocalName().equals(XFDL_LINE))) { 

     reader.next(); 
     if(reader.isStartElement()) { 
      if(reader.getLocalName().equals(XFDL_ITEMLOCATION)) { 
       pages.get(currentPage).addLine(processItemLocation()); 
      } 
     } 
    } 

} 

/** 
* Processes an item location field into a Rectangle object used to set 
* the bounds and location of form item. 
* Start State: Cursor positioned on the itemlocation start element. 
* End State: Cursor positioned on the itemlocation end element 
* 
* Currently only handles absolute positioning and extent sizes. 
* Any other form of positioning data returns null. 
* 
* @return Rectangle representing the location and size of item. 
* @throws XMLStreamException 
*/ 
private Rectangle processItemLocation() throws XMLStreamException { 
    Rectangle result = new Rectangle(); 

    ArrayList<String> attributes = new ArrayList<String>(); 

    while(reader.hasNext() && 
      !(reader.isEndElement() && 
        reader.getLocalName().equals(XFDL_ITEMLOCATION))) 
    { 
     reader.next(); 
     if(reader.isCharacters() && !reader.isWhiteSpace()) { 
      attributes.add(reader.getText()); 
     } 
    } 

    for(int x=0; x<attributes.size(); x++) { 
     if(attributes.get(x).equals(XFDL_LOCATION_STYLE_ABSOLUTE)) { 
      result.setLocation(Integer.parseInt(attributes.get(x+1)), 
        Integer.parseInt(attributes.get(x+2))); 
     } else if(attributes.get(x).equals(XFDL_LOCATION_SIZE_EXTENT)) { 
      result.setSize(Integer.parseInt(attributes.get(x+1)), 
        Integer.parseInt(attributes.get(x+2))); 
     } else { 
      try{ 
       Integer.parseInt(attributes.get(x)); 
      } catch (NumberFormatException nfe) { 
       result = null; 
       x = attributes.size(); 
      } 
     } 
    } 

    return result; 
} 

FormPanel中是JPanel的延伸具有额外方法addLine()和重写的paintComponent()如下所示:

private static ArrayList<Rectangle> lines; 

public void addLine(Rectangle line) { 
    lines.add(line); 
} 

/** 
* Overrides JPanel paintComponenet and draws lines on the form. 
*/ 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    for(int x = 0; x<lines.size(); x++) { 
     g.drawRect(lines.get(x).x, 
       lines.get(x).y, 
       lines.get(x).width, 
       lines.get(x).height); 
     g.fillRect(lines.get(x).x, 
       lines.get(x).y, 
       lines.get(x).width, 
       lines.get(x).height); 
    } 
} 
+0

您是否使用CardLayout来显示各种页面,或者是这样,还是每个页面在垂直之前就在页面之下? – MeBigFatGuy 2011-05-11 17:46:03

回答

1

看起来当你进入一个新页面,你应该打电话

lines.clear(); 

假设每个页面都在它自己的容器中。

当然,行变量被定义为静态,所以你有一个行容器为整个文档。人们会认为你想要每页一个,所以静态的使用似乎是可疑的。

+0

我甚至不记得在行ArrayList上写入静态修饰符。放下它,一切都一起来了。 – MrWizard54 2011-05-11 23:02:43