2015-08-29 2 views
3

Gradle сборки из глюонной плагина (в Netbeans 8.0.2) для портирования JavaFX для Android создает каталог следующие структуры:Странная Gluon структура проекта для JavaFX - Android портирования

  1. Источник Пакеты [Java]
  2. Android/Java пакеты
  3. Desktop/Java пакеты
  4. Ios/Java Пакеты

Каждый из этих каталогов содержат Java пак внутри них. Как правило, сборка Gluon создала бы «основной» класс для нас в одном пакете java внутри каталога «Source Packages» [имя Пакеты с «Source Packages» могут вводить в заблуждение, поскольку это не пакет Java, а всего лишь каталог файловой системы]. Этот основной класс расширяет класс приложений Javafx и, таким образом, является точкой входа в наше приложение.

API Android доступен только в каталоге Android/Java Packages для любого созданного внутри него пакета Java. Скажем, класс android.Vibrator доступен только здесь.

Проблема заключается в том, что мы не можем ссылаться на класс, созданный внутри любого пакета Java внутри каталога Android/Java, на любой пакет java, созданный в каталоге Source Packages [Java] !! Если это так, то как мы возьмем приложение вперед от метода start() javafx.Application в say android.Vibrator.

Структура проекта глюонной имеет снимок на: How to reference android.jar in Gluon Project

ответ

2

Как вы знаете, проект JavaFXPorts позволяет развернуть JavaFX приложений в Desktop, Android и IOS устройств. Когда это просто чистый код JavaFX, проект добавляется в основной области, и оттуда он будет виден на всех этих платформах.

Только в том случае, если вам нужен какой-либо конкретный код платформы, вы должны добавить его в соответствующий пакет.

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

Если вы проверите HelloPlatform sample в репозитории JavaFXPorts, вы найдете класс PlatformService для загрузки пакетов с использованием ServiceLoader.

Другая возможность заключается в использовании Class.forName() для динамической загрузки классов во время выполнения, как только мы узнаем о платформе, на которой работает приложение.

Я предлагаю вам ознакомиться с проектом Gluon Down, который управляет несколькими услугами определенной платформы и предоставляет вам единый, независимый от платформы API.

Для тех услуг, которые еще не доступны в Down (не стесняйтесь вносить свой вклад), вы можете реализовать их как в этом простом приложении, созданном с использованием Gluon Plugin.

Источник Пакеты [Java]

Во-первых, создать метод getPlatform(), и добавьте указанные классы для каждой конкретной платформы. Например, добавьте org.gluonoss.vibrator.GluonAndroidPlatform.java в пакет Android.

public class GluonPlatformFactory { 

    public static GluonPlatform getPlatform() { 
     try { 
      String platform = System.getProperty("javafx.platform", "desktop"); 
      String path = "org.gluonoss.vibrator.GluonDesktopPlatform"; 
      if(platform.equals("android")) { 
       path = "org.gluonoss.vibrator.GluonAndroidPlatform"; 
      } else if(platform.equals("ios")) { 
       path = "org.gluonoss.vibrator.GluonIosPlatform"; 
      } 
      return (GluonPlatform) Class.forName(path).newInstance(); 
     } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { 
      System.out.println("Platform Error "+e.getMessage()); 
     } 
     return null; 
    } 
} 

Теперь создадим интерфейс, с помощью метода вы хотите на всех платформах:

public interface GluonPlatform { 

    void vibrate(); 

} 

Наконец, на главном классе получить платформу и вызвать ваш метод:

@Override 
    public void start(Stage stage) { 
     final Button button = new Button("Click me!"); 

     button.setOnAction(e-> GluonPlatformFactory.getPlatform().vibrate()); 

     StackPane root = new StackPane(button); 

     Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds(); 
     Scene scene = new Scene(root, visualBounds.getWidth(), visualBounds.getHeight()); 

     stage.setScene(scene); 
     stage.show(); 
    } 

Настольные/Java-пакеты

Добавить e вибрирующий метод. Пока оставьте его пустым, но вы можете добавить Timeline, чтобы переместить кнопку, например.

public class GluonDesktopPlatform implements GluonPlatform { 

    @Override 
    public void vibrate() { 
     System.out.println("Vibrating!"); 
    } 

} 

Android/Java пакеты

Добавить метод вибрировать. Обратите внимание, что мы должны использовать FXActivity, который является мостом между потоком JavaFX и активностью Android.

public class GluonAndroidPlatform implements GluonPlatform { 

    @Override 
    public void vibrate() { 
     Vibrator v = (Vibrator) FXActivity.getInstance().getSystemService(Context.VIBRATOR_SERVICE); 
     v.vibrate(500); 
    } 

} 

Не забудьте добавить требуемое разрешение на вашем AndroidManifest файле (вы найдете его под src/android/AndroidManifest.xml.

Теперь вы можете развернуть проект и запустить его на рабочем столе (gradlew run), и он будет работать , и установите его на Android (gradlew androidInstall), и он тоже будет работать.

+0

Большое спасибо @Jose Pereda. Поскольку для java.util.ServiceLoader необходимо явно указать реализации поставщика услуг через распознающий файл внутри META- Каталог INF/services и эта структура каталогов должны присутствовать во время выполнения classpath приложения, то какие изменения необходимо внести в сценарии построения градации, чтобы установить путь к классам времени выполнения, чтобы указать на META-INF/services. Я очень новичок в градиенте, поэтому любой вход был бы замечательным. –

+0

Я не думаю, что вам нужна какая-либо модификация. Пример HelloPlatform работает с ServiceLoader без каких-либо изменений в [build.gradle] (https://bitbucket.org/javafxports/samples/src/tip/build.gradle). Во всяком случае, я предпочитаю подход Class.forName(), где имена классов вставляются в код, поэтому вам не нужны дополнительные текстовые файлы. Вы попробовали образец вибратора « –

+0

@ JosePereda.Thanks много для вашей помощи и объяснения. Я пробовал код выше, и он работал как «шарм»; Я использовал Class.forName (String) вместо ServiceLoader . Поскольку вы уже работаете над Charm Down, и, как вы говорите, есть еще не созданные сервисы, я бы хотел внести свой вклад в то же самое сейчас, так как теперь я чувствую некоторый уровень уверенности в JavaFXPorts. Профессионально работаю над JavaFX для пользовательского интерфейса в сочетании с EJB в качестве серверных компонентов со стандартами, такими как RMI и JMS для интеграции. Я хотел бы обсудить с вами, я хотел бы знать, с какой службы следует начинать. –