Created
November 25, 2012 11:30
-
-
Save aoetk/4143183 to your computer and use it in GitHub Desktop.
第8回JavaFX勉強会のサンプルアプリケーション
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package aoetk.multitouch.sample; | |
import javafx.application.Application; | |
import javafx.fxml.FXMLLoader; | |
import javafx.scene.Parent; | |
import javafx.scene.Scene; | |
import javafx.stage.Stage; | |
/** | |
* 第8回JavaFX勉強会に使用したマルチタッチサンプルアプリケーション。 | |
*/ | |
public class JavafxMultitouchSample extends Application { | |
/** | |
* アプリケーション開始処理。 | |
* @param stage アプリケーションのステージ | |
* @throws Exception アプリケーション実行中に何らかの例外が発生 | |
*/ | |
@Override | |
public void start(Stage stage) throws Exception { | |
Parent root = FXMLLoader.load(getClass(). | |
getResource("TouchRegion.fxml")); | |
Scene scene = new Scene(root); | |
stage.setScene(scene); | |
stage.setTitle("JavaFXマルチタッチサンプル"); | |
stage.show(); | |
} | |
/** | |
* メインメソッド。 | |
* @param args コマンドライン引数 | |
*/ | |
public static void main(String[] args) { | |
launch(args); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.border { | |
-fx-border-color: black; | |
-fx-border-width: 3; | |
} | |
.pagination .page { | |
-fx-background-color: #DDF1F8; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<?import java.lang.*?> | |
<?import java.net.*?> | |
<?import java.util.*?> | |
<?import javafx.geometry.*?> | |
<?import javafx.scene.*?> | |
<?import javafx.scene.control.*?> | |
<?import javafx.scene.layout.*?> | |
<?import javafx.scene.shape.*?> | |
<?import javafx.scene.text.*?> | |
<AnchorPane id="AnchorPane" prefHeight="680.0" prefWidth="1000.0" xmlns:fx="http://javafx.com/fxml" fx:controller="aoetk.multitouch.sample.TouchRegionController"> | |
<children> | |
<TabPane fx:id="tabPane" prefHeight="680.0" prefWidth="1000.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | |
<tabs> | |
<Tab text="タッチテスト"> | |
<content> | |
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> | |
<children> | |
<Pane fx:id="touchPane" onTouchPressed="#handleTouchStart" prefHeight="606.0" prefWidth="960.0" styleClass="border" AnchorPane.bottomAnchor="56.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="14.0" /> | |
<Label text="Touch Event Set ID:" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="20.0" /> | |
<Label fx:id="lblEventSetId" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="151.0" /> | |
<Label text="Touch Count:" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="197.0" /> | |
<Label fx:id="lblTouchCount" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="291.0" /> | |
<Label text="Touch x:" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="341.0" /> | |
<Label fx:id="lblTouchX" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="407.0" /> | |
<Label text="y:" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="469.0" /> | |
<Label fx:id="lblTouchY" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="487.0" /> | |
<Button layoutX="891.0" layoutY="600.0" mnemonicParsing="false" onAction="#handleBtnClearAction" prefHeight="30.0" prefWidth="86.0" text="クリア" /> | |
</children> | |
</AnchorPane> | |
</content> | |
</Tab> | |
<Tab text="ズーム・ローテーションテスト"> | |
<content> | |
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> | |
<children> | |
<Rectangle fx:id="rectangle" arcHeight="5.0" arcWidth="5.0" fill="#ff007a" height="200.0" onRotate="#handleRectangleRotation" onScroll="#handleRectangleScroll" onZoom="#handleRectangleZoom" stroke="BLACK" strokeType="INSIDE" width="200.0" AnchorPane.bottomAnchor="222.0" AnchorPane.rightAnchor="400.0" /> | |
<GridPane id="GridPane" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="20.0"> | |
<children> | |
<Label text="縮尺:" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="0"> | |
<font> | |
<Font size="50.0" fx:id="x1" /> | |
</font> | |
</Label> | |
<Label fx:id="lblFactor" alignment="CENTER_RIGHT" font="$x1" text="100" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="0" /> | |
<Label font="$x1" text="\%" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="0" /> | |
<Label font="$x1" text="角度:" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="1" /> | |
<Label fx:id="lblAngle" alignment="CENTER_RIGHT" font="$x1" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="1" /> | |
<Label font="$x1" text="度" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1" /> | |
<Label font="$x1" text="Δx:" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2" /> | |
<Label font="$x1" text="Δy:" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="3" /> | |
<Label id="lblAngle" fx:id="lblDeltaX" alignment="CENTER_RIGHT" font="$x1" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="2" /> | |
<Label id="lblAngle" fx:id="lblDeltaY" alignment="CENTER_RIGHT" font="$x1" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="3" /> | |
<Label font="$x1" text="px" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="2" /> | |
<Label font="$x1" text="px" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="3" /> | |
</children> | |
<columnConstraints> | |
<ColumnConstraints hgrow="SOMETIMES" maxWidth="130.0" minWidth="10.0" prefWidth="130.0" /> | |
<ColumnConstraints hgrow="SOMETIMES" maxWidth="160.0" minWidth="10.0" prefWidth="160.0" /> | |
<ColumnConstraints hgrow="SOMETIMES" maxWidth="63.0" minWidth="10.0" prefWidth="63.0" /> | |
</columnConstraints> | |
<rowConstraints> | |
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> | |
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> | |
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> | |
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> | |
</rowConstraints> | |
</GridPane> | |
</children> | |
</AnchorPane> | |
</content> | |
</Tab> | |
<Tab text="コントロールのタッチ対応テスト"> | |
<content> | |
<BorderPane prefHeight="200.0" prefWidth="200.0"> | |
<center> | |
<Pagination fx:id="pagination" styleClass="bullet"> | |
<BorderPane.margin> | |
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> | |
</BorderPane.margin> | |
</Pagination> | |
</center> | |
<right> | |
<ListView fx:id="lvFonts" prefHeight="200.0" prefWidth="230.0" /> | |
</right> | |
</BorderPane> | |
</content> | |
</Tab> | |
</tabs> | |
</TabPane> | |
</children> | |
<stylesheets> | |
<URL value="@style.css" /> | |
</stylesheets> | |
</AnchorPane> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package aoetk.multitouch.sample; | |
import static javafx.scene.paint.Color.*; | |
import java.net.URL; | |
import java.util.List; | |
import java.util.ResourceBundle; | |
import javafx.collections.FXCollections; | |
import javafx.event.ActionEvent; | |
import javafx.event.EventHandler; | |
import javafx.fxml.FXML; | |
import javafx.fxml.Initializable; | |
import javafx.scene.Node; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.ListView; | |
import javafx.scene.control.Pagination; | |
import javafx.scene.input.MouseEvent; | |
import javafx.scene.input.RotateEvent; | |
import javafx.scene.input.ScrollEvent; | |
import javafx.scene.input.TouchEvent; | |
import javafx.scene.input.TouchPoint; | |
import javafx.scene.input.ZoomEvent; | |
import javafx.scene.layout.Pane; | |
import javafx.scene.layout.VBox; | |
import javafx.scene.paint.Color; | |
import javafx.scene.shape.Circle; | |
import javafx.scene.shape.Rectangle; | |
import javafx.scene.text.Font; | |
import javafx.util.Callback; | |
/** | |
* 第8回JavaFX勉強会に使用したマルチタッチサンプルアプリケーションのコントローラー。 | |
*/ | |
public class TouchRegionController implements Initializable { | |
/** | |
* タッチ場所に表示したサークルのタッチ移動に対するハンドラ。 | |
*/ | |
class TouchMoveHandler implements EventHandler<TouchEvent> { | |
private double startSceneX; | |
private double startSceneY; | |
public TouchMoveHandler(double startSceneX, double startSceneY) { | |
this.startSceneX = startSceneX; | |
this.startSceneY = startSceneY; | |
} | |
@Override | |
public void handle(TouchEvent event) { | |
final Circle circle = (Circle) event.getTarget(); | |
final TouchPoint point = event.getTouchPoint(); | |
relocateCircle(circle, point.getSceneX() - startSceneX + circle.getLayoutX(), | |
point.getSceneY() - startSceneY + circle.getLayoutY()); | |
startSceneX = point.getSceneX(); | |
startSceneY = point.getSceneY(); | |
} | |
} | |
/** タッチした場所に表示する円の色定義。10色サイクル。 */ | |
private static final Color[] COLORS = new Color[] { BLUE, RED, GREEN, VIOLET, BROWN, CYAN, YELLOW, BLACK, GREY, PINK }; | |
/** 円の半径。 */ | |
private static final double CIRCLE_RADIUS = 30.0; | |
/** フォント一覧を表示するページネーションコントロールの1ページあたりの表示数。 */ | |
private static final int FONTS_PER_PAGE = 25; | |
/** 円が表示された総数。 */ | |
private int circleCount = 0; | |
/** システムがサポートするフォントのリスト。 */ | |
private List<String> fonts; | |
/** タッチテストの領域。 */ | |
@FXML | |
private Pane touchPane; | |
/** 総タッチ数を表示するラベル。 */ | |
@FXML | |
private Label lblTouchCount; | |
/** タッチイベントのIDを表示するラベル。 */ | |
@FXML | |
private Label lblEventSetId; | |
/** タッチポイントのx座標を表示するラベル。 */ | |
@FXML | |
private Label lblTouchX; | |
/** タッチポイントのy座標を表示するラベル。 */ | |
@FXML | |
private Label lblTouchY; | |
/** フォント一覧を表示するページネーションコントロール。 */ | |
@FXML | |
private Pagination pagination; | |
/** ジェスチャーイベントの対象となる四角形。 */ | |
@FXML | |
private Rectangle rectangle; | |
/** ズームイベントの倍率を表示するラベル。 */ | |
@FXML | |
private Label lblFactor; | |
/** ローテーションイベントの角度を表示するラベル。 */ | |
@FXML | |
private Label lblAngle; | |
/** スクロールイベントのx方向の移動量を表示するラベル。 */ | |
@FXML | |
private Label lblDeltaX; | |
/** スクロールイベントのy方向の移動量を表示するラベル。 */ | |
@FXML | |
private Label lblDeltaY; | |
/** フォント一覧を表示するリスト。 */ | |
@FXML | |
private ListView<String> lvFonts; | |
/** | |
* タッチテストの領域で発生したタッチ開始イベントのハンドラ。 | |
* タッチ位置にサークルを描画する。 | |
* サークルにはタッチ位置に応じて移動するためのイベントハンドラと、 | |
* ダブルタップ時に消去するためのイベントハンドラを登録する。 | |
* @param event タッチイベント情報 | |
*/ | |
@FXML | |
private void handleTouchStart(TouchEvent event) { | |
if (!(event.getTarget() instanceof Circle)) { | |
circleCount++; | |
final TouchPoint point = event.getTouchPoint(); | |
lblTouchCount.setText(Integer.toString(event.getTouchCount())); | |
lblEventSetId.setText(Integer.toString(event.getEventSetId())); | |
final Circle circle = new Circle(CIRCLE_RADIUS, COLORS[circleCount % 10]); | |
relocateCircle(circle, point.getX(), point.getY()); | |
circle.setOnTouchMoved(new TouchMoveHandler(point.getSceneX(), point.getSceneY())); | |
circle.setOnMouseClicked(new EventHandler<MouseEvent>() { | |
@Override | |
public void handle(MouseEvent event) { | |
if (event.getClickCount() >= 2) { | |
touchPane.getChildren().remove((Node) event.getTarget()); | |
} | |
} | |
}); | |
lblTouchX.setText(Double.toString(point.getX())); | |
lblTouchY.setText(Double.toString(point.getY())); | |
touchPane.getChildren().add(circle); | |
} | |
} | |
/** | |
* クリアボタンクリック時の処理。サークルを全て消去する。 | |
* @param event アクションイベント情報 | |
*/ | |
@FXML | |
private void handleBtnClearAction(ActionEvent event) { | |
touchPane.getChildren().clear(); | |
} | |
/** | |
* 四角形に対するズームイベントの処理。ズーム倍率に合わせて四角形のスケールを変更する。 | |
* @param event ズームイベント情報 | |
*/ | |
@FXML | |
private void handleRectangleZoom(ZoomEvent event) { | |
double totalScale = event.getZoomFactor() * rectangle.getScaleX(); | |
rectangle.setScaleX(totalScale); | |
rectangle.setScaleY(totalScale); | |
lblFactor.setText(Integer.toString((int) (totalScale * 100))); | |
event.consume(); | |
} | |
/** | |
* 四角形に対するローテーションイベントの処理。回転に合わせて四角形を回転する。 | |
* @param event ローテーションイベント情報 | |
*/ | |
@FXML | |
private void handleRectangleRotation(RotateEvent event) { | |
double totalAngle = event.getAngle() + rectangle.getRotate(); | |
rectangle.setRotate(totalAngle); | |
lblAngle.setText(Integer.toString((int) totalAngle)); | |
event.consume(); | |
} | |
/** | |
* 四角形に対するスクロールイベントの処理。スクロール方向に合わせて移動する。 | |
* @param event スクロールイベント情報 | |
*/ | |
@FXML | |
private void handleRectangleScroll(ScrollEvent event) { | |
if (!event.isInertia()) { | |
double totalDeltaX = rectangle.getTranslateX() + event.getDeltaX(); | |
double totalDeltaY = rectangle.getTranslateY() + event.getDeltaY(); | |
rectangle.setTranslateX(totalDeltaX); | |
rectangle.setTranslateY(totalDeltaY); | |
lblDeltaX.setText(Integer.toString((int) totalDeltaX)); | |
lblDeltaY.setText(Integer.toString((int) totalDeltaY)); | |
} | |
event.consume(); | |
} | |
/** | |
* コントローラーの初期処理。 | |
* システムがサポートするフォントを取得し、ページネーションコントロールとリストに設定する。 | |
* @param url FXMLのロケーション | |
* @param rb リソースバンドル | |
*/ | |
@Override | |
public void initialize(URL url, ResourceBundle rb) { | |
fonts = Font.getFamilies(); | |
pagination.setPageCount(fonts.size() / FONTS_PER_PAGE); | |
pagination.setPageFactory(new Callback<Integer, Node>() { | |
@Override | |
public Node call(Integer idx) { | |
return createPage(idx); | |
} | |
}); | |
lvFonts.setItems(FXCollections.observableArrayList(fonts)); | |
} | |
/** | |
* サークルの位置を変更する。 | |
* @param circle 対象となるサークル | |
* @param sceneX サークルのシーングラフ上におけるx座標 | |
* @param sceneY サークルのシーングラフ上におけるy座標 | |
*/ | |
private void relocateCircle(final Circle circle, double sceneX, double sceneY) { | |
circle.relocate(sceneX - CIRCLE_RADIUS, sceneY - CIRCLE_RADIUS); | |
} | |
/** | |
* ページネーションコントロールに表示するページを生成する。 | |
* @param idx ページインデックス | |
* @return ページネーションコントロールに表示するページ | |
*/ | |
private VBox createPage(int idx) { | |
VBox box = new VBox(5.0); | |
int page = idx * FONTS_PER_PAGE; | |
for (int i = page; i < page + FONTS_PER_PAGE; i++) { | |
Label lblFont = new Label(fonts.get(i)); | |
box.getChildren().add(lblFont); | |
} | |
return box; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment