如何在JAVAFX中自定义组合框

时间:2018-11-09 16:26:24

标签: java javafx javafx-8

我想在JavaFX中重现该组合框 enter image description here

使用swing可以通过一种渲染器来传递HTML代码。

我还没有在JAVAFX中找到一种方法。我看到了cellFactory,但似乎只能处理一行文本。

我尝试使用WebView的observableList。我能够根据需要显示信息,但是从未调用过onAction。我尝试通过设置一个事件和一个侦听器,但是没有任何效果。我分别尝试了下一个示例。

 cbOrderLine.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<WebView>() {

        @Override
        public void changed(ObservableValue<? extends WebView> arg0, WebView arg1, WebView arg2) {
            int uasbdviadn = 0;
            if (arg2 != null) {
                System.out.println("Selected employee: " + arg2.getId() + " " + uasbdviadn);
            }
        }
    });




cbOrderLine.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent ev) {
            int index = cbOrderLine.getSelectionModel().getSelectedIndex();
            initComboBox(index);
        }
    });

这是创建我的虚拟值的代码

private List<WebView> createListFakeOrderLineItem() {

    List<WebView> list = new ArrayList<>();
    list.add(createFakeOrderLineItem(1));
    list.add(createFakeOrderLineItem(2));
    list.add(createFakeOrderLineItem(3));
    list.add(createFakeOrderLineItem(4));
    return list;
}

private WebView createFakeOrderLineItem(int id) {
    WebView wv = new WebView();
    wv.setPrefSize(684, 90);
    ProductionOrderHeader header = new ProductionOrderHeader();
    header.setPoNumber("PONumber1234");

    ProductionOrderLine line = new ProductionOrderLine();
    line.setId(3333);

    ManufactureProduct product = new ManufactureProduct();
    product.setId(1111);
    product.setPartNumber("Product.PartNumber1111");

    ManufacturePart part = new ManufacturePart();
    part.setId(9999);
    part.setPartNumber("Part.Partnumber9999");
    part.setHardwareId(666666);
    part.setHardwareName("Hardware Name");

    OrderLineItem item = new OrderLineItem(id, header, line, part, product);
    // return item;
    wv.getEngine().loadContent(item.toString());
    return wv;
}

这是我的OrderLineItem

public class OrderLineItem {

Integer index;

ProductionOrderHeader header;

ProductionOrderLine line;

ManufacturePart part;

ManufactureProduct product;

public OrderLineItem(Integer index, ProductionOrderHeader header, ProductionOrderLine line, ManufacturePart part,
        ManufactureProduct product) {
    this.index = index;
    this.header = header;
    this.line = line;
    this.part = part;
    this.product = product;
}

public Integer getIndex() {
    return index;
}

public void setIndex(Integer index) {
    this.index = index;
}

public ProductionOrderHeader getHeader() {
    return header;
}

public void setHeader(ProductionOrderHeader order) {
    this.header = order;
}

public ProductionOrderLine getLine() {
    return line;
}

public void setLine(ProductionOrderLine orderLine) {
    this.line = orderLine;
}

public ManufacturePart getPart() {
    return part;
}

public void setPart(ManufacturePart part) {
    this.part = part;
}

public ManufactureProduct getProduct() {
    return product;
}

public void setProduct(ManufactureProduct product) {
    this.product = product;
}

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("<html>");
    sb.append("<table>");
    sb.append("<tr>");
    sb.append("<td valign=\"middle\" style=\"font-size: 32px; padding-right:5px;\">");
    sb.append((index + 1));
    sb.append("</td>");
    sb.append("<td style=\"border: 1px solid #919191; width:616px; font-size:12px; padding:10px;\">");
    sb.append("<b>");
    sb.append(header.getPoNumber());
    sb.append(" [");
    sb.append(line.getId());
    sb.append("] </b> -");
    sb.append("<b>P/N: </b> #");
    sb.append(product.getId());

    sb.append("<b> ");
    sb.append(product.getPartNumber());
    sb.append("</b><br/>");
    sb.append("Part: # ");
    sb.append(part.getId());
    sb.append("<b> ");
    sb.append(part.getPartNumber());
    sb.append("</b> H/W: # ");
    sb.append(part.getHardwareId());
    sb.append("<b> ");
    sb.append(part.getHardwareName());
    sb.append("</b>");

    sb.append("</td>");
    sb.append("</tr>");
    sb.append("</table>");
    sb.append("</html>");

    return sb.toString();
}

} 我正在使用JAVAFX 8。

谢谢

1 个答案:

答案 0 :(得分:1)

  

