簡體   English   中英

JavaFX中的“會計”樣式表單元

[英]“Accounting” Style Table Cell in JavaFX

有沒有一種方法可以在JavaFX表中創建“會計”樣式單元格? 通過核算,我的意思是在單元格中將美元符號左對齊,並將值右對齊。 這是在Excel中的外觀:

Excel會計單元格格式

這是我到目前為止嘗試過的:

public class PriceTableCell<S> extends TableCell<S, Long>
{
    public PriceTableCell()
    {
        final Label label = new Label("$");
        this.setAlignment(Pos.CENTER_RIGHT);
        this.setContentDisplay(ContentDisplay.LEFT);
        this.setGraphic(label);
    }

    @Override
    protected void updateItem(Long item, boolean empty)
    {
        if (item == null || empty)
        {
            this.setText(null);
            return;
        }

        this.setText(String.format(Locale.ENGLISH, "%,d.%02d", item / 100, Math.abs(item % 100)));
    }
}

不幸的是,我沒有找到一種為圖形和文本設置單獨的對齊方式的方法。 JavaFX呈現了以下內容:

JavaFX嘗試

AnchorPane使用兩個標簽應該可以工作。

(更新:按照@kleopatra的建議,我將DecimalFormat合並到此解決方案中,它將(至少部分地)定位貨幣符號以及小數位數等。這將假定貨幣符號會顯示在貨幣值的左側,這不一定適用於所有貨幣,但是無論如何,該假設在問題中還是有些隱含的。)

public class PriceTableCell<S> extends TableCell<S, Long> {

    private final AnchorPane pane ;
    private final Label valueLabel ;
    // locale-aware currency format to use for formatting
    private DecimalFormat format;

    public PriceTableCell() {
        // grab an instance
        format = (DecimalFormat) NumberFormat.getCurrencyInstance();
        //get the currency symbol
        String symbol = format.getCurrency().getSymbol();
        // replace the currency symbol with an empty string
        DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
        symbols.setCurrencySymbol("");
        format.setDecimalFormatSymbols(symbols);

        Label currencySignLabel = new Label(symbol);
        valueLabel = new Label();
        pane = new AnchorPane(currencySignLabel, valueLabel);
        AnchorPane.setLeftAnchor(currencySignLabel, 0.0);
        AnchorPane.setRightAnchor(valueLabel, 0.0);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }

    @Override
    protected void updateItem(Long price, boolean empty) {
        super.updateItem(price, empty);
        if (empty) {
            setGraphic(null);
        } else {
            // manual formatting 
            //String text = String.format("%,d.%02d", price / 100, Math.abs(price % 100));
            valueLabel.setText(format.format(price));
            setGraphic(pane);
        }
    }
}

這是一個SSCCE:

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Random;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
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.stage.Stage;

public class TableViewWithAccountingStyleCell extends Application {

    public static class PriceTableCell<S> extends TableCell<S, Long> {

        private final AnchorPane pane ;
        private final Label valueLabel ;
        // locale-aware currency format to use for formatting
        private DecimalFormat format;

        public PriceTableCell() {
            // grab an instance
            format = (DecimalFormat) NumberFormat.getCurrencyInstance();
            //get the currency symbol
            String symbol = format.getCurrency().getSymbol();
            // replace the currency symbol with an empty string
            DecimalFormatSymbols symbols = format.getDecimalFormatSymbols();
            symbols.setCurrencySymbol("");
            format.setDecimalFormatSymbols(symbols);

            Label currencySignLabel = new Label(symbol);
            valueLabel = new Label();
            pane = new AnchorPane(currencySignLabel, valueLabel);
            AnchorPane.setLeftAnchor(currencySignLabel, 0.0);
            AnchorPane.setRightAnchor(valueLabel, 0.0);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        }

        @Override
        protected void updateItem(Long price, boolean empty) {
            super.updateItem(price, empty);
            if (empty) {
                setGraphic(null);
            } else {
                // manual formatting 
                //String text = String.format("%,d.%02d", price / 100, Math.abs(price % 100));
                valueLabel.setText(format.format(price));
                setGraphic(pane);
            }
        }
    }

    public static class Item {
        private final StringProperty name = new SimpleStringProperty();
        private final LongProperty price = new SimpleLongProperty();

        public Item(String name, long price) {
            setName(name);
            setPrice(price);
        }

        public StringProperty nameProperty() {
            return name ;
        }

        public final String getName() {
            return nameProperty().get();
        }

        public final void setName(String name) {
            nameProperty().set(name);
        }

        public LongProperty priceProperty() {
            return price ;
        }

        public final long getPrice() {
            return priceProperty().get();
        }

        public final void setPrice(long price) {
            priceProperty().set(price);
        }
    }

    @Override
    public void start(Stage primaryStage) {
        TableView<Item> table = new TableView<>();
        table.getColumns().add(column("Item", Item::nameProperty));
        TableColumn<Item, Long> priceColumn = column("Price", item -> item.priceProperty().asObject());
        priceColumn.setPrefWidth(300);

        priceColumn.setCellFactory(tc -> new PriceTableCell<>());

        table.getColumns().add(priceColumn);


        Random rng = new Random();
        for (int i = 1 ; i <= 20 ; i++) {
            table.getItems().add(new Item("Item "+i, rng.nextInt(1_000_000)));
        }

        Scene scene = new Scene(table);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private <S,T> TableColumn<S,T> column(String name, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> column = new TableColumn<>(name);
        column.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return column ;
    }

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

產生

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM