如何避免在javafx组合框中单击鼠标时关闭弹出菜单?

时间:2015-08-11 07:16:23

标签: combobox javafx

我有自定义ListCell的组合框:

private class SeverityCell extends ListCell<CustomItem> {
    private final CustomBox custombox;
    {
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
        custombox = new CustomBox();
    }
    @Override 
    protected void updateItem(CustomItem item, boolean empty) {         
        super.updateItem(item, empty);
        if (null != item) {
            ...
        }
        setGraphic(custombox);
    }
}

combobox.setCellFactory(new Callback<ListView<CustomItem>, ListCell<CustomItem>>() {
        @Override public ListCell<CustomItem> call(ListView<CustomItem> p) {
            return new SeverityCell();
        }
    });

当我点击mu自定义组件弹出窗口关闭时,我想避免它。我需要覆盖哪种方法/事件?

1 个答案:

答案 0 :(得分:3)

ComboBox在内部使用ListView来呈现其项目。它的皮肤类别为ComboBoxListViewSkin。在这个类的源代码中,有一个布尔标志来控制弹出隐藏行为:

// Added to allow subclasses to prevent the popup from hiding when the
// ListView is clicked on (e.g when the list cells have checkboxes).
protected boolean isHideOnClickEnabled() {
    return true;
}

用于listview:

       _listView.addEventFilter(MouseEvent.MOUSE_RELEASED, t -> {
            // RT-18672: Without checking if the user is clicking in the
            // scrollbar area of the ListView, the comboBox will hide. Therefore,
            // we add the check below to prevent this from happening.
            EventTarget target = t.getTarget();
            if (target instanceof Parent) {
                List<String> s = ((Parent) target).getStyleClass();
                if (s.contains("thumb")
                        || s.contains("track")
                        || s.contains("decrement-arrow")
                        || s.contains("increment-arrow")) {
                    return;
                }
            }

            if (isHideOnClickEnabled()) {
                comboBox.hide();
            }
        });

因此,您想要的行为可以(并且可能应该)使用自定义皮肤实现。但是,解决方法可以是

combobox.setSkin( new ComboBoxListViewSkin<CustomItem>( combobox )
{
    @Override
    protected boolean isHideOnClickEnabled()
    {
        return false;
    }
} );

并在例如更改值时手动隐藏弹出窗口:

combobox.valueProperty().addListener( new ChangeListener()
{
    @Override
    public void changed( ObservableValue observable, Object oldValue, Object newValue )
    {
        combobox.hide();
    }
});

请注意,我没有完全测试这种匿名的内在皮肤方法。