Как сохранить таблицу JTable в XML

Как сохранить таблицу JTable в XML Заметил, что в панели администрирования моего wordpress в секции «Ключевые слова — По этим словам люди нашли ваш блог» на первом месте последнее время запрос «java jtable to xml». Собственно об этом и будет всё ниже написанное. Возьму обычный JTable с какими-нибудь данными и при помощи Java DOM сохраню всё содержимое таблицы в xml. Первое, что необходимо сделать — это получить данные из таблицы. Кстати таблица редактируемая, поэтому данные в ячейках можно изменять и при очередном сохранении они будут обновляться в XML файле. Так как же получить данные с таблицы? Делаетcя это через TableModel — модель таблицы, в которой находятся все данные отображаемые в JTable в данный момент. Получить модель у таблицы можно при помощи метода getModel. Затем при помощи метода getValueAt(row, col) TableModel можно получить значение из конкретной ячейки таблицы, где row — индекс строки, а col — индекс колонки.

String[] columnNames = { "Name", "Modified", "Type", "Size" };
String[][] data = { { "addins", "02.11.2006 19:15", "Folder", "" },
		{ "AppPatch", "03.10.2006 14:10", "Folder", "" },
		{ "assembly", "02.11.2006 14:20", "Folder", "" },
		{ "Boot", "13.10.2007 10:46", "Folder", "" },
		{ "Branding", "13.10.2007 12:10", "Folder", "" },
		{ "Cursors", "23.09.2006 16:34", "Folder", "" },
		{ "Debug", "07.12.2006 17:45", "Folder", "" },
		{ "Fonts", "03.10.2006 14:08", "Folder", "" },
		{ "Help", "08.11.2006 18:23", "Folder", "" },
		{ "explorer.exe", "18.10.2006 14:13", "File", "2,93MB" },
		{ "helppane.exe", "22.08.2006 11:39", "File", "4,58MB" },
		{ "twunk.exe", "19.08.2007 10:37", "File", "1,08MB" },
		{ "nsreg.exe", "07.08.2007 11:14", "File", "2,10MB" },
         	{ "avisp.exe", "17.12.2007 16:58", "File", "12,67MB" }, };

final JTable table = new JTable(data, columnNames);
TableModel model = table.getModel();
int row = 1;
int col = 2;
String value = model.getValueAt(row, col).toString();

Кроме данных из ячеек таблицы мне понадобятся заголовки столбцов. Конечно заголовки столбцов известны заранее, но есть способ получить их из самой таблицы. Для это получаем ссылку на TableColumnModel при помощи метода getColumnModel. Теперь можно узнать количество столбцов и пробежавшись по всем столбцам получить заголовок каждого из них вот так.

TableModel model = table.getModel();
TableColumnModel columns = table.getColumnModel();

for (int i = 0; i < model.getRowCount(); i++) {
      for (int j = 0; j < columns.getColumnCount(); j++) {
             TableColumn col = columns.getColumn(j);
             String header = col.getHeaderValue().toString();
      }
}

Все необходимые данные получены. Теперь необходимо при помощи DOM создать в памяти объектное представление нашего будущего документа. Для начала создаем Document.

DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = f.newDocumentBuilder();
Document doc = builder.newDocument();

Далее с помощью DOM методов добавляем необходимые узлы и их атрибуты к документу. Затем при помощи следующей конструкции мы сохраняем получившийся документ в файл.

TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);

