На JPanel нарисованы неправильные линии - PullRequest
1 голос
/ 11 мая 2011

Я занимаюсь разработкой приложения рендеринга XFDL на Java.XFDL - это язык определения формы, который является расширением XML.

Класс визуализации использует 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);
    }
}

1 Ответ

1 голос
/ 11 мая 2011

Казалось бы, когда вы входите на новую страницу, вы должны вызвать

lines.clear();

Предполагая, что каждая страница находится в своем собственном контейнере.

Конечно, переменная lines определяется как статическаяТаким образом, у вас есть один контейнер строк для всего документа.Можно подумать, что вам нужно по одному на страницу, поэтому использование статики кажется сомнительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...