「*[JavaFX]」の検索結果を表示しています
2014-07-12 08:40

よなよなJavaFX ~ミニ四駆動〜

昨日はよなよなJavaFX ~ミニ四駆動〜 - connpassに参加してきました。

@さん、すでにスライドがアップされてました。javafx-mini4wd
ミニ四駆のお話、すごく楽しく聞かせていただきました。そこからJavaFXシミュレータを作成するって、すごいです!
youtubeで拝見させていただいたのですが、すごいです!ミニ四駆シミュレーター v2014-05-22 - YouTube
物理演算は、やっぱり難しくてついていけなかったです、、、(汗)
JBullet - Java port of Bullet Physics LibraryJavaで作られたLibraryのお話とかとても勉強になります。
JavaFXでのミニ四駆シュミレータ、ぜひJavaOneにスピーカーとして参加、期待してます!
もちろんミニ四駆での活躍も応援しています!

@さん、まだ10代とお聞きして驚きました。しかもSwingJavaFXも勉強されていて頭の下がる思いです。
Javaビーム、楽しく新しい発想、勉強がさらに楽しくなっている様子がいいですよね〜。
若い方がJavaに、興味を持って勉強されているのは嬉しいです!

@さん、毎回そうなんですが、スラドがとっても綺麗で、オシャレで、すごく考えられていて、とにかくすごいです!
ITProでのJavaFXの連載Java技術最前線 - Java技術最前線:ITpro、終わってとても残念です。でも今はJavaSE8の連載、毎回写経して楽しく勉強させていただいています!
Bindのお話、ブログの記事で過去に勉強させていただいてますが、やっぱりお話をお聞きすることで理解が深まります。
Bindの機能をRule、validation、layoutに適用させるお話は、目からうろこです!
bindをアニメーションに使っているお話で@さんの絵描き歌を紹介されてました。
お話の進め方、スライドの作成、などなど、JavaFXだけでなくプレゼンの勉強にもなります!

私@の、JavaFXでのローカライズの紹介です。緊張していて何をお話したのが、よく覚えてないです、
とりあえずアップしました。tomoTaka01/JavaFX8Presenter ? GitHub
ローカライズは興味があるので、Javaでの数値、通貨のフォーマットなどいろいろ勉強していこうと思っています。

@さん、Typetalk(タイプトーク) - チームでのチャットはもっと楽しくなれるJavaFX、ScalaFXで作成したお話。
さらっと数日で作成したとの発言、すごいです!

参加者の皆様、お疲れ様でした。とても楽しく有意義な時間を過ごせました。
いろいろお世話してくださったスタッフの方々にも感謝です!!!

2014-07-04 08:52

JavaFX localization Sample

I just wanted to know how to make JavaFX Application for localization.
First of all, this code shows you only how to apply resource properties to the JavaFX Label control. And Java8 has 5 type of Chronology classes that easily fit to JavaFX DatePicker control.
FYI see http://docs.oracle.com/javafx/scenebuilder/1/user_guide/i18n-support.htm

f:id:tomoTaka:20140703073530p:image:w380

You can select Locale and Calendar in this screen.
When you click the locale ComboBox, you can see country and language(e.g. United States(English)).
But once you select the locale, this ComboBox displays the locale.toString???(e.g. en_US)
I have no idea how to fix this problem…
In the EntryStart.java(see code-2-2) shows you how to set locale to the comboBox and change the label using StringConverter.
You can get Calendars from Chronology#getAvailableChronologies method and put each Chronology to the RadioButton by setUserData method.
f:id:tomoTaka:20140703073601p:image:w300
f:id:tomoTaka:20140703073636p:image:w260

When you select the [United States(English)] and [ISO] by Label_en_US.properties
LocalizationInfoTitle.fxml(see code3-1)and Entry1.fxml(see code5-1) show you how to set the properties key using the present sign(%).
Thanks to the JavaFX, it is easy to set the resource properties to your application.
You just make properties file for each locale(see Figure 8), and use FXMLLoader with ResourceBundle class which is created with the properties file and locale.(see code3-2)
I think the NetBeans has very good editor for properties file(see Figure7).
f:id:tomoTaka:20140703073742p:image:w360