А теперь посмотрим на весь исходный код тестового примера, который выглядит вот так.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class TestFrame extends JFrame {

	public static void createGUI() {
		JFrame frame = new JFrame("Test frame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		String[] columnNames = { "Name", "Modified", "Type", "Size" };

		String[][] data = { { "addins", "02.11.2006 19:15", "Folder", "" },
				{ "AppPatch", "03.10.2006 14:10", "Folder", "" },
				{ "assembly", "02.11.2006 14:20", "Folder", "" },
				{ "Boot", "13.10.2007 10:46", "Folder", "" },
				{ "Branding", "13.10.2007 12:10", "Folder", "" },
				{ "Cursors", "23.09.2006 16:34", "Folder", "" },
				{ "Debug", "07.12.2006 17:45", "Folder", "" },
				{ "Fonts", "03.10.2006 14:08", "Folder", "" },
				{ "Help", "08.11.2006 18:23", "Folder", "" },
				{ "explorer.exe", "18.10.2006 14:13", "File", "2,93MB" },
				{ "helppane.exe", "22.08.2006 11:39", "File", "4,58MB" },
				{ "twunk.exe", "19.08.2007 10:37", "File", "1,08MB" },
				{ "nsreg.exe", "07.08.2007 11:14", "File", "2,10MB" },
				{ "avisp.exe", "17.12.2007 16:58", "File", "12,67MB" }, };

		final JTable table = new JTable(data, columnNames);
		JScrollPane scrollPane = new JScrollPane(table);

		JButton button = new JButton("Save to xml");

		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					DocumentBuilderFactory f = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder builder = f.newDocumentBuilder();
					File file = new File("table.xml");

					if (!file.exists()) {
						file.createNewFile();
					}

					Document doc = builder.newDocument();
					Element tableEl = doc.createElement("table");
					doc.appendChild(tableEl);

					TableModel model = table.getModel();
					TableColumnModel columns = table.getColumnModel();

					for (int i = 0; i < model.getRowCount(); i++) {
						Element rowEl = doc.createElement("row");
						tableEl.appendChild(rowEl);

						for (int j = 0; j < columns.getColumnCount(); j++) {
							TableColumn col = columns.getColumn(j);
							String header = col.getHeaderValue().toString();
							String value = model.getValueAt(i, j).toString();
							Element cellEl = doc.createElement("cell");
							Attr colAttr = doc.createAttribute("colName");
							cellEl.setAttributeNode(colAttr);
							rowEl.appendChild(cellEl);
							colAttr.appendChild(doc.createTextNode(header));
							cellEl.appendChild(doc.createTextNode(value));
						}
					}

					TransformerFactory tFactory = TransformerFactory
							.newInstance();
					Transformer transformer = tFactory.newTransformer();
					DOMSource source = new DOMSource(doc);
					StreamResult result = new StreamResult(file);
					transformer.transform(source, result);
				} catch (Exception exception) {
					exception.printStackTrace();
				}
			}
		});

		frame.getContentPane().add(button, BorderLayout.SOUTH);

		frame.getContentPane().add(scrollPane);
		frame.setPreferredSize(new Dimension(450, 200));
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				JFrame.setDefaultLookAndFeelDecorated(true);
				createGUI();
			}
		});
	}
}
Реклама

7 Responses to Как сохранить таблицу JTable в XML

  1. chevalry says:

    Хочется написать пару слов благодарности. У Вас отличные примеры — и все работает без запинки. Очень помогают оба Ваших поста по Java/XML (как открыть данные из XML-файла и как сохранить данные JTable в XML), и кроме того помог пост про абсолютное позиционирование компонентов. Я всего лишь только начинаю программировать на Java и у меня с абсолютным позиционированием вышла какая-то затыка. Вот в тот момент я и нашел Ваш блог — сразу подписался и даже сделал на своем блоге на Вас ссылку с рекомендацией

    Надеюсь, Вы будете продолжать тему 🙂

  2. chevalry says:

    С позволения автора, оставлю здесь эту ссылку:
    Convert a flat file to XML (DOM)
    Это хорошее дополнение к данному примеру. Дело в том, что в данном примере результат вывода данных в XML-файл выглядит не очень удобным для просмотра. Мне подумалось: «а нельзя ли сделать так, чтобы элементы и теги были разбиты по разным строкам, а дочерние элементы имели отступ от родительского элемента вправо на нужное мне расстояние».
    Как я выяснил — можно. Во-первых, для разбивки элемпентов по строкам в текст программы (там, где появляется transformer) нужно добавить команду:
    transformer.setOutputProperty(OutputKeys.INDENT, «yes»);
    А для того, чтобы вообще все было красиво — рядом следует добавить еще и эту команду:
    transformer.setOutputProperty(«{http://xml.apache.org/xslt}indent-amount», «4»);
    Результатом я остался очень доволен 🙂

  3. Fruzenshtein says:

    Очень здорово получилась статья!
    В инэте мало статей про JAVA + XML / JSON

    Кстати про последний можно было бы тоже статейку написать=)

  4. с начальным уровнем с трудом понимаю код… информация очень полезна.. буду разбираться)

  5. Anton says:

    Добавь тег xml

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: