2. WEB — графика с Three.js. Рисование линий

👁 0 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Линия — это один из примитивов в Three.js, наверное как и в любой графической библиотеке, на основе которой можно построить составные объекты. После предыдущей статьи нам будет легче ориентироваться в методологии рисовании на Three.js. Рисовать линию действительно просто, надо только знать базовые основы математики такие как декартовы координаты и векторы. Давайте возьмем код из первой статьи, а именно файл script.js, остальное будет прежним,  и перепишем так, чтобы Three.js нам вывел обычную линию

window.onload = init;
function init(){
	//--------------Создаем в дереве DOM элемент для вывода на экран-------
	container = document.createElement("div");
	document.body.appendChild(container);
	
	//--------------Общие переменные--------------
	var scene, camera, render;
	
	//--------------Инициализация общих переменных---------
	scene = new THREE.Scene();//Сцена
	camera = new THREE.PerspectiveCamera(65, window.innerWidth/window.innerHeight, 0.1, 2000);//Перспективная проекция камеры. Принимает 3 параметра(масштаб, пропорция, точка 0 вблизи, точка 0 в дали
    camera.position.x = 150;//Позиция камеры по x
	camera.position.z = 600;//Позиция камеры по y
	render = new THREE.WebGLRenderer();//Рендеринг
	render.setSize(window.innerWidth, window.innerHeight);//Инициализация рендерера
	
	//--------------Создаем объект-------------------
	var lineGeometry = new THREE.Geometry();//Производная фигура
	lineGeometry.vertices.push(new THREE.Vector3(0, 0, 0));//Указываем вектор первой точки
	lineGeometry.vertices.push(new THREE.Vector3(0, 200, 0));//Указываем вектор второй точки
	var lineMaterial = new THREE.LineBasicMaterial({color:0xFFFFFF, linewidth:500});
	var line = new THREE.Line(lineGeometry, lineMaterial);//Создаем линию из созданной геометрии
	
	//--------------Добавление вывод-----------------
	scene.add(line);//Добавляем объект на сцену
	render.render(scene, camera);//Добавляем сцену и камеру в рендер
	container.appendChild(render.domElement);//Добавляем рендер в DOM для вывода на экран
}

Как видим все просто. Как видим из примера в Three.js существует понятие вектор и специальный объект для этого и при создании объекта будущей фигуры мы должны, передав вектору значения по координатным осям, передать нашему объекту в виде параметра метода вершин vertices() и он послужит для нас точкой, для определения второй точки поступаем тем же образом, а для того, чтобы указать Three.js, что мы хотим вывести именно линии, а не чисто 2 точки, то существует для этого специальный объект

THREE.Line(lineGeometry, lineMaterial)

который помимо объекта линии принимает еще и значение материала. Материал, в данном случае, принимает значения цвета и ширины линии. Пример работы показан на картинке ниже, а исходный код примера можете скачать здесь.
ThreejsLine-post-2

1. WEB — графика с Three.js. Общий принцип создания графики на Three.js

👁 580 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Three.js — это легкая библиотека для создания кроссбраузерных графических WEB приложений. Данная библиотека для отображения графики может использовать как Canvas из HTML5, как SVG для отображения 2D графики, так и WebGL для отображения 3D графики.

Примечание. Что плохо, так это то, что раз WebGL работает не во всех браузерах и типичным примером этого является отсутствие поддержки WebGL в JDK, посредством которых можно было бы создавать 3D программы на HTML5, из-за чего моя любимая платформа JavaFX не удовлетворяет меня в некоторых моих проектах 🙂 , но есть Canvas и SVG.

Последнюю версию Three.js можно скачать с репозитории GitHub или на официальном сайте Three.js. После распаковки архива у вас есть целый набор примеров и вспомогательных инструментов для работы с графикой. Следует отметить, что для работы некоторых примеров потребуется сервер, без которого они, наверняка не заработают в браузере, а так для начала достаточно обычного текстового редактора и навыков работы на HTML/JavaScript. Библиотека Three.js сама по себе кроссбраузерна, но если мы будем писать на голом JavaScript необходимо помнить, что пользовательский код на JavaScript должен быть оптимизирован под каждый браузер, а можно сделать еще легче — использовать кроссбраузерную библиотеку, такую как jQuery, но для простых примеров сойдет и обычный JavaScript 🙂 .

Прежде чем идти дальше, давайте разберем общую архитектуру построения Three.js — приложений и обозначим основные моменты, на которых следует акцентировать внимание. Ниже приведен рисунок, который отражает основной принцип. Все, что отображает Threejs — это либо объекты Canvas, либо SVG или WebGL, а JavaScript выступает связующим звеном между DOM HTML — интерфейса страницы — 6 и элементами сцены — 1 Three.js. В простейшем случае сцена может состоять из самой области вывода — 1, она так и называется — сцена(Scene), из камеры — 2, из объектов, которых мы хотим отобразить — 3 и освещения — пока этого всего нам достаточно, чтобы рассмотреть простейшие примеры. После окончания построения сцены начинается этап рендеринга(прорисовки) — 4 и приема пользовательских команд для изменения состояния элементов сцены — 1.

threejs-1

Итак, что нам нужно сделать для того, чтобы отобразить простой объект в окне браузера:

  • создать сцену;
  • создать рендер;
  • создать освещение;
  • создать камеру;
  • создать объекты;
  • добавить освещение, камеру и объекты на сцену;
  • добавить сцену на рендер;

Давайте теперь приступим к процессу кодирования и для этого нам, в первую очередь, будет необходимо создать скелет пустого HTML с названием index.html

<html lang="ru">
        <head>
            <meta charset="utf-8" />
            <title>Графика на Three.js</title>
            <script src="js/three.min.js"></script>
            <script src="js/script.js"></script>
        </head>
    <body>
    </body>
</html>

В разделе head мы подключаем библиотеку Three.js и наш рабочий скрипт, который мы назвали script.js, обеих закинули в папку js, из которого мы их читаем. Библиотека Three.js находиться в скачанном архиве в папке build, причем есть компрессивная и полная версия, разницы нет, кроме как в размере файла. В компрессивном отсутствуют лишние пробелы и символы. Итак, мы подключили файлы библиотеки и нашего рабочего скрипта, теперьпосмотрим на наш файл script.js

 

window.onload = init;
function init(){
	//--------------Создаем в дереве DOM элемен для вывода на экран-------
	container = document.createElement("div");//Создаем тег контейнера для вывода
	document.body.appendChild(container);//Добавляем в DOM HTML - документа
	
	//--------------Общие переменные объектов--------------
	var scene, camera, render;
	
	//--------------Инициализация общих переменных---------
	scene = new THREE.Scene();//Сцена
	camera = new THREE.PerspectiveCamera(65, window.innerWidth/window.innerHeight, 0.1, 2000);//Перспективаная проекция камеры. Принимает 3 параметра(масштаб, пропорция, точка 0 в близи, точка 0 в дали
    camera.position.x = 150;//Позиция камеры по x
	camera.position.z = 600;//Позиция камеры по y
	render = new THREE.WebGLRenderer();//Рендеринг
	render.setSize(window.innerWidth, window.innerHeight);//Инициализация рендерера
	
	//--------------Создаем объекты-------------------
	var cubeGeometry = new THREE.BoxGeometry(100, 100, 100);//Производная фигура. Первые 3 параметра - размеры, вторые - количество сегментов по 3-м граням. Последние параметры нужны для исключения деформации вывода текстуры при перспективе
	var cubeMaterial = new THREE.MeshNormalMaterial();//Устанавливаем материал
	var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);//Создаем линию из созданной геометрии
	scene.add(cube);//Добавляем объект на сцену
	
	var cylinderGeometry = new THREE.CylinderGeometry(50, 50, 200);//Производная фигура
	var cylinderMaterial = new THREE.MeshNormalMaterial();//Устанавливаем материал
	var cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);//Создаем линию из созданной геометрии
	cylinder.position.x = 200;//Перемещаем от начала координат по оси X
	scene.add(cylinder);//Добавляем объект на сцену
	
	//--------------Добавление вывод-----------------
	render.render(scene, camera);//Добавляем сцену и камеру в рендер после каждого цикла вызова
	
	container.appendChild(render.domElement);//Добавляем рендер в DOM для вывода на экран
}

В итоге должен получиться вот такой вот результат

Threejs-1-screen-1Пример вы можете скачать вот здесь.

Способы передачи параметров в Java

👁 196 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Как известно, в Java нет отдельных функций, как в С++/C/PHP/…, все реализуется в пределах класса и бывает случаи, когда необходимо передавать параметры методу или конструкции по умолчанию, или переменное количество параметров. В данной статье рассмотрим несколько способов реализации передачи необязательных параметров.

1.Способ перегрузки

void foo(String a,Integer b){//...}
void foo(String a){
foo(a,0);// где, 0 является необязательным параметром для b
}
foo("a",2); foo("a");

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

2. Использование Varargs

a) Все необязательные параметры имеют одинаковые типы:

void foo(String a, Integer... b){
  Integer b1 = b.length >0? b[0]:0;
  Integer b2 = b.length >1? b[1]:0;
  //...
  }
  foo("a");
  foo("a", 1, 2);

b) Типы необязательных параметров различные:

void foo(String a,Object... b){
     Integer b1 =0;
     String b2 ="";
     if(b.length >0){
        if(!(b[0] instanceof Integer)){
          throw new IllegalArgumentException("...");
        }
        b1 =(Integer)b[0];
     }
     if(b.length > 1){
       if(!(b[1] instanceof String)){
         throw new IllegalArgumentException("...");
       }
       b2 =(String)b[1];
       //...
     }
     //...
}  

foo("a");
foo("a",1);
foo("a",1,"b2");

Главный недостаток данного подхода — то, что необязательные параметры имеют различные типы и этим вы теряете статическую проверку типов. Кроме того, если каждый параметр имеет различные значения, то необходимо каким-то образом различить их.

3. Проверка на NULL

Для устранения ограничения передачи по типу можно использовать другой подход — проверка на передача значения на null и внутри тела функции организовать проверку : если передано null, то установить значения по умолчанию

void foo(String a,Integer b,Integer c){ 
         b = b !=null? b :0; 
         c = c !=null? c :0;
         //...
      }  
      foo("a",null,2);

Теперь все значения всех аргументов должны быть определены, но по умолчанию можно установить и как null.

4. Передача необязательного класса

Этот подход аналогичен предыдущему подходу, но использует guava необязательный класс в виде параметра, который имеет значения по умолчанию

void foo(String a,Optional bOpt){
         Integer b = bOpt.isPresent()? bOpt.get():0;
         //...
   }

   foo("a",Optional.of(2));
   foo("a",Optional.absent());

5.Использование шаблона Builder

Шаблон Builder используется для конструкторов и реализуется путем введения отдельного класса Builder

class Foo{
     privatefinalString a;
     privatefinalInteger b;
     Foo(String a,Integer b){
       this.a = a;
       this.b = b;
     }
     //...
}
class FooBuilder{
    privateString a ="";
    privateInteger b =0;
    FooBuilder setA(String a){
     this.a = a;
     return this;
    }
    FooBuilder setB(Integer b){
      this.b = b;
      return this;
    }
    Foo build(){returnnewFoo(a, b);
  }
}
Foo foo =new FooBuilder().setA("a").build();

6. Использование карт Maps

Когда количество параметров слишком большое и для большинство из них используют значения по умолчанию, то вы можете получить аргументы метода в виде карты, как имя/значение

void foo(Map<String,Object> parameters){
        String a ="";
        Integer b =0;
        if(parameters.containsKey("a")){
        if(!(parameters.get("a") instanceof Integer)){
           throw new IllegalArgumentException("...");
        }
        a =(String)parameters.get("a");
    }
    if(parameters.containsKey("b")){
     //... 
    }
     //...
}
foo(ImmutableMap.<String, Object>of("a", "a", "b", 2, "d", "value"));

 