When you select the [Japan(Japanese)] and [Japanese Calendar] by Label_ja_JP.properties
I needed function, that has page transfer and localizations data(locale and calendar) transfer.
I found that The JavaFX custom control has this function.
In the code3-1,3-2 and 4 show you how to create Localization.java and Entry1.java(EntryBase.java) as a custom control.
F.Y.R http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm
I got the hint from this web site(http://skrb.hatenablog.com/entry/2012/06/16/175920) which explain how to implement page transitions.
f:id:tomoTaka:20140703073801p:image:w360

When you select the [Taiwan(Chinese)] and [Minguo Calendar] by Label.properties(default)
f:id:tomoTaka:20140703073818p:image:w360

When you select the [Saudi Arabia(Arabic)] and [Islamic Umm al-aura Calendar] by Label_ar_SA.properties
JavaFX DataPicker has setChronology method, all you need is to use this method for the specific calendar.(see code5-2)
f:id:tomoTaka:20140703073858p:image:w360

When you select the [Thailamd(Thai)] and [Buddhist Calendar] by Label.properties(default)
f:id:tomoTaka:20140703082216p:image:w360

NetBean8 has properties editor
f:id:tomoTaka:20140703073937p:image:w360

The project files
f:id:tomoTaka:20140703080950p:image:w280

public class Main extends Application{
    private BorderPane root;
    private EntryStartController entryStartController; 
    private HBox bottomHBox;
    private Button startButton;
    private Button resetLocaleButton;
    private Button nextButton;
    private PresentInfo presentInfo;
    private int fxmlIx = 0;
    private ENTRY[] fxmls = ENTRY.values();

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

    @Override
    public void start(Stage stage) throws Exception {
        this.presentInfo = new PresentInfo();
        Locale.setDefault(Locale.US);
        this.root = new BorderPane();
        setEntryStart();
        this.bottomHBox = new HBox();
        this.bottomHBox.getStyleClass().add("hbox");
        this.bottomHBox.setId("hbox-custom");        
        this.startButton = new Button("Start");
        this.resetLocaleButton = new Button("reset locale");
        this.nextButton = new Button("next");
        this.bottomHBox.getChildren().add(this.startButton);        
        this.setStartEvent();
        this.setResetLocaleEvent();
        this.setNextEvent();
        this.root.setBottom(this.bottomHBox);
        Scene scene = new Scene(root, 700, 500);
        stage.setTitle("Localization Sample");
        scene.getStylesheets().addAll("/css/layout.css");
        stage.setScene(scene);
        stage.show();
    }

    private void setEntryStart(){
        URL url = getClass().getResource("EntryStart.fxml");
        FXMLLoader loader = new FXMLLoader(url);
        try {
            this.presentInfo.centerNode = loader.<Node>load();
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.root.setCenter(this.presentInfo.centerNode);
        this.entryStartController = loader.getController();
    }

    private void setStartEvent() {
        this.startButton.setOnAction(event -> {
            this.presentInfo.localizationInfo = this.entryStartController.getLocalizationInfo();
            this.root.getChildren().remove(this.presentInfo.centerNode);
            this.presentInfo.topTitle = new LocalizationInfoTitle(this.presentInfo.localizationInfo);
            this.root.setTop(this.presentInfo.topTitle);
            this.bottomHBox.getChildren().remove(this.startButton);
            this.bottomHBox.getChildren().addAll(this.resetLocaleButton, this.nextButton);
            setEntry();
        });
    }
    
    private void setResetLocaleEvent() {
        this.resetLocaleButton.setOnAction(event -> {
            this.root.getChildren().remove(this.presentInfo.centerNode);
            this.root.getChildren().remove(this.presentInfo.topTitle);
            fxmlIx = 0;
            this.bottomHBox.getChildren().remove(this.resetLocaleButton);
            this.bottomHBox.getChildren().remove(this.nextButton);
            this.bottomHBox.getChildren().addAll(this.startButton);
            this.setEntryStart();
        });
    }

    private void setNextEvent() {
        this.nextButton.setOnAction(event -> {
            this.root.getChildren().remove(this.presentInfo.centerNode);
            fxmlIx++;
            setEntry();
        });
    }
    private void setEntry() {
        ENTRY entry = fxmls[fxmlIx];
        EntryBase entryBase = entry.getController();
        entryBase.loadFxml(this.presentInfo.localizationInfo, entry.getFxmlPath());
        this.root.setCenter(entryBase);
    }
    
private class PresentInfo{
    Node centerNode;
    LocalizationInfo localizationInfo;
    LocalizationInfoTitle topTitle;
}

}
enum ENTRY{
    Entry1("Entry1.fxml") {
        @Override
        EntryBase getController() {
            return new Entry1();
        }
    },
    Entry2("Entry2.fxml") {
        @Override
        EntryBase getController() {
            return new Entry2();
        }
    };
    private String fxmlPath;
    private ENTRY(String fxmlPath) {
        this.fxmlPath = fxmlPath;
    }
    abstract EntryBase getController();
    String getFxmlPath(){
        return this.fxmlPath;
    }
}
<AnchorPane id="AnchorPane" prefHeight="500.0" prefWidth="800.0" stylesheets="@../../css/layout.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sample.EntryStartController">
   <children>
      <ComboBox fx:id="localeCombo" layoutX="172.0" layoutY="54.0" prefWidth="150.0" />
      <Label layoutX="45.0" layoutY="54.0" prefHeight="26.0" prefWidth="102.0" text="Select Locale" />
      <Label layoutX="45.0" layoutY="113.0" text="Select Calendar" />
      <VBox fx:id="calendarVBox" layoutX="172.0" layoutY="113.0" prefHeight="179.0" prefWidth="288.0" spacing="10.0" style="-fx-border-style: solid; -fx-border-color: #666666;">
         <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
         </padding></VBox>
   </children>
</AnchorPane>
public class EntryStartController implements Initializable{
    @FXML
    private ComboBox<Locale> localeCombo;
    @FXML
    private VBox calendarVBox;
    private ToggleGroup calendarGroup = new ToggleGroup();

    @Override
    public void initialize(URL location, ResourceBundle resources) {        
        Locale.setDefault(Locale.ENGLISH);
        setLocaleCombo();
        setCalendar();
    }
    private void setLocaleCombo() {
        ObservableList<Locale> list = FXCollections.observableArrayList(
                new Locale("ja", "JP"),  // Japan
                new Locale("en", "US"),  // United States
                new Locale("fr", "FR"),  // France
                new Locale("de", "DE"),  // Germany
                new Locale("th", "TH"),  // Thailand
                new Locale("ar", "SA"),  // Saudi Arabia
                new Locale("zh", "TW")   // Taiwan
        );
        StringConverter<Locale> converter = new StringConverter<Locale>(){
            @Override
            public String toString(Locale object) {
                return String.format("%s(%s)", object.getDisplayCountry(), object.getDisplayLanguage());
            }
            @Override
            public Locale fromString(String string) {
                return null;
            }
        };
        localeCombo.getItems().addAll(list);
        localeCombo.setCellFactory(ComboBoxListCell.<Locale>forListView(converter));
        localeCombo.getSelectionModel().select(0);
    }

    private void setCalendar() {
        List<RadioButton> chronolories = Chronology.getAvailableChronologies().stream()
                .map(chronology -> {
                    RadioButton radioButton = new RadioButton(chronology.getDisplayName(TextStyle.FULL, Locale.getDefault()));
                    radioButton.setToggleGroup(calendarGroup);
                    radioButton.setUserData(chronology);
                    if (chronology.getCalendarType().equals("iso8601")) {
                        radioButton.setSelected(true);
                    }
                    return radioButton;
                }).collect(Collectors.toList());
        calendarVBox.getChildren().addAll(chronolories);
    }
    public LocalizationInfo getLocalizationInfo() {
        Locale locale = localeCombo.getSelectionModel().getSelectedItem();
        Chronology chronology = (Chronology) calendarGroup.getSelectedToggle().getUserData();
        LocalizationInfo localizationInfo = new LocalizationInfo();
        localizationInfo.setLocale(locale);
        localizationInfo.setChronolory(chronology);
        return localizationInfo;
    }
}
<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml" 
         stylesheets="@../../css/layout.css" styleClass="hbox"> 
      <Label text="%locale_label" styleClass="locale-label" />
      <Label fx:id="selectedLocale"  text="" styleClass="locale-label"/>
        <HBox.margin>
           <Insets right="50.0" />
        </HBox.margin>
      <Label text="%chronology_label" styleClass="locale-label" />
      <Label fx:id="selectedChronology" text="" styleClass="locale-label" />
</fx:root>
public class LocalizationInfoTitle extends HBox implements Initializable{
    private LocalizationInfo localizationInfo;
    @FXML
    private Label selectedLocale;
    @FXML
    private Label selectedChronology;
    
    public LocalizationInfoTitle(LocalizationInfo info) {
        this.localizationInfo = info;
        loadFxml();
    }
    private void loadFxml() {
        URL url = getClass().getResource("LocalizationInfoTitle.fxml");
        ResourceBundle bundle = ResourceBundle.getBundle("resources/Label"
                , localizationInfo.getLocale());
        FXMLLoader loader = new FXMLLoader(url, bundle);
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.<HBox>load();
        } catch (IOException ex) {
            Logger.getLogger(LocalizationInfoTitle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        Locale locale = this.localizationInfo.getLocale();
        this.selectedLocale.setText(String.format("%s(%s)"
                , locale.getDisplayCountry(locale), locale.getDisplayLanguage(locale)));
        Chronology chronolory = this.localizationInfo.getChronolory();
        this.selectedChronology.setText(chronolory.getDisplayName(TextStyle.FULL, locale));
    }
}
public abstract class EntryBase extends GridPane implements Initializable {
    protected LocalizationInfo localizationInfo;

    protected void loadFxml(LocalizationInfo localizationInfo, String fxmlPath) {
        this.localizationInfo = localizationInfo;
        URL url = getClass().getResource(fxmlPath);
        ResourceBundle bundle = ResourceBundle.getBundle("resources/Label", localizationInfo.getLocale());
        FXMLLoader loader = new FXMLLoader(url, bundle);
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.<GridPane>load();
        } catch (IOException ex) {
            Logger.getLogger(LocalizationInfoTitle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public abstract boolean goNext();
}
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="javafx.scene.layout.GridPane" hgap="10" vgap="10" 
    stylesheets="@../../css/layout.css" styleClass="grid"> 
    <children>
      <Label text="%letter_field_label" GridPane.columnIndex="0" GridPane.rowIndex="0" />
      <TextField fx:id="letterText" GridPane.columnIndex="1" GridPane.rowIndex="0" />
      <Label text="%digit_field_label" GridPane.columnIndex="0" GridPane.rowIndex="1" />
      <TextField fx:id="digitText" GridPane.columnIndex="1" GridPane.rowIndex="1" />
      <Label text="%date_label" GridPane.columnIndex="0" GridPane.rowIndex="2" />
      <DatePicker fx:id="datePicker" GridPane.columnIndex="1" GridPane.rowIndex="2" />
      <Label text="%currency_field_label" GridPane.columnIndex="0" GridPane.rowIndex="3" />
      <TextField fx:id="currencyText" GridPane.columnIndex="1" GridPane.rowIndex="3" />
    </children>
</fx:root>
public class Entry1 extends EntryBase {
    @FXML
    private DatePicker datePicker;
    
    @Override
    public boolean goNext() {
        // TODO do something about locatizaltion
        return true;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        this.datePicker.setChronology(this.localizationInfo.getChronolory());
    }    
}

The whole code is here(https://github.com/tomoTaka01/LocalizationSample)
I will continue working on this project to learn about localization.
I am really happy if you leave any comments.
keep coding... ;-)

2014-05-10 21:48

Simple WebView Sample

The following code is a very simple example how to start loading the url or cancel it.
You can get more details information here Adding HTML Content to JavaFX Applications | JavaFX 2 Tutorials and Documentation

f:id:tomoTaka:20140506171322p:image:w160

f:id:tomoTaka:20140506171355p:image:w360

f:id:tomoTaka:20140506172420p:image:w360

f:id:tomoTaka:20140506172441p:image:w360

The following code shows how to start or cancel loading a url.
This is very easy. First you get the WebEngine and use the load method to get the Web Page.
Since loading happens on a background thread, use the Worker to cancel it.

    public void initialize(URL url, ResourceBundle rb) {
...
        this.engine = webView.getEngine(); // *** 1.get the WebEngine from WebView
...
    }
    @FXML private void loadURL(Event event){
        startLoadState.apply();
        String url = urlText.getText();
        this.engine.load(url);   // *** 2.to start loading the url
    }
    @FXML private void cancelLoad(Event event) {
        startCancelState.apply();
        this.engine.getLoadWorker().cancel();  // *** 3.to cancel loading the url
    }

Thanks to bindings, it is very easy to show progress on indicator.(see figure1)

    public void initialize(URL url, ResourceBundle rb) {
...
        // binding the progressIndicator to the Web LoadWorker
        this.indicator.progressProperty().bind(this.engine.getLoadWorker().progressProperty());
...
    }

You need to add the ChangeListener for changing the state of the screen.
The following code implements SUCCEEDED, CANCELLED and FAILED states, but you can use more.
(FYR seehttp://docs.oracle.com/javafx/2/api/)

    public void initialize(URL url, ResourceBundle rb) {
…
        this.engine.getLoadWorker().stateProperty().addListener(
                (ov, oldState, newState) -> {
                    switch (newState){ 
                        case SUCCEEDED:
                            loadCompletedState.apply();
                            loadCompletedState.setScreenCommonState(this);
                            break;
                        case CANCELLED:
                            loadCanceledState.apply();
                            loadCanceledState.setScreenCommonState(this);
                            break;
                        case FAILED:
                            loadFailedState.apply();
                            loadFailedState.setScreenCommonState(this);
                            break;
                    };
                });
…

I just want to use FunctionalInterface to learn how to use it.
I am not sure if this is the right way.But it is fun to use JavaSE8.

@FunctionalInterface
interface LoadingState{
    void apply();
    default void setScreenCommonState(FXMLDocumentController controller) {
        controller.urlText.setDisable(false);
        controller.loadButton.setDisable(false);
        controller.cancelButton.setDisable(true);
        controller.indicator.setVisible(false);
    }

To change the state of controllers by implementing above FunctionalInterface.

    public void initialize(URL url, ResourceBundle rb) {
        setLoadingState();
…
    }

    private void setLoadingState() {
        initState = () -> {
            loadState.setText("");            
            webView.setVisible(false);
        };
        startLoadState = () -> {
            urlText.setDisable(true);
            loadButton.setDisable(true);
            cancelButton.setDisable(false);
            loadState.setTextFill(Color.BLACK);
            loadState.setText("loading...");            
            webView.setVisible(false);
            indicator.setVisible(true);
        };
        startCancelState = () -> {
            cancelButton.setDisable(true);
            loadState.setTextFill(Color.BLACK);
            loadState.setText("cancelling....");            
        };
        loadCompletedState = () -> {
            loadState.setTextFill(Color.BLACK);
            loadState.setText("completed!");            
            webView.setVisible(true);
        };
        loadFailedState = () -> {
            loadState.setTextFill(Color.RED);
            loadState.setText("failed!!!");            
            webView.setVisible(false);
        };
        loadCanceledState = () -> {
            loadState.setTextFill(Color.ORANGE);
            loadState.setText("canceled!");            
            webView.setVisible(false);
        };
    }

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.web.*?>

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxsimplewebview.FXMLDocumentController">
    <children>
        <WebView fx:id="webView" layoutX="15.0" layoutY="86.0" prefHeight="497.0" prefWidth="773.0" />
        <Label layoutX="30.0" layoutY="33.0" text="URL:" />
        <TextField fx:id="urlText" layoutX="68.0" layoutY="28.0" prefHeight="26.0" prefWidth="592.0" />
        <Button fx:id="loadButton" layoutX="700.0" layoutY="28.0" mnemonicParsing="false" onMouseClicked="#loadURL" prefHeight="26.0" prefWidth="82.0" text="load" />
        <Label fx:id="loadState" layoutX="102.0" layoutY="65.0" prefHeight="16.0" prefWidth="500.0" />
        <Label layoutX="27.0" layoutY="65.0" prefHeight="16.0" prefWidth="75.0" text="load state:" />
        <ProgressIndicator fx:id="indicator" layoutX="163.0" layoutY="119.0" prefHeight="148.0" prefWidth="218.0" progress="0.0" />
        <Button fx:id="cancelButton" layoutX="673.0" layoutY="60.0" mnemonicParsing="false" onMouseClicked="#cancelLoad" prefHeight="26.0" prefWidth="111.0" text="cancel load" />
    </children>
</AnchorPane>

The above code2 is created by Scene Builder.
f:id:tomoTaka:20140510212904p:image:W380

The main entry point for JavaFX application is here.

public class JavaFXSimpleWebView extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        // *** load the FXML(code2)
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene scene = new Scene(root);
        stage.setTitle("Simple WebView Sample");
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);  // *** 
    }
}

Assigned the project using Flex, so I created the HTML with swf file before. 2014-05-06 - tomoTakaの日記
I was a little curious about if HTML with Flex works on JavaFX WebView.
It does not work, but it is very fun to try something new by myself.
f:id:tomoTaka:20140506173418p:image:w430
whole code is herehttps://github.com/tomoTaka01/JavaFXSimpleWebView
just keep coding... ;-)

2014-03-11 08:24

DragboardChecker

Thanks to JavaFX Drag & Drop function, you can drag something from a third-party(native) application such as Finder(Mac OS).
You just need to implement of the DragOver and DragDropped event hander on a Target(see code1).
This is exciting for me, so I just want to know what kind of content the dragboard has.
This application checks dragboard contents and shows them to the screen.

f:id:tomoTaka:20140310080809p:image:w360

When you drag files from Finder(Max OS 10.9) to this App, the dragboard has files and 1 Dataformat.
f:id:tomoTaka:20140310074624p:image:w480

When you drag URL from web browser to this, the dragboard has string, URL, files and 3 of Dataformat.
f:id:tomoTaka:20140310074652p:image:w480

f:id:tomoTaka:20140311075106p:image:w360f:id:tomoTaka:20140311075127p:image:w360

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        initContextCheckers();
        this.dataFormatListView.setCellFactory(p -> new DataFormatCell()); // <― see code 4
        this.dropHereImage.setOnDragOver(e -> {
            e.acceptTransferModes(TransferMode.ANY);
            e.consume();
        });
        this.dropHereImage.setOnDragDropped(e -> {
            Dragboard db = e.getDragboard();
            this.contextCheckers.forEach(checker -> checker.check(db)); // <― see code2,3
            setDataFormatListView(db);
            e.setDropCompleted(true);
        });
    }
    private void initContextCheckers() {
        this.contextCheckers = Arrays.asList(
            new StringContextChecker(this.stringCheck, this.stringText)
          , new UrlContextChecker(this.urlCheck, this.urlText)
          , new FileContextChecker(this.filesCheck, this.filesText)
          , new RtfContextChecker(this.rtfCheck, this.rtfText)
          , new ImageContextChecker(this.imageCheck, this.imageView)
          , new HtmlContextChecker(this.htmlCheck, this.htmlText)
        );
    }    
    private void setDataFormatListView(Dragboard db) {
        List<DataFormatInfo> list = db.getContentTypes().stream().map(df -> {
            return new DataFormatInfo(df, db.getContent(df).toString());
        }).collect(Collectors.toList());       // <― see code5
        this.dataFormatListView.setItems(FXCollections.observableArrayList(list));
    }

This is the base class for each checker class like StringChecker, UrlChecker so on.

public abstract class ContextChecker<T extends Node> {
    protected BooleanProperty checkboxProp;
    protected T node;
    public ContextChecker(CheckBox checkbox, T node) {
        this.checkboxProp = new SimpleBooleanProperty(false);
        checkbox.selectedProperty().bind(this.checkboxProp);
        this.node = node;
    }
    abstract public void check(Dragboard db);    
}

Since clipboard(dragboard) has 6 methods for contains data, I create 6 checker class.

typemethodmethodchecker class
StringhasStringgetString StringContextChecker
FileshasFilesgetFilesFileContextChecker
HTMLhasHtmlgetHtmlHtmlContextChecker
ImagehasImagegetImageImageContextChecker
RTFhasRtfgetRtfRtfContextChecker
URLhasUrlgetUrlUrlContextChecker
public class StringContextChecker extends ContextChecker<TextArea>{
    public StringContextChecker(CheckBox checkbox, TextArea node) {
        super(checkbox, node);
    }
    @Override
    public void check(Dragboard db) {
        if (db.hasString()) {
            super.checkboxProp.set(true);
            super.node.setText(db.getString());
        } else {
            super.checkboxProp.set(false);
            super.node.clear();
        }
    }   
}

The clipboard(dragboard) has some custom data which are defined by data format.
To show the custom data, you can implement custom list cell like below.

public class DataFormatCell extends ListCell<DataFormatInfo>{
    GridPane root;
    Label dataFormatLabel;
    Text dataFormatText;
    Label contentLabel;
    Text contentText;
    Label idsLabel;
    ListView idsListView;
    ObservableList<String> idsList;
    
    public DataFormatCell() {
        init();
    }
    @Override
    protected void updateItem(DataFormatInfo info, boolean empty) {
        super.updateItem(info, empty);
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            this.dataFormatText.setText(info.getDataFormat());
            this.contentText.setText(info.getContent());
            this.idsList.setAll(info.getIdentifiersList());
            setGraphic(root);
        }
    }
    private void init() {
        this.root = new GridPane();
        this.root.setPadding(new Insets(2));
        this.root.setHgap(2);
        this.root.setVgap(2);
        this.dataFormatLabel = new Label("Data Format:");
        this.dataFormatLabel.setPrefWidth(100);
        this.dataFormatText = new Text();
        this.dataFormatText.prefWidth(400);
        this.contentLabel = new Label("Content:");
        this.contentText = new Text();
        this.idsLabel = new Label("Identifires");        
        this.idsList = FXCollections.observableArrayList();
        this.idsListView = new ListView(this.idsList);
        this.idsListView.setPrefHeight(70);
        this.idsListView.setPrefWidth(500);        
        this.root.add(this.dataFormatLabel, 0, 0);
        this.root.add(this.dataFormatText, 1, 0);
        this.root.add(this.contentLabel, 0, 1);
        this.root.add(this.contentText, 1, 1);
        this.root.add(this.idsLabel, 0, 2);
        this.root.add(this.idsListView, 0, 3, 2, 1);
    }
}

This code has custom data information for DataFormatCell(see code4).

public class DataFormatInfo {
    private StringProperty dataFormatProp;
    private StringProperty contentProp;
    private List<String> identifiersList;    

    public DataFormatInfo(DataFormat dataFormat, String content) {
        this.dataFormatProp = new SimpleStringProperty(dataFormat.toString());
        this.contentProp = new SimpleStringProperty(content);
        this.identifiersList = 
            dataFormat.getIdentifiers().stream().collect(Collectors.toList());
    }
    public String getDataFormat(){
        return this.dataFormatProp.getValue();
    }
    public String getContent() {
        return this.contentProp.getValue();
    }
    public List<String> getIdentifiersList() {
        return this.identifiersList;
    }
}

The whole code is heretomoTaka01/DragboardChecker ? GitHub.
keep coding... ;-)

2014-02-26 08:33

JavaFX does not work in NetBeans7.4 using JDK7

It is easy to create JavaFX project using NetBeans7.4.
After updating JavaSE7 to 1.7.0_51, JavaFX project has ClassNotFoundException error in NetBeans7.4. It has no compiler errors.
So I just looked into the reason to improve my skill about Java.

f:id:tomoTaka:20140224073113p:image:w360

f:id:tomoTaka:20140224074516p:image:w360

f:id:tomoTaka:20140224073945p:image:medium

f:id:tomoTaka:20140224075039p:image:w360

Why has JavaFX project been compiled without error in NetBeans7.4

NetBeans adds [javafx.classpath.extension] to the library
f:id:tomoTaka:20140224074636p:image:w360

project.properties indicates location of javafx.classpath.extension.

...
javac.classpath=\
    ${javafx.classpath.extension}
...
javafx.classpath.extension=\
    ${platforms.JDK_1.7.home}/jre/lib/jfxrt.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/javaws.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/deploy.jar:\
    ${platforms.JDK_1.7.home}/jre/lib/plugin.jar

NetBeans does not add [javafx.classpath.extension] to the library
f:id:tomoTaka:20140224080626p:image:w360

The difference between JavaSE7 and JavaSE8.

This code shows how to get the locations of paths.
(Bootstrap classes, Extension classes and User classes)

import java.net.URL;

public class Test {
    public Test() {
        String pathProp = System.getProperty("sun.boot.class.path");
        String[] paths = pathProp.split(":");
        for (String path : paths) {
            System.out.println(String.format("path:%s", path));
        }
        System.out.println("**********");
        String extPathProp = System.getProperty("java.ext.dirs");
        String[] extPaths = extPathProp.split(":");
        for (String path : extPaths) {
            System.out.println(String.format("java.ext.dir:%s", path));
        }
        System.out.println("**********");
        String classPathProp = System.getProperty("java.class.path");
        String[] classPaths = classPathProp.split(":");
        for (String path : classPaths) {
            System.out.println(String.format("class.path:%s", path));
        }
        System.out.println("**********");
        ClassLoader loader = getClass().getClassLoader();
        URL url = loader.getResource("javafx/application/Application.class");
        System.out.println(String.format("Application URL:%s", url.toString()));
    }
    public static void main(String... args) {
        new Test();
    }
}
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:.
**********
Exception in thread "main" java.lang.NullPointerException      // <---「javafx.application.Application.class」がloadできない?
	at Test.<init>(Test.java:25)
	at Test.main(Test.java:28)
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:.
**********
Application URL:jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/jfxrt.jar!/javafx/application/Application.class

JavaSE7 does not include jfxrt.jar in sun.boot.class.path.


versionlocation
JavaSE7/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib
JavaSE8/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext
javac -cp /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar:. Test.java
java -cp /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar:. Test

The NullPointerException error resolves.

path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/resources.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/rt.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/sunrsasign.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jsse.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jce.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/charsets.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfr.jar
path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/classes
**********
java.ext.dir:/Users/tomo/Library/Java/Extensions
java.ext.dir:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/ext
java.ext.dir:/Library/Java/Extensions
java.ext.dir:/Network/Library/Java/Extensions
java.ext.dir:/System/Library/Java/Extensions
java.ext.dir:/usr/lib/java
**********
class.path:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar
class.path:.
**********
Application URL:jar:file:/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar!/javafx/application/Application.class

The conclusion

It is nothing to say,
I know I have no knowledge about classloader, so I must learn hard about Java.

just keep coding…;-)

tomoTaka
tomoTaka