Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Listview JavaFX2中奇怪的控件宽度?_Listview_User Interface_Combobox_Size_Javafx 2 - Fatal编程技术网

Listview JavaFX2中奇怪的控件宽度?

Listview JavaFX2中奇怪的控件宽度?,listview,user-interface,combobox,size,javafx-2,Listview,User Interface,Combobox,Size,Javafx 2,我是JavaFX2新手,对ComboBox和ListView的默认宽度感到困惑。我希望组合框更宽,这样文本“提示文本”将完全可见,而对于ListView,我希望它更小,仅在必要时尽可能宽。下面是代码和屏幕截图 1) 如何实现ComboBox和Listview的大小都与所需的宽度相符 2) 如何使两个控件的宽度相同(因此是两个宽度中的最大值),是否可以在两个控件的宽度之间创建某种链接?我特别想为FXML寻找一个优雅的解决方案 谢谢你的提示 @Override public void start(S

我是JavaFX2新手,对ComboBox和ListView的默认宽度感到困惑。我希望组合框更宽,这样文本“提示文本”将完全可见,而对于ListView,我希望它更小,仅在必要时尽可能宽。下面是代码和屏幕截图

1) 如何实现ComboBox和Listview的大小都与所需的宽度相符

2) 如何使两个控件的宽度相同(因此是两个宽度中的最大值),是否可以在两个控件的宽度之间创建某种链接?我特别想为FXML寻找一个优雅的解决方案

谢谢你的提示

@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();
}
@覆盖
公共无效开始(阶段primaryStage){
ComboBox ComboBox=新建ComboBox();
setPrompText(“提示文本”);
ObservableList items=FXCollections.observableArrayList();
项目。添加所有(“项目1”、“项目2”);
comboBox.setItems(项目);
ListView列表=新建ListView();
ObservableList items2=FXCollections.observableArrayList(
“蓝色”、“红色”);
列表。设置项目(项目2);
VBox VBox=新的VBox();
vBox.getChildren().addAll(组合框,列表);
设置场景(新场景(vBox,200300));
primaryStage.show();
}
1)尝试设置
minWidth(x)、prefWidth(x)、maxWidth(x)
。这有帮助,但不确定这是否是一个好的决定

2) 使用方法
无效绑定(observeValue
2) 如何使两个控件的宽度相同(因此是两个宽度中的最大值),是否可以在两个控件的宽度之间创建某种链接?我特别想为FXML寻找一个优雅的解决方案

默认情况下,ListView的maxWidth是无界的,而ComboBox的maxWidth是固定在初始项列表的宽度上的。要使这些控件具有相同的宽度,最简单的方法是将它们放置在布局管理器中(如您所做的那样-VBox),然后松开组合框的maxWidth

在代码中,可以执行以下操作:

comboBox.setMaxWidth(Double.MAX_VALUE);
在FXML中,向ComboBox元素添加以下attibute定义:

maxWidth="Infinity"
您可以使用约翰·格雷的绑定解决方案,但我发现上面的方法更优雅

1) 如何实现ComboBox和Listview的大小都与所需的宽度相符

我认为您在这里要问的是如何使combobox和listview只占用它们所需的空间,而不占用更多空间。我认为这有点棘手,JavaFX平台并没有为此提供很多支持

下面是一些示例代码,用于将列表框的大小固定到所需的最小值

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);
  }
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.scene.*;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.ListView;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.Priority;
导入javafx.stage.stage;
公共类GridControlWidths扩展了应用程序{
公共静态void main(字符串[]args)引发异常{launch(args);}
@覆盖公共无效开始(阶段){
ComboBox ComboBox=新的ComboBox(FXCollections.observableArrayList(“项目1”、“项目2”));
setPrompText(“提示文本”);
ListView列表=新的ListView(FXCollections.observableArrayList(“蓝色”、“红色”));
//使用适当的约束在网格中布局控件。
GridPane grid=新建GridPane();
添加(组合框,0,0);
添加(列表,0,1);
grid.setVgrow(list,Priority.ALWAYS);//使列表尽可能垂直增长
//松开组合框的最大宽度。
comboBox.setMaxWidth(Double.MAX_值);
//显示场景。
舞台场景(新场景(网格,200300));
stage.show();
//根据列表单元格设置listview的prefWidth(允许单元格填充8个像素)。
双最大宽度=0;
对于(节点n:list.lookupAll(“.text”)){
maxWidth=Math.max(maxWidth,n.getBoundsInParent().getWidth()+8);
}
list.setPrefWidth(maxWidth);
}
}
FWIW,我认为当你只有几个项目时,推荐的方法是将项目放在VBox中,而不是使用ListView或ChoiceBox而不是ComboBox,这样你就不需要进行单元格自省,也不需要一直更新首选宽度,因为布局管理器和控件会为你处理。ListView经过优化以处理虚拟化列表的情况,该列表可能包含数千个任意大小的项目,您可能无法轻松计算布局宽度,这就是为什么我认为它带有默认控件大小调整行为,该行为不会将其大小调整为可能具有的最小大小。通常在使用ListView时,您只需为ListView选择一个合理的prefWidth,并在ListView上设置它,而不是像上面的示例所示的那样反省项目


此外,在JavaFX中,当ComboBox提示文本比ComboBox项文本宽时,它没有正确地计算ComboBox控件的首选宽度。在我看来,裁剪某些提示文本的图像似乎是一个bug。由于ComboBox目前是一个全新的控件,我在JavaFX控件的早期版本中看到了此类问题,并且这些问题得到了修复,因此我希望ComboBox的首选宽度计算很快会得到修复。

非常感谢您对控件为何会有这种行为的解释(虽然我不明白为什么JavaFX会在我看来这么做并不直观)。设置MAX_值是一个好主意,尽管问题仍然是必须猜测vbox的正确宽度):[提供的代码只是一个简短的exmaple]更新的答案,以更全面地回答问题和地址(一些)关注点。需要补充的另一件有趣的事情是,SceneBuilder使用maxWidth=“-Infinity”和“-”符号,无穷大等于-1d/0d,这是的值。将maxWidth设置为
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);
  }
}