谁能告诉我为什么运行jar应用程序时下拉列表中的某些项目不可见?这似乎是随机发生的。我创建了一个ObservableList,然后递归创建了Line,并通过String作为line.setStyle(“-fx-stroke-dash-array:” + dashString +“;”)从可观察列表中为其指定笔划类型。最后,一切正常,ComboBox会获得整个行列表和特定选择。但有时有时无法在下拉列表中显示行。代码是:
package test;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class ComboLines extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
ComboBox<Line> dashCombo = new ComboBox<>();
initDashLineCombo(dashCombo, dashUnit, 2);
dashCombo.getStylesheets().add("test/style.css");
dashCombo.setStyle("-fx-min-width: 100; -fx-max-width: 100; -fx-pref-width: 100; -fx-min-height: 15; -fx-pref-height: 15; -fx-max-height: 15;");
StackPane root = new StackPane();
root.getChildren().add(dashCombo);
primaryStage.setScene(new Scene(root, 150, 300));
primaryStage.show();
}
public static void initDashLineCombo(ComboBox<Line> cb, ObservableList<int[]> list, int i)
{
ArrayList<Line> LinesList = new ArrayList<>(); // to store lines
// cycle over the list and generate a line with dashing defined by list
for(int j = 0; j < list.size(); j++)
{
int sum = 0;
int[] dash = list.get(j);
String dashString = " ";
for(int k : dash) // cycle over an int array which defines the dashing
{ dashString += k + " ";
sum += k; }
System.out.println("sum = " + sum);
Line line = new Line(15, 0, 1*(15+sum), 0);
System.out.print("\ndashString :" + dashString);
// apply style
line.setStrokeWidth(2);// line width
line.setStroke(Color.BLACK);
line.setStyle("-fx-stroke-dash-array:" + dashString + ";"); // line dashing
LinesList.add(line); // collect the line
}
// create the observable list
final ObservableList<Line> LinesObs = FXCollections.observableArrayList(LinesList);
// set all line items in the combo box
cb.setItems(LinesObs);
// select an item ion the combo box
cb.setValue(LinesObs.get(i-1));
}
// ... dashing ...
int[] s10 = {1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,};
int[] s9 = {1,3,1,3,1,4,5,4,5,4, 1,3,1,3,1,4,5,4,5,4};
int[] s8 = {6,3,6,3,6,5,1,5, 6,3,6,3,6,5,1,5};
int[] s7 = {1,3,1,3,1,6,6,6, 1,3,1,3,1,6,6,6};
int[] s6 = {5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3};
int[] s5 = {5, 4, 5, 4, 1, 3, 1, 4, 5, 4, 5, 4, 1, 3, 1, 4};
int[] s4 = {5, 4, 1, 3, 1, 4, 5, 4, 1, 3, 1, 4, 5, 4, 1, 3, 1, 4};
int[] s3 = {5, 3, 1, 3, 5, 3, 1, 3, 5, 3, 1, 3, 5, 3, 1, 3};
int[] s2 = {15, 3, 15, 3, 15, 3};
int[] s1 = {60};
final ObservableList<int[]> dashUnit = FXCollections.observableArrayList(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
}
/* style.css */
.combo-box {
-fx-min-width: 35;
-fx-pref-width: 35;
-fx-max-width: 35;
-fx-min-height: 20;
-fx-pref-height: 20;
-fx-max-height: 20;
-fx-padding: -2 -8 -2 -5;
}
.combo-box-base > .arrow-button {
-fx-background-radius: 0 3 3 0, 0 2 2 0, 0 1 1 0;
-fx-background-color: transparent;
-fx-alignment: center-left;
}
.combo-box .cell {
-fx-font-size: 8.75pt;
-fx-font-family: "Arial";
-fx-text-fill: BLACK;
-fx-alignment: BASELINE_RIGHT;
-fx-padding: 0 3 0 -5;
}
更新:使用cell factory的简化版本(不使用CSS且不使用破折号)是这样的。相同的问题仍然存在,并且进一步,我无法应用初始选择。
package test;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboLines extends Application
{
public static void main(String[] args) { launch(args); }
ComboBox<Line> dashCombo = new ComboBox<>();
@Override
public void start(Stage primaryStage)
{
StackPane root = new StackPane();
root.getChildren().add(dashCombo);
dashCombo.setItems(FXCollections.observableList(DASHUNIT));
dashCombo.getSelectionModel().selectFirst();
dashCombo.setCellFactory(new Callback<ListView<Line>, ListCell<Line>>()
{
@Override
public ListCell<Line> call(ListView<Line> newLine)
{
return new ListCell<Line>()
{
@Override
protected void updateItem(Line item, boolean y)
{
super.updateItem(item, false);
setGraphic(item);
} // end updateItem
} ; // end new ListCell
} // end call()
}); // end setCellFactory
primaryStage.setScene(new Scene(root, 150, 300));
primaryStage.show();
}
Line line1 = new Line(15, 0, 50, 0), line2 = new Line(15, 0, 50, 0), line3 = new Line(15, 0, 50, 0);
final ObservableList<Line> DASHUNIT = FXCollections.observableArrayList(line1, line2, line3);
}
最后,我将其与下面的代码一起使用。根据kleopatra的评论,同伙来自Oracle官方页面https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/ComboBox.html
ComboBox<Line> dashCombo = new ComboBox<>();
dashCombo.getStylesheets().add("style.css");
dashCombo.setStyle("-fx-min-width: 100; -fx-max-width: 100; -fx-pref-width: 100; "
+ "-fx-min-height: 15; -fx-pref-height: 15; -fx-max-height: 15;");
initDashLineCombo(dashCombo, common.General.DASHUNIT, (numberCoils - i), colCombo);
public static void initDashLineCombo(ComboBox<Line> cb, ObservableList<int[]> list, int i, ColorPicker cp)
{
for(int j = 0; j < list.size(); j++) // cycle over the list and generate a line with dashing defined by list
{
int[] dash = list.get(j);
String dashString = " ";
for(int k : dash)
dashString += k + " ";
Line line = new Line(25, 0, 95, 0);
line.setStrokeWidth(2); line.strokeProperty().bind(cp.valueProperty());
line.setStyle("-fx-stroke-dash-array:" + dashString + ";");
cb.getItems().add(line);
}
cb.getSelectionModel().clearAndSelect(i-1);
cb.setCellFactory(new Callback<ListView<Line>, ListCell<Line>>()
{
@Override public ListCell<Line> call(ListView<Line> p)
{
return new ListCell<Line>() {
private final Line line;
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
line = new Line(0, 0, 70, 0);
line.setStrokeWidth(2);
line.strokeProperty().bind(cp.valueProperty());
} // end Line
@Override protected void updateItem(Line item, boolean empty)
{
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
}
else {
line.setStyle(item.getStyle());
setGraphic(line);
setItem(line);
}
} // end updateItem()
}; // end ListCell
} // end call()
}); // end setCellFactory
}