Готовые отчеты (2020) / Java. Лабораторная работа 8
.pdfФедеральное агентство связи ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М. А. БОНЧ-БРУЕВИЧА» (СПбГУТ)
Факультет инфокоммуникационных сетей и систем Кафедра программной инженерии и вычислительной техники
ЛАБОРАТОРНАЯ РАБОТА №8
по дисциплине «Разработка Java-приложений управления телекоммуникациями»
Выполнил: студент 3-го курса дневного отделения группы ИКПИ-85
Коваленко Леонид Александрович Преподаватель:
доцент кафедры ПИиВТ Белая Татьяна Иоанновна
Санкт-Петербург
2020
Цель работы Ознакомиться с базовыми принципами создания апплетов, технологией
Swing и обработкой событий.
Ход работы
Создадим апплет «Калькулятор векторов» при помощи Swing (примечание: поддержка апплетов исключена из Java, начиная с версии 11).
На форме будут присутствовать три поля ввода с подписями (первое для указания размера вектора для его создания, второе для указания индекса вектора в качестве первого операнда, третье для указания индекса вектора в качестве второго операнда), список векторов с индексами, кнопка для вычисления скалярного произведения, кнопка для вычисления суммы векторов, кнопка для открытия файла для добавления данных в программу, кнопка сохранения данных в файл из программы.
В случае некорректных запросов со стороны пользователя будут выводиться окна с сообщениями об ошибках.
Длина векторов будет ограничена только естественными ограничениями (допустимые значения типа int) и операционной системой.
Код приведен в табл. 1. Таблица 1 — Код Task8.java
// <applet code="Task8" width=470 height=390></applet> import vectors.Array;
import vectors.IVector; import vectors.Vectors;
import javax.swing.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader;
import java.io.FileWriter; import java.util.ArrayList;
public class Task8 extends JApplet { // Spinner. Целые числа
JSpinner vectorSizeEdit = new JSpinner(new SpinnerNumberModel(5, 1, Integer.MAX_VALUE, 1)),
firstVectorIndexEdit = new JSpinner(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1)),
secondVectorIndexEdit = new JSpinner(new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1));
// Кнопки
JButton createButton = new JButton("Добавить вектор"),
2
clearButton = new JButton("Удалить все векторы"), scalarMulButton = new JButton("Скалярное произведение"), sumButton = new JButton("Сумма векторов"),
openButton = new JButton("Открыть..."), saveButton = new JButton("Сохранить...");
//Массив объектов JTextField (текстовых полей ввода векторов) ArrayList<JTextField> vectorArrayList = new ArrayList<JTextField>();
//Панель mainPanel содержит панели topPanel и centerPane(centerPanel) JPanel mainPanel = new JPanel(),
topPanel = new JPanel(new GridLayout(0, 2, 5, 5)), centerPanel = new JPanel(new GridLayout(0, 1));
//Прокручиваемая область
JScrollPane centerPane = new JScrollPane(centerPanel);
// Метод инициализации public void init() {
// Отображение значений внутри Spinner по центру ((JSpinner.DefaultEditor)
vectorSizeEdit.getEditor()).getTextField().setHorizontalAlignment(JTextField. CENTER);
((JSpinner.DefaultEditor) firstVectorIndexEdit.getEditor()).getTextField().setHorizontalAlignment(JText Field.CENTER);
((JSpinner.DefaultEditor) secondVectorIndexEdit.getEditor()).getTextField().setHorizontalAlignment(JTex tField.CENTER);
// Настройка верхней панели topPanel.add(new JLabel("Размер вектора:")); topPanel.add(vectorSizeEdit);
topPanel.add(new JLabel("Индекс первого вектора:")); topPanel.add(firstVectorIndexEdit); topPanel.add(new JLabel("Индекс второго вектора:")); topPanel.add(secondVectorIndexEdit); topPanel.add(createButton); topPanel.add(clearButton); topPanel.add(scalarMulButton); topPanel.add(sumButton);
topPanel.add(openButton);
topPanel.add(saveButton);
// Настройка центральной панели centerPane.setPreferredSize(new Dimension(442, 200));
centerPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDE D);
//Настройка главной панели mainPanel.add(topPanel, BorderLayout.NORTH); mainPanel.add(centerPane, BorderLayout.CENTER); getContentPane().add(mainPanel);
//Настройка каркаса
Frame mainFrame = (Frame) this.getParent().getParent(); mainFrame.setTitle("Калькулятор векторов"); // Заголовок mainFrame.setResizable(false); // Запрет изменения размеров mainFrame.setLocationRelativeTo(null); // По центру
// Настройка обработчика нажатия на кнопку создания вектора createButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) { int len;
try { len =
Integer.parseInt(vectorSizeEdit.getValue().toString()); } catch (Exception e) {
JOptionPane.showMessageDialog(null, "Размер введен неверно", "Ошибка", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
3
return;
}
StringBuilder valueString = new StringBuilder(2 * len); valueString.append('0');
for (int i = 1; i < len; ++i) { valueString.append(" 0");
}
addVector(valueString.toString());
}
});
//Настройка обработчика нажатия на кнопку очистки панели с векторами clearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) { clearVectorPanel();
}
});
//Настройка обработчика нажатия на кнопку для выполнения скалярного
умножения
scalarMulButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent actionEvent) {
try {
Array[] arrays = getTwoVectors();
if (arrays[0] == null || arrays[1] == null) { return;
}
double result = Vectors.mul(arrays[0], arrays[1]); JOptionPane.showMessageDialog(null, "Результат скалярного
произведения двух векторов: " + result, "Результат", JOptionPane.PLAIN_MESSAGE);
} catch (Exception e) { JOptionPane.showMessageDialog(null, "Ошибка при
вычислении скалярного произведения двух векторов", "Ошибка", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
}); // Настройка обработчика нажатия на кнопку для выполнения суммы двух
векторов
sumButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent actionEvent) { try {
Array[] arrays = getTwoVectors();
if (arrays[0] == null || arrays[1] == null) { return;
}
IVector result = Vectors.sum(arrays[0], arrays[1]); JOptionPane.showMessageDialog(null, "Результат сложения
двух векторов:\n" + result.toString(), "Результат", JOptionPane.PLAIN_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Ошибка при сложении двух векторов", "Ошибка", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
}); // Настройка обработчика нажатия на кнопку для открытия файла с
векторами
openButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent actionEvent) {
4
try {
JFileChooser openFile = new JFileChooser(); if (openFile.showOpenDialog(null) ==
JFileChooser.APPROVE_OPTION) {
if (!openFile.getSelectedFile().exists()) { JOptionPane.showMessageDialog(null, "Такого файла
не существует", "Ошибка", JOptionPane.ERROR_MESSAGE); return;
}
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(openFile.getSelectedFile()))) {
if (vectorArrayList.size() > 0 && JOptionPane.showConfirmDialog(null, "Предварительно очистить список векторов?", "Вопрос", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
clearVectorPanel();
}
for (String line; (line = bufferedReader.readLine()) != null; ) {
String[] elements = line.split("[,;\\s]+"); Array vector = new Array(elements.length); for (int i = 0; i < elements.length; ++i) {
vector.set(i,
Double.parseDouble(elements[i]));
}
addVector(vector.toString());
}
} catch (Exception e) { JOptionPane.showMessageDialog(null, "Ошибка
чтения данных из файла", "Ошибка", JOptionPane.ERROR_MESSAGE); e.printStackTrace();
}
}
} catch (Exception e) { JOptionPane.showMessageDialog(null, "HeadlessException.
Ошибка совместимости периферии", "Ошибка", JOptionPane.ERROR_MESSAGE); e.printStackTrace();
}
}
}); // Настройка обработчика нажатия на кнопку для сохранения файла с
векторами
saveButton.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent actionEvent) { try {
JFileChooser saveFile = new JFileChooser(); if (saveFile.showSaveDialog(null) ==
JFileChooser.APPROVE_OPTION) {
if (saveFile.getSelectedFile().exists() && JOptionPane.showConfirmDialog(null, "Перезаписать файл?", "Вопрос", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
return;
}
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(saveFile.getSelectedFile()))) {
for (JTextField textField : vectorArrayList) { bufferedWriter.write(textField.getText() + "\
n");
}
} catch (Exception e) { JOptionPane.showMessageDialog(null, "Ошибка
записи данных в файл", "Ошибка", JOptionPane.ERROR_MESSAGE); e.printStackTrace();
}
}
5
} catch (Exception e) { JOptionPane.showMessageDialog(null, "HeadlessException.
Ошибка совместимости периферии", "Ошибка", JOptionPane.ERROR_MESSAGE); e.printStackTrace();
}
}
});
}
// Метод добавления вектора
private void addVector(String string) { try {
JTextField jTextField = new JTextField(string, 35); JPanel jPanel = new JPanel();
jPanel.add(new JLabel(String.valueOf(vectorArrayList.size())), BorderLayout.WEST);
jPanel.add(jTextField);
centerPanel.add(jPanel);
vectorArrayList.add(jTextField); } catch (Exception e) {
JOptionPane.showMessageDialog(null, "Ошибка создания вектора", "Ошибка", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
clearVectorPanel();
}
mainPanel.validate();
mainPanel.repaint();
}
//Метод очистки панели с векторами private void clearVectorPanel() {
centerPanel.removeAll();
vectorArrayList.clear();
mainPanel.validate();
mainPanel.repaint();
}
//Метод получения двух векторов по указанным в Editor's индексам private Array[] getTwoVectors() {
int arrayListLen = vectorArrayList.size(), firstIndex, secondIndex;
try { firstIndex =
Integer.parseInt(firstVectorIndexEdit.getValue().toString()); secondIndex =
Integer.parseInt(secondVectorIndexEdit.getValue().toString()); } catch (Exception e) {
JOptionPane.showMessageDialog(null, "Первый и/или второй индекс указан(ы) неверно", "Ошибка", JOptionPane.ERROR_MESSAGE);
return new Array[]{null, null};
}
if (!(0 <= firstIndex && firstIndex < arrayListLen)) { JOptionPane.showMessageDialog(null, "Индекс первого вектора
выходит за пределы", "Ошибка", JOptionPane.ERROR_MESSAGE); return new Array[]{null, null};
}
if (!(0 <= secondIndex && secondIndex < arrayListLen)) { JOptionPane.showMessageDialog(null, "Индекс второго вектора
выходит за пределы", "Ошибка", JOptionPane.ERROR_MESSAGE); return new Array[]{null, null};
}
String[] firstVectorStringArray = vectorArrayList.get(firstIndex).getText().split("[,;\\s]+");
String[] secondVectorStringArray = vectorArrayList.get(secondIndex).getText().split("[,;\\s]+");
int vectorSize = firstVectorStringArray.length, vectorSize2 =
6
secondVectorStringArray.length; if (vectorSize == 0) {
JOptionPane.showMessageDialog(null, "Нулевой размер у первого вектора", "Ошибка", JOptionPane.ERROR_MESSAGE);
return new Array[]{null, null};
}
if (vectorSize2 == 0) {
JOptionPane.showMessageDialog(null, "Нулевой размер у второго вектора", "Ошибка", JOptionPane.ERROR_MESSAGE);
return new Array[]{null, null};
}
if (vectorSize != vectorSize2) {
JOptionPane.showMessageDialog(null, "Векторы неравны по размеру", "Ошибка", JOptionPane.ERROR_MESSAGE);
return new Array[]{null, null};
}
try {
Array firstArray = new Array(vectorSize), secondArray = new Array(vectorSize);
for (int i = 0; i < vectorSize; ++i) { firstArray.set(i,
Double.parseDouble(firstVectorStringArray[i]));
secondArray.set(i,
Double.parseDouble(secondVectorStringArray[i]));
}
return new Array[]{firstArray, secondArray};
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Ошибка работы с векторами", "Ошибка", JOptionPane.ERROR_MESSAGE);
return new Array[]{null, null};
}
}
}
Результат компиляции и запуска представлен на рис. 1.
Рисунок 1 — Результат компиляции и запуска Task8.java
Векторы добавляются при помощи кнопки «Добавить вектор» и могут
быть отредактированы в процессе работы без затруднений (рис. 2-4). 7
Рисунок 2 — Результат добавления шести векторов
Рисунок 3 — Результат добавления ещё трех векторов
Рисунок 4 — Семь примеров корректных векторов 8
На рис. 4 были приведены примеры корректных с точки зрения программы векторов. В качестве разделителя чисел могут использоваться либо пробелы, либо точки с запятыми, либо запятые, либо любые их сочетания и перестановки. Точка используется в качестве десятичного разделителя (целая и дробная части).
Все векторы можно удалить при помощи кнопки «Удалить все векторы» (рис. 5).
Рисунок 5 — Результат удаления всех векторов Поле ввода размера вектора на самом деле сделано для удобства — оно
влияет на число генерируемых элементов-нулей создаваемого вектора (т. е. если указано 5, то вектор в программе по умолчанию будет значиться как «0 0 0 0 0»).
Теперь рассмотрим функцию скалярного произведения, предварительно добавив несколько векторов (рис. 6). В полях-индексах записываются индексы векторов-операндов. В нашем случае — это 1 и 2. Нетрудно посчитать, что 3×1.5 + 2×2 + 1.5×3 = 4.5 + 4 + 4.5 = 13.
9
Рисунок 6 — Результат скалярного произведения второго (1) и третьего (2) векторов
Теперь рассмотрим функцию суммы векторов (рис. 7). Индексы векторов те же. Нетрудно посчитать, что 3 + 1.5 = 4.5, 2 + 2 = 4, 1.5 + 3 = 4.5.
Рисунок 7 — Результат суммы второго (1) и третьего (2) векторов Если векторы отличаются по размеру, то возникает ошибка (рис. 8).
Рисунок 8 — Ошибка неравенства размеров двух векторов Если индекс одного из векторов выходит за пределы, то возникает
ошибка (рис. 9, 10).
10