2012-05-07 31 views
5

Tôi mới dùng JavaFX 2 và bối rối về độ rộng mặc định của ComboBox và ListView. Tôi mong đợi ComboBox sẽ rộng hơn, để văn bản "văn bản nhắc nhở" sẽ hoàn toàn hiển thị, cho ListView tôi mong đợi nó sẽ nhỏ hơn, chỉ rộng khi cần thiết. Mã và ảnh chụp màn hình sau đây.Độ rộng điều khiển lạ trong JavaFX 2?

1) Làm thế nào tôi có thể đạt được ComboBox và Listview đều có kích thước với chiều rộng mà họ cần?

2) Làm thế nào để cả hai điều khiển có cùng chiều rộng (do đó tối đa là cả hai chiều rộng), có thể tạo ra một loại liên kết nào đó giữa độ rộng của cả hai không? Tôi đặc biệt đang tìm kiếm một giải pháp thanh lịch cho FXML.

Cảm ơn bạn đã gợi ý!

@Override 
public void start(Stage primaryStage) { 
    ComboBox<String> comboBox = new ComboBox<String>(); 
    comboBox.setPromptText("the prompt text"); 
    ObservableList<String> items = FXCollections.observableArrayList(); 
    items.addAll("item 1", "item 2"); 
    comboBox.setItems(items); 

    ListView<String> list = new ListView<String>(); 
    ObservableList<String> items2 =FXCollections.observableArrayList (
     "blue", "red"); 
    list.setItems(items2); 

    VBox vBox = new VBox(); 
    vBox.getChildren().addAll(comboBox, list); 

    primaryStage.setScene(new Scene(vBox, 200, 300)); 
    primaryStage.show(); 
} 

enter image description here

Trả lời

0

1) Cố gắng thiết lập minWidth(x), prefWidth(x), maxWidth(x). Điều đó giúp, nhưng không chắc đó là một quyết định tốt.

2) Sử dụng phương pháp void bind(ObservableValue<? extends Number> observable); từ khung ràng buộc. Nó được phát triển chỉ cho những trường hợp như vậy. Ví dụ:

someProperty.bind(otherProperty); 

Bạn cũng có thể sử dụng ràng buộc hai chiều để liên kết chúng.

+0

Cảm ơn bạn đã trả lời, maxWidth có ích/tốt hơn so với tình huống cũ, mặc dù vẫn phải đoán giá trị): Tôi cần một số điều chỉnh tự động do JavaFX thực hiện): Và cảm ơn thông tin về tài sản! thực sự thích WPF ;-) –

+0

Và tốt hơn để sử dụng SceneBuilder nếu cho các trường hợp như vậy và sau đó xuất khẩu fxml cho dự án của bạn. – 4lex1v

8

2) Làm cách nào để tạo cả hai điều khiển có cùng độ rộng (do đó tối đa cả hai chiều rộng), có thể tạo một loại liên kết nào đó giữa độ rộng của cả hai không? Tôi đặc biệt đang tìm kiếm một giải pháp thanh lịch cho FXML.

Dường như, theo mặc định, ListView có maxWidth không bị chặn, nhưng ComboBox có maxWidth được kẹp theo chiều rộng của danh sách mục ban đầu. Để làm cho các điều khiển này có cùng chiều rộng, cách dễ nhất để làm điều đó là đặt chúng trong trình quản lý bố cục (như bạn đã làm - VBox) và sau đó bỏ chọn maxWidth của comboBox.

Trong mã bạn có thể làm điều này:

comboBox.setMaxWidth(Double.MAX_VALUE); 

Trong FXML thêm dòng sau attibute nét đến yếu tố ComboBox của bạn:

maxWidth="Infinity" 

Bạn có thể sử dụng giải pháp ràng buộc John Gray, nhưng tôi tìm ra trên thanh lịch hơn.

1) Làm thế nào tôi có thể đạt được ComboBox và Listview đều có kích thước theo chiều rộng mà họ cần?

Tôi nghĩ rằng những gì bạn đang hỏi ở đây là làm thế nào để làm cho combobox và listview chỉ chiếm nhiều không gian khi họ cần và không còn nữa. Đây là, tôi tin rằng một chút khôn lanh, và nền tảng JavaFX không cung cấp rất nhiều hỗ trợ cho việc này.

