Java 具有彩色形状的 FX 组合框
Java FX ComboBox with coloured shapes
我想添加两个或更多圆圈作为组合框的选项。
Circle c1 = new Circle(10, 8, 5);
Circle c2 = new Circle(24, 8, 5);
圆圈应使用 CSS 样式
单独着色
c1.setStyle("-fx-fill: red;");
c2.setStyle("-fx-fill: green;");
或直接使用 Java 语法
c1.setFill(Color.RED);
c2.setFill(Color.GREEN);
我的问题是 setGraphic()
方法将单个 Node
对象作为参数,要形成这个 Node
对象,需要一个布尔运算,例如 Shape.union(c1, c2)
。但这消除了之前应用的样式,所以我得到的不是红色和绿色 Circle
,而是黑色。
下面是最小的例子。所有代码都可以放在一个 .java
文件中
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.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Test extends Application {
public static ObservableList<String> colours = FXCollections.observableArrayList("1", "2");
@Override
public void start(Stage primaryStage) throws Exception {
ComboBox comboBox = new ComboBox();
comboBox.setItems(colours);
comboBox.setCellFactory(new gui.combos.ColourCellFactory());
comboBox.setButtonCell(new gui.combos.ColourCell());
HBox hbox = new HBox(comboBox);
Scene scene = new Scene(hbox, 200, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
class ColourCell extends ListCell<String> {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
}
else {
setText(item);
Shape shapes = this.getShapes(item);
setGraphic(shapes);
}
}
public Shape getShapes(String string) {
Shape shapes = null;
switch (string) {
case "1":
Circle c = new Circle(10, 8,5); c.setStyle("-fx-fill: red;");
shapes = c;
break;
case "2":
Circle c1 = new Circle(10, 8,5); c1.setFill(Color.RED);
Circle c2 = new Circle(24, 8,5); c2.setFill(Color.GREEN);
shapes = Shape.union(c1, c2);
break;
default:
shapes = null;
}
return shapes;
}
}
class ColourCellFactory implements Callback<ListView<String>, ListCell<String>> {
@Override
public ListCell<String> call(ListView<String> listview) {
return new gui.combos.ColourCell();
}
}
如果能知道如何克服这种不便,我们将不胜感激。谢谢。
形状的并集将创建一个单一的形状。组成联合形状的元素不能独立设置样式。
正如 James_D 在评论中建议的那样,不要合并形状,而是使用父容器,例如 Group 或 HBox。
下面的示例演示了对图形使用 HBox,它允许图形内容由布局窗格管理,而不需要手动布局。
import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import java.util.List;
public class ShapeCombo extends Application {
public static ObservableList<String> colours = FXCollections.observableArrayList(
"1", "2"
);
@Override
public void start(Stage stage) throws Exception {
ComboBox<String> comboBox = new ComboBox<>(colours);
comboBox.setCellFactory(listView -> new ColourCell());
comboBox.setButtonCell(new ColourCell());
Scene scene = new Scene(new HBox(comboBox), 200, 120);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class ColourCell extends ListCell<String> {
private HBox graphicContent = new HBox(6);
public ColourCell() {
graphicContent.setPadding(new Insets(2, 3, 2, 3));
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
setText(item);
graphicContent.getChildren().setAll(
getShapes(item)
);
setGraphic(graphicContent);
}
}
public List<Shape> getShapes(String string) {
return switch (string) {
case "1" -> List.of(
new Circle(5, Color.RED)
);
case "2" -> List.of(
new Circle(5, Color.RED),
new Circle(5, Color.GREEN)
);
default -> List.of();
};
}
}
我想添加两个或更多圆圈作为组合框的选项。
Circle c1 = new Circle(10, 8, 5);
Circle c2 = new Circle(24, 8, 5);
圆圈应使用 CSS 样式
单独着色c1.setStyle("-fx-fill: red;");
c2.setStyle("-fx-fill: green;");
或直接使用 Java 语法
c1.setFill(Color.RED);
c2.setFill(Color.GREEN);
我的问题是 setGraphic()
方法将单个 Node
对象作为参数,要形成这个 Node
对象,需要一个布尔运算,例如 Shape.union(c1, c2)
。但这消除了之前应用的样式,所以我得到的不是红色和绿色 Circle
,而是黑色。
下面是最小的例子。所有代码都可以放在一个 .java
文件中
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.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Test extends Application {
public static ObservableList<String> colours = FXCollections.observableArrayList("1", "2");
@Override
public void start(Stage primaryStage) throws Exception {
ComboBox comboBox = new ComboBox();
comboBox.setItems(colours);
comboBox.setCellFactory(new gui.combos.ColourCellFactory());
comboBox.setButtonCell(new gui.combos.ColourCell());
HBox hbox = new HBox(comboBox);
Scene scene = new Scene(hbox, 200, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
class ColourCell extends ListCell<String> {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
}
else {
setText(item);
Shape shapes = this.getShapes(item);
setGraphic(shapes);
}
}
public Shape getShapes(String string) {
Shape shapes = null;
switch (string) {
case "1":
Circle c = new Circle(10, 8,5); c.setStyle("-fx-fill: red;");
shapes = c;
break;
case "2":
Circle c1 = new Circle(10, 8,5); c1.setFill(Color.RED);
Circle c2 = new Circle(24, 8,5); c2.setFill(Color.GREEN);
shapes = Shape.union(c1, c2);
break;
default:
shapes = null;
}
return shapes;
}
}
class ColourCellFactory implements Callback<ListView<String>, ListCell<String>> {
@Override
public ListCell<String> call(ListView<String> listview) {
return new gui.combos.ColourCell();
}
}
如果能知道如何克服这种不便,我们将不胜感激。谢谢。
形状的并集将创建一个单一的形状。组成联合形状的元素不能独立设置样式。
正如 James_D 在评论中建议的那样,不要合并形状,而是使用父容器,例如 Group 或 HBox。
下面的示例演示了对图形使用 HBox,它允许图形内容由布局窗格管理,而不需要手动布局。
import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import java.util.List;
public class ShapeCombo extends Application {
public static ObservableList<String> colours = FXCollections.observableArrayList(
"1", "2"
);
@Override
public void start(Stage stage) throws Exception {
ComboBox<String> comboBox = new ComboBox<>(colours);
comboBox.setCellFactory(listView -> new ColourCell());
comboBox.setButtonCell(new ColourCell());
Scene scene = new Scene(new HBox(comboBox), 200, 120);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class ColourCell extends ListCell<String> {
private HBox graphicContent = new HBox(6);
public ColourCell() {
graphicContent.setPadding(new Insets(2, 3, 2, 3));
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
setText(item);
graphicContent.getChildren().setAll(
getShapes(item)
);
setGraphic(graphicContent);
}
}
public List<Shape> getShapes(String string) {
return switch (string) {
case "1" -> List.of(
new Circle(5, Color.RED)
);
case "2" -> List.of(
new Circle(5, Color.RED),
new Circle(5, Color.GREEN)
);
default -> List.of();
};
}
}