Давно хотел написать программу? которая поможет отвлечься от компьютера на пару минут. Основная её задача - сообщить пользователю о том, что необходимо отвлечься от компьютера и отдохнуть.
Требования к проекту:
- Программу можно закрывать только в рабочий период;
- Программа не должна сворачиваться в период отдыха.
Далее я опишу проблемы возникшие при работе над проектом. Проект разрабатывается на Java, место его расположения здесь, используемое IDE - Eclipse.
Поехали.
Работа с циклом for, for-each
В процессе работы часто бывает нужно последовательно перебрать все элементы массива.Существует простая возможность прямого перебора всех элементов массива или коллекции. Это перебор "for-each", конструкция цикла не меняется для коллекций и массивов.
for (type var : arr) { body-of-loop }
где:
type - тип возвращаемой переменной var
arr - массив или коллекция которую перебирают
Рабочий пример:
int[] J = {1,2,3,4}; for (int i : J){ System.out.println(i); }
Стандартный перебор массива циклом for будет такой:
for (int i = 0; i < arr.length; i++) { type var = arr[i]; body-of-loop }А для коллекции это выглядело бы вот так:
for (Iteratoriter = coll.iterator(); iter.hasNext(); ) { type var = iter.next(); body-of-loop }
Диалоговое окно
Здесь вроде проблем нет, но лично я всё время забываю, как это делать. Думаю, будет полезно записать лишний раз.Итак простая команда:
JOptionPane.showMessageDialog(frame, "Сообщение");
где:
frame - это форма от которой построено диалоговое окно
"Сообщение" - это сообщение окна.
На всякий случай стоит сказать, что для использования JOptionPane необходимо импортировать javax.swing.JOptionPane, а то вдруг IDE не подскажет.
Остановка выполнения потока. Команда "sleep"
Иногда бывает необходимо остановить выполнение программы на определённый период. Делается это очень просто, главное запомнить в каком классе описан метод "sleep"try { Thread.sleep(10000); // ждать 10 секунд } catch (InterruptedException e) { e.printStackTrace(); }где:
10000 - количество миллисекунд.
e.printStackTrace(); - выведет в консоль приложения стек ошибки.
Внешний вид JFrame, развёртывание окна на весь экран, отключение пиктограмм работы с окном.
Уж не знаю насколько корректно назван данный раздел, задача заключается в том, что нужно отключить кнопки сворачивания и разворачивания окна, а так же возможность его закрыть нажав "х".Над решением данной проблемы пришлось повозиться.
Для того, что бы построить форму максимального размера (раскрыть на весь экран) обычно советуют следующее:
JFrame fr = new JFrame(); // создание окна fr.setVisible(true); // показать окно fr.setExtendedState(fr.getExtendedState() | fr.MAXIMIZED_BOTH); // сделать окно максимальных размеров fr.setAlwaysOnTop(true); // оставить окно поверх всех оконВсё вроде просто и понятно. Но у меня не работало. Возможно были проблемы с операционкой, но окно не разворачивалось на весь экран.
Так что пришлось пойти другим путём:
JFrame fr = new JFrame(); // создание окна fr.setAlwaysOnTop(true); // оставляем всегда на верху fr.setSize(Toolkit.getDefaultToolkit().getScreenSize()); // получаем разрешение экрана и устанавливаем максимальный размеры для окна fr.setVisible(true); // показываем окноРезультат выполнения этого кода меня устраивает гораздо больше.
Для отключения кнопок окна и запрета его закрытия можно дописать следующие строчки:
fr.setDefaultCloseOperation(fr.DO_NOTHING_ON_CLOSE); // отключает возможность закрыть окно при нажатии "х" fr.setUndecorated(true); // убираем заголовок окна и 3 кнопки работы с окном
Воспроизведение звукового .wav файла.
Механизм воспроизведения звукового файла оказался проще, чем показалось на первый взгляд.Обычно, в случаях когда нужно подать звуковой сигнал, я использовал BEEP, но с удивлением узнал, что домашний ноутбук, такой радостью не обладает. Так-что пришлось осваивать:
private void PlaySound() throws UnsupportedAudioFileException, IOException, LineUnavailableException { // процедура проигрывающая один заранее заданный файл AudioInputStream stream = AudioSystem.getAudioInputStream(new File("womp.wav")); // создаём аудио поток из файла DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat()); // получаем информацию о звуке из потока Clip clip = (Clip) AudioSystem.getLine(info); // инициализируем проигрыватель clip.open(stream); // воспроизводим файл clip.start(); // закрываем проигрыватель }где:
"womp.wav" - звуковой файл находящийся в одном каталоге с исполняемым файлом
для работы со звуком необходим пакет javax.sound.sampled.*
Работа с XML.
Работа с XML документами является очень большой и сложной темой. Но я не могу пройти мимо и хочу оставить маленький пример, так сказать на будущее.Чтение XML файла простого формата
Пример обрабатывает простой файл следующего формата:<Head>
<tag1>value</tag1>
...
<tagN>value</tagN>
</Head>
В примере ниже идёт обращение по именам тегов:
try { Document sets = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(path); // загружаем заданный файл Element EyeSets = sets.getDocumentElement(); // получаем элементы документа // получаем значение по именам String sWaitPeriod = EyeSets.getElementsByTagName("tag1").item(0).getFirstChild().getNodeValue(); String sPracticePeriod = EyeSets.getElementsByTagName("tag2").item(0).getFirstChild().getNodeValue(); String sPracticeCount = EyeSets.getElementsByTagName("tag3").item(0).getFirstChild().getNodeValue(); // преобразование полученных данных в требуемый формат try { waitPeriod = Integer.parseInt(sWaitPeriod); practicePeriod = Integer.parseInt(sPracticePeriod); practiceCount = Integer.parseInt(sPracticeCount); } catch (NumberFormatException nfe) { JOptionPane.showMessageDialog(null, nfe.getMessage()); System.err.println(nfe.getMessage()); } } catch (Exception e){ System.err.println(e.getMessage()); }где:
Загрузка XML файла простого формата
Сохранённый выше файл можно загрузить с помощью примера ниже:// задаём экземпляр потока выходного файла FileOutputStream fo = null; try { // создаём экземпляр с заданным именем файла fo = new FileOutputStream(path); } catch (FileNotFoundException e1) { e1.printStackTrace(); } // создание экземпляра класса? генерирующего xml файл в указанный выходной поток XMLStreamWriter writer; try { writer = XMLOutputFactory.newInstance().createXMLStreamWriter(fo); try { // начало создания файла writer.writeStartDocument(); // основной тег writer.writeStartElement("setings"); // открытие узла writer.writeStartElement("tag1"); //запись значения узла writer.writeCharacters(Integer.toString(waitPeriod)); // закрытие узла writer.writeEndElement(); writer.writeStartElement("tag2"); writer.writeCharacters(Integer.toString(practicePeriod)); writer.writeEndElement(); writer.writeStartElement("tag3"); writer.writeCharacters(Integer.toString(practiceCount)); writer.writeEndElement(); // закрываем все открытые узлы writer.writeEndDocument(); } finally { // закрываем класс writer.close(); } } catch (XMLStreamException e) { e.printStackTrace(); }где:
path - путь где будет сохранён файл
Стоит отметить что существует 2 технологии работы с XML:
- SAX (Simple API for XML);
- DOM (Document Object Model).
В примерах выше вся работа велась через DOM объекты
Сериализация объектов в бинарный файл
Выше был приведён пример сохранения требуемых данных в XML файл. Но это не единственный способ сохранения состояний объектов. Существует возможность сериализации объекта в файл - для последующей его передачи куда либо или сохранения его текущих состояний.Необходимо помнить? что сериализуемые объекты должны наследовать интерфейс java.io.Serializable.
Функция для сохранения объекта очень проста:
public void writeSets(Vector<eyesset> ser) throws Exception{ System.out.println("write objects:"); FileOutputStream fos=new FileOutputStream("output.bin"); ObjectOutputStream oos=new ObjectOutputStream(fos); oos.writeObject(ser); oos.close(); }где:
Vector<eyesset> - коллекция объектов для сериализации.(может быть любым другим объектом реализующим интерфейс Serializable)
Для десериализации объекта можно использовать следующий пример:
/** * Функция загружает настройки из сериализованного файла * Изменяет список всех упражнений в текущем классе * * @return список всех упражнений * @throws Exception FileNotFoundException - ошибка отсутствия загружаемого файла * EOFException - ошибка обработки потока (поток достиг своего конца) * */ public Vector<eyesset> readSets() throws Exception { // загружаем все упражнения из сохранённого файла File f = new File("output.bin"); if (f.exists()) { System.out.println("Read objects:"); FileInputStream fis=new FileInputStream("output.bin"); ObjectInputStream ois=new ObjectInputStream(fis); Vector<eyesset> readObject = (Vector<eyesset>)ois.readObject(); ois.close(); return readObject; } else {return new Vector();}
Выше, перед функцией, можно увидеть пример документирования кода ( JavaDoc). О том как писать JavaDoc можно почитать вот здес здесь
Переопределение отображения JList.
Довольно часто в списках JList требуется отображать только определённые данные из объекта. У программиста есть 2 варианта:- или создавать массив строк с готовыми данными для отображения, что на мой взгляд является не корректно;
- или переопределить отрисовку данных.
jlSet.setCellRenderer(new javax.swing.DefaultListCellRenderer(){ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Property prop = (Property)value; setText(prop.getDisplayCoordinat()); return this; } });Почитать первоисточник можно вот здесь
Ну вот кажется и всё.
Ждём продолжения, поскольку проект ещё не закончен и впереди показались проблемы, которые требуют своего решения.
Надеюсь на комментарии.
Продолжение часть 2
Спасибо, пригодилось
ОтветитьУдалить