Класс Stage в JavaFX

👁 202 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Загрузка...

В данной статье попытаемся разобраться с классом Stage в JavaFX. Понимание принципа работы данного класса очень важно, так как это один из главных классов, который вплотную работает с графами(контролами JavaFX). Публичный класс Stage расширяет класс Window. 

Замечание. Так как, данное слово имеет множество омонимов, то мне так и не удалось ясно представить суть значения этого слова с английского на русский, но кандидатами могут быть следующие значения: этап, стадия, ступень, платформа. Но больше всего подходит платформа, на котором, в дальнейшем, строятся различные сцены с помощью класса Scene.

public class Stage extends Window

Класс Stage в JavaFX является верхнеуровневым контейнером.  Основной Stage конструирует платформу. В приложении могут быть сконструированы дополнительные платформы на основе Stage. Объект Stage должен быть сконструирован и модифицирован на основе потока JavaFX приложения. Большинство свойств данного класса предназначены только для чтения, потому что они могут быть изменены извне базовой платформы и, следовательно, не могут быть связанными.

Стили Stage

Stage платформа может иметь один из следующих стилей, которые являются статическими свойствами класса  StageStyle:

  • StageStyle.DECORATEDStage со сплошным белым задним фоном и стилизацией платформы;
  • StageStyle.UNDECORATED — Stage со сплошным белым задним фоном и без стилизацией платформы;
  • StageStyle.TRANSPARENT — Stage с прозрачным задним фоном и без стилизации платформы;
  • StageStyle.UTILITY — Stage со сплошным белым задним фоном и с минимальной стилизацией платформы;

Стили должны быть инициализированы перед тем, как платформа может быть выведена на экран с помощью метода show().  На некоторых платформах стилизации могут быть недоступны. К примеру, на некоторых мобильных или встраиваемых устройствах. В таких случаях запросы DECORATED или UTILITY окна могут быть установлены, но стили не будут показаны.

Родитель Stage

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

Модальность

Платформа имеет один из следующих модальностей:

  • Modality.NONE — платформа, которая не блокируется никаким другим окном;
  • Modality.WINDOW_MODAL — платформа, которую блокируют входные события, распространяемые от источника ко всем окнам из его родителя к его корню. Этот корень является ближайшим предком окна без родителя;
  • Modality.APPLICATION_MODAL — платформа, которую блокируют входные события, распространяемые от того же приложения, исключая для тех которые исходят из его иерархии потомков;

Когда окно блокировано модальной платформой Stage его Z-порядок по отношению к потомкам сохраняется и он не получает никаких событий и никаких событий активации окна, но продолжает анимировать и нормально визуализировать. Необходимо заметить, что показываемая модальная платформа не обязательно блокирует его вызвавший родитель.  Метод show() возвращает вывод непосредственно и независимо от модальности платформы.  Если необходимо блокировать родитель, вызвавший платформу Stage до скрытия или закрытия платформы, то необходимо использовать showAndWait().  Модальное окно может быть инициализировано перед тем, как платформа может быть выведена(показана).