Dưới đây là một số mã mẫu để sửa kích thước của hộp danh sách theo yêu cầu tối thiểu.

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.scene.*; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Priority; 
import javafx.stage.Stage; 

public class GridControlWidths extends Application { 
    public static void main(String[] args) throws Exception { launch(args); } 
    @Override public void start(Stage stage) { 
    ComboBox<String> comboBox = new ComboBox<String>(FXCollections.observableArrayList("item 1", "item 2")); 
    comboBox.setPromptText("the prompt text"); 

    ListView<String> list = new ListView<String>(FXCollections.observableArrayList ("blue", "red")); 

    // layout the controls in a grid with appropriate constraints. 
    GridPane grid = new GridPane(); 
    grid.add(comboBox, 0, 0); 
    grid.add(list, 0, 1); 
    grid.setVgrow(list, Priority.ALWAYS); // make the list grow vertically as much as possible 

    // unclamp the max width of the combo box. 
    comboBox.setMaxWidth(Double.MAX_VALUE); 

    // display the scene. 
    stage.setScene(new Scene(grid, 200, 300)); 
    stage.show(); 

    // set the prefWidth of the listview based on the list cells (allowing 8 pixels for padding of the cells). 
    double maxWidth = 0; 
    for (Node n: list.lookupAll(".text")) { 
     maxWidth = Math.max(maxWidth, n.getBoundsInParent().getWidth() + 8); 
    } 
    list.setPrefWidth(maxWidth); 
    } 
} 

FWIW, tôi tin rằng một cách tiếp cận đề nghị khi bạn chỉ có một vài mục là để đặt các mục của bạn trong một VBox hơn là sử dụng một ListView hoặc một ChoiceBox chứ không phải là một ComboBox, như vậy bạn không cần để làm nội suy tế bào và cập nhật chiều rộng ưa thích tất cả các thời gian như người quản lý bố trí và điều khiển sẽ chăm sóc nó cho bạn. ListView được tối ưu hóa để xử lý trường hợp danh sách ảo hóa có thể chứa hàng nghìn mục có kích thước tùy ý mà bạn không thể dễ dàng tính toán chiều rộng bố cục, đó là lý do tại sao tôi nghĩ nó đi kèm với hành vi kiểm soát mặc định kích thước nó đến kích thước tối thiểu nó có thể có thể có. Thông thường khi sử dụng một ListView, bạn sẽ chỉ cần chọn một prefWidth hợp lý cho listView và đặt nó trên listView thay vì nhìn vào các mục như ví dụ trên cho thấy.

Ngoài ra, hình ảnh bạn có nơi một số văn bản nhắc được cắt bớt, dường như (với tôi) là lỗi trong JavaFX, nơi nó không tính toán độ rộng ưa thích cho điều khiển ComboBox khi văn bản nhắc ComboBox rộng hơn so với văn bản mục ComboBox. Vì ComboBox hiện là một điều khiển hoàn toàn mới và tôi đã thấy các vấn đề này trong các phiên bản trước của các điều khiển JavaFX và chúng đã được sửa, tôi hy vọng rằng tính toán chiều rộng được ưu tiên cho ComboBox sẽ sớm được khắc phục một cách hợp lý.

+0

Cảm ơn bạn rất nhiều vì đã giải thích lý do tại sao các điều khiển hoạt động theo cách đó (mặc dù tôi không thể hiểu tại sao JavaFX thực hiện điều đó một cách vô tình theo ý kiến ​​của tôi). Đặt MAX_VALUE là một ý tưởng hay, mặc dù vấn đề vẫn là người ta phải đoán chiều rộng chính xác cho vbox): [mã được cung cấp chỉ là một hình ảnh ngắn] –

+0

Câu trả lời được cập nhật để trả lời đầy đủ hơn các câu hỏi và địa chỉ (một số). – jewelsea

+0

Một điều thú vị nữa để thêm rằng SceneBuilder sử dụng maxWidth = "- Infinity" với dấu "-" – 4lex1v

Các vấn đề liên quan