Skip to content

Instantly share code, notes, and snippets.

@aoetk
Created December 6, 2013 16:15
Show Gist options
  • Save aoetk/7827455 to your computer and use it in GitHub Desktop.
Save aoetk/7827455 to your computer and use it in GitHub Desktop.
JavaFX Advent Calendar 2013 の 7 日目のエントリ、「ListViewやTableViewのセルをカスタマイズする方法」のソースコードです。
package aoetk;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import java.util.List;
/**
* ブックマークを表示するカスタムのセル.
*/
public class BookmarkCell extends ListCell<BookmarkModel> {
private VBox cellContainer;
private Text txtTitle;
private Text txtComment;
private HBox tagContainer;
private boolean bound = false;
/**
* コンストラクタ.
* 初期化時に表示するNodeのインスタンスを生成しておく.
*/
public BookmarkCell() {
initComponent();
initStyle();
}
private void initStyle() {
txtTitle.setFont(new Font("System Bold", 18.0));
}
private void initComponent() {
cellContainer = new VBox(5);
txtTitle = new Text();
VBox.setVgrow(txtTitle, Priority.NEVER);
txtComment = new Text();
VBox.setVgrow(txtComment, Priority.ALWAYS);
tagContainer = new HBox();
VBox.setVgrow(tagContainer, Priority.NEVER);
cellContainer.getChildren().addAll(txtTitle, txtComment, tagContainer);
}
@Override
protected void updateItem(BookmarkModel bookmarkModel, boolean empty) {
super.updateItem(bookmarkModel, empty);
if (!bound) {
txtTitle.wrappingWidthProperty().bind(getListView().widthProperty().subtract(25));
txtComment.wrappingWidthProperty().bind(getListView().widthProperty().subtract(25));
bound = true;
}
if (empty) {
setText(null);
setGraphic(null);
} else {
txtTitle.setText(bookmarkModel.titleProperty().get());
txtComment.setText(bookmarkModel.commentProperty().get());
tagContainer.getChildren().clear();
List<String> tags = bookmarkModel.getTagList();
for (String tagName : tags) {
tagContainer.getChildren().add(createTagLink(tagName));
}
setGraphic(cellContainer);
}
}
private Hyperlink createTagLink(String tagName) {
Hyperlink hyperlink = new Hyperlink(tagName);
hyperlink.setTextFill(Color.BLUE);
return hyperlink;
}
}
package aoetk;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.List;
/**
* ブックマークを表すモデル.
*/
public class BookmarkModel {
private StringProperty title = new SimpleStringProperty();
private StringProperty comment = new SimpleStringProperty();
private ObservableList<String> tagList = FXCollections.observableArrayList();
/**
* コンストラクタ.
*
* @param title タイトル
* @param comment コメント
* @param tagList タグのリスト
*/
public BookmarkModel(String title, String comment, List<String> tagList) {
this.title.set(title);
this.comment.set(comment);
this.tagList.addAll(tagList);
}
/**
* タイトル.
*
* @return タイトル
*/
public StringProperty titleProperty() {
return title;
}
/**
* コメント.
*
* @return コメント
*/
public StringProperty commentProperty() {
return comment;
}
/**
* タグのリストを取得する.
*
* @return タグのリスト
*/
public ObservableList<String> getTagList() {
return tagList;
}
}
package aoetk;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* カスタムのセルを使ったListViewのサンプルアプリケーション.
*/
public class CustomCellSampleApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("SampleListView.fxml"));
primaryStage.setTitle("Custom Cell Sample");
primaryStage.setScene(new Scene(root, 460, 700));
primaryStage.show();
}
/**
* アプリケーション起動メソッド.
*
* @param args 起動引数
*/
public static void main(String[] args) {
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="460.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="aoetk.SampleListViewController">
<center>
<ListView fx:id="listView" prefHeight="200.0" prefWidth="200.0" />
</center>
</BorderPane>
package aoetk;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;
import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
/**
* SampleListViewのコントローラ.
*/
public class SampleListViewController implements Initializable {
public ListView<BookmarkModel> listView;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
listView.setCellFactory(new Callback<ListView<BookmarkModel>, ListCell<BookmarkModel>>() {
@Override
public ListCell<BookmarkModel> call(ListView<BookmarkModel> listView) {
return new BookmarkCell();
}
});
ObservableList<BookmarkModel> bookmarkModels = createBookmarkModels();
listView.setItems(bookmarkModels);
}
private ObservableList<BookmarkModel> createBookmarkModels() {
final String longComment = "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。"
+ "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。"
+ "長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。長いコメントのサンプルです。";
final String normalComment = "普通の長さのコメント。";
ObservableList<BookmarkModel> bookmarkModels = FXCollections.observableArrayList();
for (int i = 0; i < 500; i++) {
String comment = "";
if (i % 3 == 0) {
comment = longComment;
} else if (i % 3 == 1) {
comment = normalComment;
}
BookmarkModel model = new BookmarkModel(
"ブックマークタイトル" + i, comment, Arrays.asList("tag1", "tag2", "tag3"));
bookmarkModels.add(model);
}
return bookmarkModels;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment