JavaFX技巧20:有很多需要展示的地方吗? 使用画布!
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                JavaFX技巧20:有很多需要展示的地方吗? 使用画布!
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                JavaFX應用程序似乎有兩種:第一種使用帶有節點和CSS樣式的場景圖,第二種使用單個畫布。 但是,將這兩種方法混合使用是完全合法的。 尤其是當您的應用程序必須顯示大量詳細信息時,您很容易最終創建成千上萬個節點。 即使JavaFX的整體性能非常出色,當所有這些節點都需要樣式設置時(特別是由于可視化的動態性質而需要反復進行樣式設置時),您很有可能會使系統崩潰。
對我來說,這是一個頓悟,當我意識到在FlexGanttFX中保證高性能的唯一方法是對每個包含畫布的單元使用ListView。 不幸的是,該框架的代碼太復雜,無法在一個小博客中與您共享。因此,我寫了一個小例子來說明基本概念。 下圖顯示了運行示例時的結果。 ListView顯示的數據涵蓋了我生命中的歲月,并且每年的每一天都有隨機生成的值。
最重要的類稱為CanvasCell 。 它是一個專門的列表視圖單元,其中包含標簽和畫布。 標簽用于顯示年份,畫布用于繪制圖表。
import java.util.Collections; import java.util.List;import javafx.geometry.Pos; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.ContentDisplay; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.CycleMethod; import javafx.scene.paint.LinearGradient; import javafx.scene.paint.Stop;public class CanvasCell extends ListCell<YearEntry> {private Label yearLabel;private ResizableCanvas canvas;public CanvasCell() {/** Important, otherwise we will keep seeing a horizontal scrollbar.*/setStyle("-fx-padding: 0px;");yearLabel = new Label();yearLabel.setStyle("-fx-padding: 10px; -fx-font-size: 1.2em; -fx-font-weight: bold;");StackPane.setAlignment(yearLabel, Pos.TOP_LEFT);/** Create a resizable canvas and bind its width and height to the width* and height of the table cell.*/canvas = new ResizableCanvas();canvas.widthProperty().bind(widthProperty());canvas.heightProperty().bind(heightProperty());StackPane pane = new StackPane();pane.getChildren().addAll(yearLabel, canvas);setGraphic(pane);setContentDisplay(ContentDisplay.GRAPHIC_ONLY);}@Overrideprotected void updateItem(YearEntry entry, boolean empty) {if (empty || entry == null) {yearLabel.setText("");canvas.setData(Collections.emptyList());canvas.draw();} else {yearLabel.setText(Integer.toString(entry.getYear()));canvas.setData(entry.getValues());canvas.draw();}}/** Canvas is normally not resizable but by overriding isResizable() and* binding its width and height to the width and height of the cell it will* automatically resize.*/class ResizableCanvas extends Canvas {private List<Double> data = Collections.emptyList();public ResizableCanvas() {/** Make sure the canvas draws its content again when its size* changes.*/widthProperty().addListener(it -> draw());heightProperty().addListener(it -> draw());}@Overridepublic boolean isResizable() {return true;}@Overridepublic double prefWidth(double height) {return getWidth();}@Overridepublic double prefHeight(double width) {return getHeight();}public void setData(List<Double> data) {this.data = data;}/** Draw a chart based on the data provided by the model.*/private void draw() {GraphicsContext gc = getGraphicsContext2D();gc.clearRect(0, 0, getWidth(), getHeight());Stop[] stops = new Stop[] { new Stop(0, Color.SKYBLUE),new Stop(1, Color.SKYBLUE.darker().darker()) };LinearGradient gradient = new LinearGradient(0, 0, 0, 300, false,CycleMethod.NO_CYCLE, stops);gc.setFill(gradient);double availableHeight = getHeight() * .8;double counter = 0;for (Double value : data) {double x = getWidth() / 365 * counter;double barHeight = availableHeight * value / 100;double barWidth = getWidth() / 365 + 1;gc.fillRect(x, getHeight() - barHeight, barWidth, barHeight);counter++;}}} }對于數據,我們使用一個非常簡單的類來存儲年份和值列表。
import java.util.ArrayList; import java.util.List;/*** Just some fake model object.*/ public class YearEntry {private int year;public YearEntry(int year) {this.year = year;}public int getYear() {return year;}private List<Double> values = new ArrayList<>();/*** Stores the values shown in the chart.*/public List<Double> getValues() {return values;} }以下清單顯示了主類。
import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.control.ListView; import javafx.stage.Stage;public class CanvasApp extends Application {@Overridepublic void start(Stage stage) throws Exception {/** Create some random data for my life span.*/ObservableList<YearEntry> data = FXCollections.observableArrayList();for (int year = 1969; year < 2015; year++) {YearEntry entry = new YearEntry(year);for (int day = 0; day < 365; day++) {entry.getValues().add(Math.random() * 100);}data.add(entry);}ListView<YearEntry> listView = new ListView<>(data);listView.setCellFactory(param -> new CanvasCell());listView.setFixedCellSize(200);Scene scene = new Scene(listView);stage.setTitle("Canvas Cell");stage.setScene(scene);stage.setWidth(600);stage.setHeight(600);stage.show();}public static void main(String[] args) {launch(args);} }翻譯自: https://www.javacodegeeks.com/2015/06/javafx-tip-20-a-lot-to-show-use-canvas.html
總結
以上是生活随笔為你收集整理的JavaFX技巧20:有很多需要展示的地方吗? 使用画布!的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: pscs3使用快捷键(pscs3快捷键常
- 下一篇: Wildfly,Apache CXF和@