我看到了cellFactory,但它似乎只能处理一行文本。

首先,您对cellFactory的理解是错误的。并且将WebView设置为您的comboBox项确实是一个可怕的想法:)。相反,您可以构建简单的布局并将其设置为单元工厂中的图形。

顺便说一句,从不设置节点作为控件(ComboBox,ListView..etc)的项,您只需传递模型并在cellFactories中构建适当的布局即可。

下面是一个快速演示,可让您了解如何构建所需的comboBox。希望这可以帮助您更好地理解。

enter image description here

    import javafx.application.Application;
    import javafx.beans.property.IntegerProperty;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListCell;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;

    public class MultiLineComboBoxDemo extends Application {

        @Override
        public void start(Stage stage) throws Exception {
            VBox root = new VBox();
            root.setSpacing(15);
            root.setPadding(new Insets(25));
            root.setAlignment(Pos.TOP_LEFT);
            Scene sc = new Scene(root, 600, 600);
            stage.setScene(sc);
            stage.show();

            final ObservableList<Person> items = FXCollections.observableArrayList();
            for (int i = 1; i < 4; i++) {
                items.add(new Person(i,"Name " + i, i + 30, "email" + i + "@test.com"));
            }

            final ComboBox<Person> comboBox = new ComboBox<>();
            comboBox.setItems(items);
            comboBox.setCellFactory(param -> new ListCell<Person>() {
                @Override
                protected void updateItem(Person item, boolean empty) {
                    super.updateItem(item, empty);
                    if (!empty) {
                        setGraphic(buildLayout(item));
                    } else {
                        setGraphic(null);
                    }
                }
            });
            comboBox.setButtonCell(new ListCell<Person>(){
                @Override
                protected void updateItem(Person item, boolean empty) {
                    super.updateItem(item, empty);
                    if (!empty) {
                        setGraphic(buildLayout(item));
                    } else {
                        setGraphic(null);
                    }
                }
            });
            comboBox.getSelectionModel().selectedItemProperty().addListener((obs,oldVal,selectedPerson)->{
                System.out.println("Name : "+selectedPerson.getName());
                // Do what you want..
            });
            root.getChildren().add(comboBox);
        }

        private HBox buildLayout(Person person) {
            VBox layout = new VBox();
            HBox.setHgrow(layout,Priority.ALWAYS);
            layout.setStyle("-fx-border-width:1px;-fx-border-color:#444444;");
            layout.setSpacing(5);
            layout.setPadding(new Insets(2));
            HBox topRow = new HBox();
            topRow.setSpacing(5);
            topRow.getChildren().addAll(getLabel("Name :","bold"),getLabel(person.getName(),"normal"), getLabel("Age :","bold"),getLabel(person.getAge()+"","normal"));
            HBox bottomRow = new HBox();
            bottomRow.setSpacing(5);
            bottomRow.getChildren().addAll(getLabel("Email :","bold"),getLabel(person.getEmail(),"normal"));
            layout.getChildren().addAll(topRow, bottomRow);

            HBox pane = new HBox();
            pane.setAlignment(Pos.CENTER_LEFT);
            pane.setSpacing(5);
            pane.setPadding(new Insets(2));
            Label num = new Label(person.getId()+"");
            num.setStyle("-fx-font-size:20px;-fx-font-weight:bold;-fx-text-fill:black;");
            pane.getChildren().addAll(num,layout);
            return pane;
        }

    private Label getLabel(String txt, String style){
        Label lblName = new Label(txt);
        lblName.setStyle("-fx-font-weight:"+style+";-fx-text-fill:black;");
        return lblName;
    }

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

    class Person {
        IntegerProperty id = new SimpleIntegerProperty();
        StringProperty name = new SimpleStringProperty();
        IntegerProperty age = new SimpleIntegerProperty();
        StringProperty email = new SimpleStringProperty();

        public Person(int id,String name, int age, String email) {
            setId(id);
            setName(name);
            setAge(age);
            setEmail(email);
        }

        public int getId() {
            return id.get();
        }

        public IntegerProperty idProperty() {
            return id;
        }

        public void setId(int id) {
            this.id.set(id);
        }

        public String getName() {
            return name.get();
        }

        public StringProperty nameProperty() {
            return name;
        }

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

        public int getAge() {
            return age.get();
        }

        public IntegerProperty ageProperty() {
            return age;
        }

        public void setAge(int age) {
            this.age.set(age);
        }

        public String getEmail() {
            return email.get();
        }

        public StringProperty emailProperty() {
            return email;
        }

        public void setEmail(String email) {
            this.email.set(email);
        }
    }
}