Use Region
as a spacer-filler in a single HBox
[警告:我不是Java FX方面的专家.]
我问了a similar Question个,更狭隘地关注于一种只使用一个HBox
而不是嵌套多个HBox
对象来完成标签按钮-按钮布局的方法.
Answer there by makki saud alghamdi至少为您提供了部分可能的解决方案.答案是使用Region
对象作为标签和按钮之间的空间,以填补空白,有效地将按钮向右推.
代码的关键行是:
// Mind the gap between label and buttons.
Region spacer = new Region ( );
HBox.setHgrow ( spacer , Priority.ALWAYS );
HBox rowBox = new HBox ( label , spacer , editButton , completedButton );
下面是一个完整的示例应用程序.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
public class HelloApplication extends Application
{
@Override
public void start ( Stage stage ) throws IOException
{
record Event( String title , LocalDate when ) { }
ObservableList < Event > events =
FXCollections.observableList (
List.of (
new Event ( "A bit of text" , LocalDate.now ( ) ) ,
new Event ( "Even more text than that." , LocalDate.now ( ).plusDays ( 1 ) ) ,
new Event ( "Lots and lots and lots of text for a very long line." , LocalDate.now ( ).plusDays ( 2 ) )
)
);
ListView < Event > eventView = new ListView <> ( events );
eventView.setCellFactory ( ( ListView < Event > listView ) -> new ListCell < Event > ( )
{
Button editButton = new Button ( "Edit" );
Button completedButton = new Button ( "Completed" );
Label label = new Label ( );
Label labelTwo = new Label( );
Region spacer = new Region ( );
VBox vBox = new VBox(label, labelTwo);
HBox rowBox = new HBox ( vBox , spacer , editButton , completedButton );
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd");
{
// Mind the gap between label and buttons.
HBox.setHgrow ( spacer , Priority.ALWAYS );
rowBox.setAlignment ( Pos.CENTER );
rowBox.setSpacing ( 7 );
}
@Override
protected void updateItem ( Event item , boolean empty )
{
super.updateItem ( item , empty );
if ( empty || item == null )
{
setText ( null );
setGraphic ( null );
}
else
{
label.setText(item.title());
labelTwo.setText("\tDue: " + item.when().format(dateTimeFormatter));
editButton.setOnAction ( actionEvent ->
{
System.out.println ( "DEBUG - Edit the Event: " + item.title() );
});
completedButton.setOnAction ( actionEvent ->
{
System.out.println ( "DEBUG - Completed the Event: " + item.title());
});
setGraphic ( rowBox );
}
}
} );
BorderPane pane = new BorderPane ( );
pane.setCenter ( eventView );
Scene scene = new Scene ( pane , 700 , 300 );
stage.setScene ( scene );
stage.setTitle ( "Schedule Example" );
stage.show ( );
}
public static void main ( String[] args )
{
launch ( );
}
}
还有一张截图.
我可能不会认为这个解决方案是完整的.如果用户缩小窗口的宽度,按钮将从窗口的右边缘消失.理想情况下,按钮在窗口内始终可见,过长的标签将被截断.我不知道那个问题的解决方案.
将域对象绑定到操作按钮
另外,最终我需要弄清楚如何将按钮与之对齐的元素发送到函数中,以便在按钮被按下时使用,如果有人对此有提示的话
将每个域对象绑定到按钮是一个与小部件布局相关的问题.因此,你应该就那个特定的问题单独提出一个问题.
但简单地说,…
请注意,向您的cell factory传递了对该项目的引用,该项目是您的Event
类的对象,将由ListView
显示.在这一行中:
protected void updateItem ( Event item , boolean empty ) …
…第一个参数Event item
是关键.请注意,在实例化每个Label
时,我如何在对item.toString
的调用中使用该引用.
Label label = new Label ( item.toString ( ) );
我们也可以在您的按钮操作处理程序中添加类似的调用.
Button editButton = new Button ( "Edit" );
Button completedButton = new Button ( "Completed" );
editButton.setOnAction ( ( ActionEvent actionEvent ) ->
{
System.out.println ( "DEBUG - Edit the Event: " + item.toString ( ) );
} );
completedButton.setOnAction ( ( ActionEvent actionEvent ) ->
{
System.out.println ( "DEBUG - Completed the Event: " + item.toString ( ) );
} );
顺便说一句,尤其是在学习的过程中,您可能会发现扩展lambdas中的参数类型很方便.这样做有助于让你的头脑保持清醒,准确地知道在每一个点上都有哪些物体在发挥作用.
所以这就是:
editButton.setOnAction ( ( ActionEvent actionEvent ) -> …
…而不是这样:
editButton.setOnAction ( actionEvent -> …