Excelのデータバー(以下参照)のような表示をTableViewで実装したいです。
http://www.becoolusers.com/excel/data-bar.html
そこで、TableColumを以下のようにしてみましたが
・テキストとデータバーを一緒に表示できない
・TableColumnの幅を変更してもデータバーの幅が追従しない
という問題に直面しています。
解決方法についてどうかよろしくお願いいたします。
(TableColumn).setCellFactory(tableColumn -> new TableCell<Sample, Double>() { //HBoxを配置し、その幅でバーを表したい private HBox box = new HBox(); { double width = (TableColumn).getWidth();//項目の最大幅を取得 double rate = 0.6;//データバーの表示割合(今回は60%で固定、本来はこのカラムに設定されたDoubleを用いたい) box.setMaxWidth(width * rate);//幅設定 } @Override protected void updateItem(Double value, boolean empty) { super.updateItem(value, empty); setText(null); if (value == null || empty) { setGraphic(null); } else { box.setBackground(new Background(new BackgroundFill(value, null, null))); setGraphic(box);//データバーを表示したい setText("60%");//テキストを表示したい、本来はDoubleの値を使用 } } });
*その後
回答を参考に、以下のようにしておおよその実装はできましたが、まだうまくいっていない点があります。
・カラム幅を変更しないとデータバーが表示されない。(初期描画時点ではデータバーが表示されず)
・カラム幅を画面幅まで広げたあと縮めると、少し広げても30の数字が表示されない。(画面幅まで広げないと表示されない)
・カラム幅を変更してからスクロールすると、一部データバーの長さがおかしい。(カラム幅を変更するとなおる)
いずれも幅変更とスクロールで解決する表示の問題ですが、都度変更しなくてもきれいに表示されるようにすることは可能でしょうか。
よろしくお願いいたします。
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
TableView<DataClass> table = new TableView<DataClass>();
TableColumn<DataClass, Integer> column = new TableColumn<DataClass, Integer>("VALUE");
column.setCellValueFactory(feature -> feature.getValue().getValue().asObject());
column.setPrefWidth(200);
column.setCellFactory(tableColumn -> new TableCell<DataClass, Integer>() {
private AnchorPane pane = new AnchorPane(); //セルに画像として表示するベース
private AnchorPane barArea = new AnchorPane(); //バー領域
private Rectangle bar = new Rectangle(); //バー
private Label label = new Label(); //テキスト領域
{
//label.setPadding(new Insets(3));
barArea.getChildren().addAll(bar);
pane.getChildren().addAll(barArea, label);
AnchorPane.setRightAnchor(label, 0.0);
AnchorPane.setLeftAnchor(barArea, 0.0);
AnchorPane.setRightAnchor(barArea, 30.0); //右30はテキスト領域として固定で空けておく
}
public void updateItem(Integer value, boolean empty) {
super.updateItem(value, empty);
if (value == null || empty) {
setText(null);
} else {
bar.setWidth(barArea.getWidth() * value/30); //幅設定
column.widthProperty().addListener((self, old, val) -> { //幅の変更に合わせてデータバーも変更
bar.setWidth(barArea.getWidth() * value/30); //幅設定
});
bar.setHeight(16); //データバーの高さ
bar.setFill(Paint.valueOf("#8f8f8f8f"));
label.setText(Integer.toString(value)); //ラベルに文字列をセット
label.setStyle("-fx-alignment: center-right;"); //文字列ラベルを右寄せ
setGraphic(pane);
setText(null);
}
}
});
table.getColumns().add(column);
ObservableList<DataClass> dataClassList = FXCollections.observableArrayList();
for (int i = 0; i <= 30; i++){
DataClass data = new DataClass(i);
dataClassList.add(data);
}
table.setItems(dataClassList);
Scene scene = new Scene(table,400,400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class DataClass{ //データクラス
private IntegerProperty value = new SimpleIntegerProperty();
public DataClass(int value){
setValue(value);
}
public IntegerProperty getValue() {
return value;
}
public void setValue(int value) {
this.value.set(value);
}
}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/19 08:41
2017/03/19 09:15