Статьи

Как визуализировать XML в диаграммах JavaFX

Допустим, у вас есть XML-файлы, полученные в результате какого-то процесса, которые выглядят так:

<graph caption="Monthly Revenue (in US Dollars)">
  <set name="Jan" value="25000" />
  <set name="Feb" value="35000" />
  <set name="Mar" value="42300" />
  <set name="Apr" value="35300" />
  <set name="May" value="31300" />
  <set name="Jun" value="37300" />
</graph>

Теперь мы хотим создать редактор XML для вышеуказанного файла, который выглядит следующим образом:

В то же время мы хотим визуализировать / визуализировать XML-файл, для которого диаграммы JavaFX являются абсолютно блестящими. Они просты в использовании и допускают анимацию в реальном времени, что круто. Вот пример того, как вышеперечисленное может быть отображено в гистограмме JavaFX:

При обнаружении изменений в базовом XML-файле диаграмма автоматически обновляется, чтобы отразить это изменение.

Вопрос в том, как создать вышеуказанное приложение. Источники выше (минус jfxrt.jar, который я должен был исключить из регистрации, потому что он был слишком большим) находится здесь:

https://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.3/misc/MySimpleGraphProcessor

Вот шаги, чтобы добраться до вышеупомянутого пункта:

  1. Создай Основу. Создайте новое приложение на платформе NetBeans и добавьте несколько дополнительных модулей (на вкладке «Библиотеки» приложения в диалоговом окне «Свойства проекта»), в частности, из кластера «ide», модулей «User Utilities» и «XML Text Editor» вместе с их необходимые зависимости, а также модуль «Избранное» из кластера «платформа».
  2. Распознать тип файла. Создайте модуль в своем приложении. Используйте Учебное пособие   по типам файлов NetBeans, чтобы сгенерировать код, необходимый для распознавания вашего XML-файла по его пространству имен или корневому имени (в этом случае, как видно из XML-файла в верхней части этой статьи, корневое имя — «graph»). Включите элемент MultiView, с помощью флажка в мастере, где будет отображаться диаграмма JavaFX.
  3. Включите JavaFX Runtime. Создайте модуль-оболочку библиотеки NetBeans, включающий «jfxrt.jar», и установите зависимость от него в модуле, описанном выше.
  4. Добавьте код к элементу MultiView. Все, что вам нужно сделать, это сделать в элементе MultiView. Здесь вам нужно проанализировать файл XML и визуализировать график JavaFX. Ниже приведен весь соответствующий код, за исключением операторов импорта и аннотаций в верхней части класса и стандартного сгенерированного кода в конце.
    public final class MySimpleGraphVisualElement extends JPanel implements MultiViewElement {
    
        private MySimpleGraphDataObject obj;
        private transient MultiViewElementCallback callback;
        private List<String> names;
        private List<String> values;
        private String caption = "";
        private FileObject fo;
    
        public MySimpleGraphVisualElement(Lookup lkp) {
            obj = lkp.lookup(MySimpleGraphDataObject.class);
            assert obj != null;
            initComponents();
            setLayout(new BorderLayout());
            parseFile();
            initJavaFX();
        }
    
        public void initJavaFX() {
            final JFXPanel chartFxPanel = new JFXPanel();
            add(chartFxPanel, BorderLayout.CENTER);
            Platform.setImplicitExit(false);
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    Scene scene = new Scene(createBarChart());
                    chartFxPanel.setScene(scene);
                }
            });
        }
    
        private void parseFile() {
            fo = obj.getPrimaryFile();
            names = new ArrayList();
            values = new ArrayList();
            InputSource source;
            try {
                source = new InputSource(fo.getInputStream());
                Document doc = XMLUtil.parse(source, false, false, null, null);
                NodeList graphNodeList = doc.getElementsByTagName("graph");
                NamedNodeMap graphNodeMap = graphNodeList.item(0).getAttributes();
                for (int j = 0; j < graphNodeMap.getLength(); j++) {
                    Node attrNode = graphNodeMap.item(j);
                    String attrName = attrNode.getNodeName();
                    if (attrName.equals("caption")) {
                        caption = attrNode.getNodeValue();
                    }
                }
                NodeList setNodeList = doc.getElementsByTagName("set");
                for (int i = 0; i < setNodeList.getLength(); i++) {
                    Node setNode = setNodeList.item(i);
                    NamedNodeMap map = setNode.getAttributes();
                    for (int j = 0; j < map.getLength(); j++) {
                        Node attrNode = map.item(j);
                        String attrName = attrNode.getNodeName();
                        if (attrName.equals("name")) {
                            names.add(attrNode.getNodeValue());
                        } else if (attrName.equals("value")) {
                            values.add(attrNode.getNodeValue());
                        }
                    }
                }
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            } catch (SAXException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
    
        private BarChart createBarChart() {
            final ObservableList<BarChart.Series> bcData = 
                    FXCollections.<BarChart.Series>observableArrayList();
            for (int column = 0; column < names.size(); column++) {
                ObservableList<BarChart.Data> series = 
                        FXCollections.<BarChart.Data>observableArrayList();
                series.add(
                        new BarChart.Data(names.get(column), 
                        Integer.parseInt(values.get(column))));
                bcData.add(new BarChart.Series(series));
            }
            CategoryAxis xAxis = new CategoryAxis();
            xAxis.setCategories(FXCollections.observableArrayList(names));
            NumberAxis yAxis = new NumberAxis();
            yAxis.setTickUnit(10000);
            final BarChart chart = new BarChart(xAxis, yAxis, bcData);
            chart.setTitle(caption);
            fo.addFileChangeListener(new FileChangeAdapter() {
                @Override
                public void fileChanged(FileEvent fe) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            parseFile();
                            for (int column = 0; column < values.size(); column++) {
                                XYChart.Series<String, Number> s = 
                                        (XYChart.Series<String, Number>) chart.getData().get(column);
                                BarChart.Data data = s.getData().get(0);
                                data.setYValue(Integer.parseInt(values.get(column)));
                            }
                        }
                    });
                }
            });
            return chart;
        }
        
        ...
        ...
        ...

Выше буквально весь код, который вам нужно добавить самостоятельно. Все остальное является частью платформы NetBeans или создается мастерами в IDE NetBeans. Например, вы автоматически можете открывать несколько графиков и сравнивать их по-разному, например:

Конечно, диаграммы могут быть отстыкованы от основного кадра и перемещены, например, на разные мониторы. Это все довольно круто.