Пример использования Stage

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class HelloWorld extends Application {

    @Override public void start(Stage stage) {
        Text text = new Text(10, 40, "Hello World!");
        text.setFont(new Font(40));
        Scene scene = new Scene(new Group(text));

        stage.setTitle("Welcome to JavaFX!"); 
        stage.setScene(scene); 
        stage.sizeToScene(); 
        stage.show(); 
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

 

Способы реализации функции (callback) функции обратного вызова в Java

👁 376 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 1,00 из 5)
Загрузка...

Callback — функция обратного вызова. Используется тогда, когда необходимо выполнить определенный кусок кода, передав данный кусок кода в виде параметра методу и, естественно, данный кусок будет исполняться внутри переданного метода. Чтобы передать данный кусок кода, нам необходимо это кусок кода как-то именовать, естественно, что в Java мы будет это организовать в виде метода и будем передавать этот метод в виде аргумента другим методам.

Когда и где это может быть использовано?

Для начала, рассмотрим задачу вывода диалогового окна, средствами JavaFX. Так как JavaFX не содержит в арсенале понятие диалоговое окно, то нам придется его создавать самим. Такое окно может выводить любую информацию в виде элемента управления или просто текста. Нам необходимо как-то обработать события, которые расположены на данном диалоговом окне. Для решения данной задачи, сначала, воспользуемся решением без использования callback

public class Dialog {
    /** Интерфейс для обработки события*/
    public static String result = null;//Создадим поле хранения текущего значения
      
    public static void setResult(String result)//Реализуем setter
    {
        Dialog.result = result;
    }
    public static String getResult()//Реализуем getter
    {
        return Dialog.result;
    }

    //Метод реализации вывода диалогового окна
    public static void showAlert(String title){

          //Создаем новый экземпляр стадии(будет выполняться наряду с основным потоком программы)
          final Stage dlgStage = new Stage();

          //Создадим кнопку
          Button btnOk = new Button("Ok");
          
          //Прикрепим к кнопке событие
          btnOk.setOnAction(new EventHandler(){
              @Override
              public void handle(ActionEvent arg0) {
                  setResult("Yo click Ok!");//Устанавливаем значение при нажатии на кнопку
                  dlgStage.close();//Закрываем диалоговое окно при нажатии
              }
          });

          //Текстовое поле для вывода информации
          Label lblTitle = new Label(title);
          lblTitle.setFont(Font.font("Amble CN", FontWeight.NORMAL, 14));

          //Создаем контейнер для вертикального выравнивания элементов
          VBox vbox = new VBox(lblTitle,btnOk);
          vbox.setAlignment(Pos.CENTER);
          vbox.setMinSize(300, 200);

          //Создаем новую сцену и передаем ей контейнер
          Scene dlgScene = new Scene(vbox);

          //Устанавливаем сцену, инициализировав стили и т.д.
          dlgStage.setScene(dlgScene);
          dlgStage.initStyle(StageStyle.UNDECORATED);
          dlgStage.initModality(Modality.APPLICATION_MODAL);
          dlgStage.setMinWidth(300);
          dlgStage.setMinHeight(200);
          dlgStage.show();      
  }
}

Наш класс реализации диалогового окна готов, настал момент вывести его на экран, написав следующий код

Dialog.showAlert("Hello world!");
if(Dialog.getResult() != null)
{
  System.out.println(Dialog.getResult());// Результат, записанный при нажатии
}

В результате мы получим следующий результат на экране

java-dialog-callback

Нажмем на кнопку и посмотрим на вывод в консоле NetBeans, где у нас ничего не выведется в первый раз, потому что диалоговое окно выполняется своим потоком, а программа своим и после нажатия на «ok» мы инициализируем значение поля result, закрываем диалоговое окно, но повторно — то этот код не выпонится, поэтому значение в result при первом запуске будет null, как мы его инициализировали в классе Dialog. При повторном выполнении данного кода у нас выведется тоже самое окно, но значение уже будет не текущее, а предыдущего нажатия, что не есть нормально, так как создается 2 потока: 1- поток программы, 2 — поток диалогового окна.

 Решение проблемы с помощью callback

Код ниже именуется как callback.

new EventHandler<ActionEvent>(){
    @Override 
    public void handle(ActionEvent arg0){    
    dlgStage.close();
  }
}

Callback не возвращает type, как вы можете видеть выше в примере, он void.

Callback — и имеют методы, которые вы получаете как аргументы в другом методе.  Другой метод должен вызвать callback метод, когда он пожелает. Это значит, что callback — и имеют асинхронность.

В вашем примере, он вызывает callback, когда вы жмете на кнопку.

И в заключении, вы не сможете возвратить его, используя return.

Что делать ?

Вы можете вызвать метод из вашего callback и отправить ваше возвращаемое значение ему как аргумент.

Пример:

btnCancel.setOnAction( newEventHandler<ActionEvent>(){
    @Override
    public void handle(ActionEvent arg0){

        YourClass.setReturnValue("This is button Cancel");
        dlgStage.close();
   }
 });

Где setReturnValue  -метод принадлежащий вашему классу YourClass или его экземпляр, который будет содержать ваше возвращаемое значение.

Другой и лучшим путем подхода будет создание класса, который будет наследовать Stage. Также в вашем  showPrompt методе вы должны блокировать выполнение основного потока, используя showAndWait() или похожим образом.

В заключении, вы не можете создавать весь Prompt из только одного метода.

Работа с обработчиками событий в JavaFX

👁 266 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Данная статья расскажет вам как работать с обработчиками событий в JavaFX программах. Вы узнаете как можно обработать событие, которое было сгенерировано клавиатурой, мышью, скролами и другими элементами управления на экране вашего JavaFX приложения 🙂 .

Обработчики событий позволяют вам обрабатывать события на этапе восходящей фазы. Каждый узел может иметь один или более обработчиков для обрабатываемого события.  Простой обработчик может использовать один или более узлов и более одного типов событий. Если обработчик события для дочернего узла не использует событие, обработчик события для родительского узла позволяет родительскому узлу действовать на события после процесса дочернего узла, обрабатывать их и обеспечить общую обработку событий для нескольких дочерних узлов.

Регистрация и удаление обработчика события для узла

Для обработки события на этапе восходящей фазы узел должен зарегистрировать обработчик. Обработчик события наследует интерфейс EventHandler. Метод handle() данного интерфейса предоставляет код, который будет выполнен, когда событие, которое ассоциировано с обработчиком получит узел,для которого зарегистрирован обработчик.

Для регистрации обработчика используется метод addEventHandler(). Данный метод получает тип события и обработчик в виде аргумента. Ниже представлен пример , где первый обработчик добавляется к простому узлу и обрабатывается определенный тип события. Второй обработчик — для обработки события ввода, определен и зарегистрирован для 2-х различных узлов. Обработчик также зарегистрирован для двух различных типов событий.

//Пример регистрации обработчика для одного узла определенного типа события
node.addEventHandler(DragEvent.DRAG_ENTERED, 
                    new EventHandler() {
                        public void handle(DragEvent) { ... };
                    });

//Определение обработчика для предыдущего события
EventHandler handler = new EventHandler(() {
    public void handle(InputEvent event) {
        System.out.println("Handling event " + event.getEventType()); 
        event.consume();
    }

//Регистрация одного обработчика для двух различных узлов
myNode1.addEventHandler(DragEvent.DRAG_EXITED, handler);
myNode2.addEventHandler(DragEvent.DRAG_EXITED, handler);

//Регистрация еще одного типа события для первого из двух различных узлов
myNode1.addEventHandler(MouseEvent.MOUSE_DRAGGED, handler);

Обратите внимание, что обработчик события, который определен для одного типа события также может быть использован в любых подтипах этого события. Для глубокого анализа можете прочесть официальную статью Oracle, где описывается иерархия типов событий.

Когда вам больше не нужен обработчик события для узла, то его можно удалить, используя метод  removeEventHandler(). Данный метод в виде параметров получает тип удаляемого события и его обработчик. В ниже следующем примере представлен код, который демонстрирует данную возможность, где удаляется событие DragEvent.DRAG_EXITED узла myNode1 из предыдущего примера, но обработчик еще выполняет данный тип события для узла myNode2, и событие MouseEvent.MOUSE_DRAGGED для узла myNode1.

//Удаляем событие обработчика
myNode1.removeEventHandler(DragEvent.DRAG_EXITED, handler);

 Совет: Для удобства удаления обработчика события достаточно передать значение null в виде параметра через специальный метод, к примеру node1.setOnMouseDragged(null).

 

Архитектура JavaFX

👁 154 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

В данной статье будет рассмотрена архитектура приложений JavaFX.  JavaFX является надслойкой виртуальной машины JVM и включает в себя целый набор утилит и модулей для полноценной работы с 2D/3D графикой, с представлениями окон, медиа — контентом, WEB — контентом, а также предоставляет программные инструменты для взаимодействия между, вышеперечисленными, компонентами. Ниже представлена иллюстрация того, как устроена надслойка JavaFX

Архитектура JavaFX

 

Графы сцены

Графы сцены или Scene Graph  — это самый верхний слой в архитектуре JavaFX. Он представлен иерархической структурой узлов и является начальной точкой построения визуального приложения JavFX, который включает в себя различные визуальные элементы управления. Данный слой управляет вводом и выводом данных начальных и конечных данных от пользователя. Графа сцены представлен набором узлов, которые имеют атрибуты такие как ID(уникальный идентификатор узла), который необходим для идентификации элемента управления в Java или CSS коде, class(используется, как правило при придании различных стилевых свойств атрибутов через CSS) и др., а также представлен определенным, ограниченным размером в пределах экрана монитора. За исключением корневого элемента или как его еще называют root node, каждый узел имеет свой родительский элемент и 0 или более дочерних узлов, которым можно придать следующие атрибуты:

  • Эффекты, такие как мутность и тень;
  • Прозрачность;
  • Трансформации;
  • Обработчики событий мыши, клавиатуры, внутренних методов в коде Java;
  • Специфичных для приложения различные состояния отображения;

В отличии от Swing и AWT(Abstract Window Toolkit) , JavaFX включает в себя еще графические примитивы такие как линии, прямоугольники, окружности и т.д., которые можно использовать наряду с остальными элементами управления и в дополнении имеет контейнеры, элементы для просмотра изображений и проигрывания медиа-контента.

JavaFX предоставляет богатые возможности для графов через javafx.animation API, который способен добавлять различные динамические спецэффекты и анимации.

JavaFX API позволяет создавать контент, специфичный для нескольких типов:

  • Узлы: Сущности (2-D и 3-D), изображения, медиа, встроенный WEB браузер, текст, UI элементы, графики, группы и другие контейнеры;
  • Состояние: Трансформации (позиции и ориентации узлов), визуальные эффекты и другие визуальные состояния;
  • Эффекты: Простые объекты, которые меняют свой внешний вид, обретая эффекты замутнения, тени и цветовых установок;

 Публичный открытый API для JavaFX

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

  • Позволяет использовать полноценные Java характеристики , такие как генераторы, аннотации, многопоточность и лямбда выражения(включенные в Java SE 8);
  • Делает разработку для WEB очень легкой и позволяет для этого использовать другие, базовые для JVM, языки, такие как Groovy и JavaScript;
  • Позволяет разработчикам использовать другие системные языки, такие как Groovy для написания больших комплексных и сложных JavaFX приложений;
  • Позволяет использовать связывание, которое включают поддержку для высокопроизводительных lazy binding, binding выражения, bound sequence выражения и частичное связывание;
  • Внешние Java коллекции библиотек включают наблюдаемые списки(observable lists) и карты, которые позволяют программам соединять пользовательский интерфейс к моделям данных, позволяя наблюдать за обновлением или изменением данных в этих моделях и обновлением или изменением вместе с этим данных в пользовательских элементах управления;

JavaFX API и и программная модель имеет продолжение от JavaFX 1.x линейки выпуска, поэтому старые проекты можно легко перенести на новый выпуск JavaFX 2.x без особых затруднений.

 

Использование библиотеки jackcess для работы с MS Access через Java

👁 304 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Jakcess — библиотека на чистом Java для чтения и редактирования реляционной базы данных Access от компании Microsoft. Данная библиотека, на момент написания данной статьи(а это 30.04.2014), поддерживает версии MS Access 2000 — 2010. Данная библиотека предоставляет кросс-платформенный, ясный Java API для использования MS Access в пользовательских Java программах . Jakcess хорошо задокументирован и является частью проекта OpenHMS, который является брендом, продвигающий коллекции open source проектов.

Что нам потребуется для использования библиотеки Jackcess?

Если мы скачаем библиотеку jackcess.jar  попытаемся использовать ее, то у нас ничего не получится, так как у Jakcess есть зависимости, т.е. он еще нуждается в дополнительных библиотеках, которые будет необходимо параллельно добавить. Данные зависимости используются только самой библиотекой, вам остается только пользоваться чисто классами Jackcess и все. Ниже приведу зависимости которые будут необходимы для полноценной работы и следует отметить, что необходимо учитывать версии зависимостей, так как новая версия зависимости может включать видоизмененные классы, которые в текущей версии библиотеки Jackcess не успели обновить, поэтому вам необходимо это учитывать.

Зависимости компиляции

Ниже представлен список зависимостей, которые требуются для компиляции и запуска приложения с библиотекой Jackcess:

Наименование Ссылка  Версия   Тип  Лицензия Опции
commons-lang commons-lang 2.0 jar The Apache Software License, Version 2.0 Нет
commons-logging commons-logging 1.0.3 jar The Apache Software License, Version 2.0 Нет
org.apache.poi poi 3.9 jar The Apache Software License, Version 2.0 Да

Зависимости запуска программы с Jackcess

Следующие зависимости необходимы для среды времени выполнения:

 Наименование   Ссылка   Версия   Тип  Лицензия Опции
log4j log4j 1.2.7 jar The Apache Software License, Version 2.0 Да

Зависимости для тестирования

Следующие зависимости необходимы для тестирования приложения с Jackess:

Наименование Ссылка Версия Тип Лицензия
junit junit 4.11 jar Common Public License Version 1.0

Замечание 1. В данной статье приведены 3 зависимости, полный перечень зависимостей можете найти на официальном сайте — вот на этой странице.

Замечание 2.  Вам не нужно иметь все зависимости, достаточно те, которые я тут привел.

Пример использования Jackcess

try {
    Table table = DatabaseBuilder.open(new File("E:\\file.mdb")).getTable("Table");//Читаем из таблицы "Table"
     for(Row row : table) {
        System.out.println("Look ma, a row: " + row.get("Column"));//Читаем колонку под именем "Column"
     }
} catch (Exception ex) {
    ex.printStackTrace(); 
}

 

Часть 1. Работа с XML в Java. Описание

👁 117 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

В Java JDK встроены 2 вида XML парсеров, которые доступны как DOM(Document Object Model) и SAX(Simple API for XML). У обеих у них как свои преимущества, так и недостатки. В данном посте приведены примеры работы с файлами XML: будет создан, изменен и прочтен файл XML с помощью DOM и SAX.

DOM XML парсер

DOM парсер — это самый легкий инструмент для работы с XML структурой в Java. При использовании данного подхода все содержимое файла XML загружается в память компьютера, моделируя объект, чтобы можно было легко производить операции со структурой файла, но, данная легкость расплачивается  прожорливостью памяти и ресурсов процессора, поэтому, данный способ эффективен, если производиться операция с файлом небольшого размера.

SAX XML парсер

SAX парсер, в отличии от DOM, не загружает структуру документа в память, а использует для манипуляции функцию обратного вызова (org.xml.sax.helpers.DefaultHandler), с помощью которого он держит связь между пользователем и файлом. Помимо этого, SAX парсер имеет возможность в любой момент обратиться к любой части XML документа и манипулировать локальным содержимым, по этой причине SAX быстрее и менее расточительнее, чем DOM парсинг.

Что выбрать?

Требования к программе могут быть разные, поэтому, сразу ответить что лучше нельзя, все исходит из потребностей, но ничто не мешает использовать и SAX и DOM парсер  одновременно в одном и том же проекте.

Tennis Anime — программа на OpenGL для моделирования игры в теннис

👁 131 просмотров
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Tennis Anime —  программа, которая анимирует процесс игры в теннис. Программа реализована на графической библиотеке OpenGL на платформе Win32. Есть возможность управления движения видовым экраном в пространстве с помощью стрелок Вверх, Вниз, Влево, Направо. Написан на C++ в среде Visual Studio 2010. Основной целью данной программы является демонстрация движения мяча в воздухе и движение ракеток.

tennis-anime

Для создания временных интервалов движения мяча в программе используется таймер. Движение мяча в пространстве от ракетки описывается формулой горизонтально брошенного тела, а отскок от земли — формулой движения тела под углом.