【问题标题】:How to customize a combobox in JAVAFX如何在 JAVAFX 中自定义组合框
【发布时间】:2018-11-09 16:26:24
【问题描述】:

我想在 JavaFX 中重现该组合框

在 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。

谢谢

【问题讨论】:

    标签: java javafx javafx-8


    【解决方案1】:

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

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

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

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

        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);
            }
        }
    }
    

    【讨论】:

    • 嗨赛,首先,非常感谢您的回答。我只有一个问题 getLabel 方法的来源。
    • 我自己解决了,一切正常,再次感谢您
    • 糟糕.. 抱歉粘贴问题 :) 更新了代码。无论如何很高兴它帮助了你:)
    猜你喜欢
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多