自定义组合框,JavaFX中居中的文本

时间:2018-08-18 02:44:56

标签: javafx combobox text-alignment

我想使组合框按钮单元格中的文本居中对齐,并使其成为默认行为。创建组合框对象后,我已经知道该怎么做。我如何在combobox的派生类中实现该方法?

box.setButtonCell(new ListCell<String>() {
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null) {
            setText(item);
            setAlignment(Pos.CENTER_RIGHT);
            Insets old = getPadding();
            setPadding(new Insets(old.getTop(), 0, old.getBottom(), 0));
        }
    }
});

2 个答案:

答案 0 :(得分:3)

当然,您可以将代码(将this替换为.combo-box>.list-cell { -fx-alignment: center; } )到类的构造函数中(或将其放在初始化程序块中)。

但是,当CSS轻松允许您这样做时,为什么要创建一个子类:

将以下样式表添加到场景中

ComboBox

如果您希望能够针对单个ComboBox更改此行为,则只需添加一种方法即可使用css选择器将居中的comboBox.getStyleClass().add("center-aligned"); 区别于其他{一个班级

java代码

.combo-box.center-aligned>.list-cell {
    -fx-alignment: center;
}

CSS

@Override
public void start(Stage primaryStage) {
    ComboBox<String> combo = new ComboBox<>();

    PseudoClass centerAligned = PseudoClass.getPseudoClass("center-aligned");
    combo.pseudoClassStateChanged(centerAligned, true);
    combo.getSelectionModel().selectedIndexProperty().addListener((o, oldValue, newValue)
            -> combo.pseudoClassStateChanged(centerAligned, newValue.intValue() % 2 == 0));

    for (int i = 0; i < 5; i++) {
        combo.getItems().add("item " + i);
    }
    combo.setValue("item 0");
    combo.setMaxWidth(Double.MAX_VALUE);

    VBox root = new VBox(combo);
    root.setFillWidth(true);
    root.setPrefWidth(300);
    Scene scene = new Scene(root);
    scene.getStylesheets().add("style.css");
    primaryStage.setScene(scene);
    primaryStage.show();
}

使用伪类将使您能够更轻松地切换行为。以下代码中心将每个项目按偶数索引对齐:

.combo-box:center-aligned>.list-cell {
    -fx-alignment: center;
}

style.css

import matplotlib.pyplot as plt
import numpy as np
import wave

file = 'test.wav'

wav_file = wave.open(file,'r')

#Extract Raw Audio from Wav File
signal = wav_file.readframes(-1)
if wav_file.getsampwidth() == 1:
    signal = np.array(np.frombuffer(signal, dtype='UInt8')-128, dtype='Int8')
elif wav_file.getsampwidth() == 2:
    signal = np.frombuffer(signal, dtype='Int16')
else:
    raise RuntimeError("Unsupported sample width")

# http://schlameel.com/2017/06/09/interleaving-and-de-interleaving-data-with-python/
deinterleaved = [signal[idx::wav_file.getnchannels()] for idx in range(wav_file.getnchannels())]

#Get time from indices
fs = wav_file.getframerate()
Time=np.linspace(0, len(signal)/wav_file.getnchannels()/fs, num=len(signal)/wav_file.getnchannels())

#Plot
plt.figure(1)
plt.title('Signal Wave...')
for channel in deinterleaved:
    plt.plot(Time,channel)
plt.show()

答案 1 :(得分:0)

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;

public class CustomComboBox<T> extends ComboBox<T> {

    public CustomComboBox() {
        super();
    }

    public CustomComboBox(ObservableList<T> items) {
        super(items);
    }

    public BooleanProperty centeredProperty() { return centered; }
    public final void setCentered(boolean value) { centeredProperty().set(value); }
    public final boolean isCentered() { return centeredProperty().get(); }
    private BooleanProperty centered = new SimpleBooleanProperty(this, "centered", false) {

        private ListCell<T> originalBttonCell =  getButtonCell();

        @Override 
        protected void invalidated() {
            if(get()) {
                setButtonCell(new ListCell<T>() {
                    @Override
                    public void updateItem(T item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null) {
                            setText(item.toString());
                            setAlignment(Pos.CENTER_RIGHT);
                            Insets old = getPadding();
                            setPadding(new Insets(old.getTop(), 0, old.getBottom(), 0));
                        }
                    }
                });
            }
            else {
                setButtonCell(originalBttonCell);
            }
        }
    };

}

用法

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class CustomComboBoxTest extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox p = new VBox();

        CustomComboBox<String> box = new CustomComboBox<>(FXCollections.observableArrayList("Item 1", "Item 2", "Item 3"));
        box.setValue("Item 2");

        Button b = new Button("Change centered");
        b.setOnAction( e -> {box.setCentered(!box.isCentered());});

        p.getChildren().addAll(box, b);

        Scene scene = new Scene(p);

        primaryStage.setScene(scene);

        primaryStage.setWidth(300);
        primaryStage.setHeight(200);

        primaryStage.show();

    }

}