java - HBox 内的左对齐按钮(如果重要的话,在 pagnition 内)

标签 java javafx scenebuilder

我在空闲时间学习 JavaFX,并认为简单的日程应用程序将是一个很好的实践。我当前的目标是输出 ArrayList 的所有成员,并为每个成员提供按钮,允许将任务标记为已完成或编辑任务。然而,我在按钮放置方面遇到了困难,我有一个包含标签和两个按钮的 HBox,我可以让它们间隔开,但由于任务是不同大小的字符串,我无法让按钮彼此对齐。有没有办法让它们的位置基于字符串的左侧,而不是字符串之后的右侧?

这是我当前的代码:

@FXML
public Node createPage(int pageIndex){
    ListView<Event> eventView = new ListView<>();
    int fromIndex = pageIndex * maxPerPage;
    int toIndex = Math.min(fromIndex + maxPerPage, schedule.size());
    List<Event> eventString = schedule.subList(fromIndex, toIndex);
    //testing buttons
    eventView.setCellFactory(param -> new ListCell<Event>(){
        @Override
        protected void updateItem(Event item, boolean empty){
            super.updateItem(item,empty);
            if(empty || item == null){
                setText(null);
                setGraphic(null);
            } else{
                Label label = new Label(item.display());

                Button editButton = new Button ("Edit");

                Button completedButton = new Button ("Completed");

                editButton.setOnAction(event ->{
                    System.out.println("done");
                });

                completedButton.setOnAction(event ->{
                    System.out.println("done");
                });

                HBox eventHbox = new HBox(label);

                HBox buttonHbox = new HBox(editButton,completedButton);

                buttonHbox.setSpacing(50);

                buttonHbox.setAlignment(Pos.CENTER_RIGHT);

                HBox.setMargin(buttonHbox,new Insets(0,0,0,200));

                HBox hbox = new HBox(eventHbox,buttonHbox);

                setGraphic(hbox);
            }
        }

    });
}

最终我还需要弄清楚如何将按钮对齐的元素发送到按下按钮时的函数(如果有人有相关提示)

我尝试使用 BASELINE_RIGHT 而不是 CENTER_RIGHT,如果我不再更改 setMargin() 中的传递,或者喜欢 max 或其他东西,会让我滚动查看它

编辑:: 试图找出 TableView 但没有得到它,对于想要照片的人来说,(想要的数据是用相同大小的数据创建的,理想情况下按钮放置不依赖于数据长度)

这是我目前拥有的:currently have

这就是我想要的 want to have

最佳答案

在单个 HBox 中使用 Region 作为间隔填充符

[警告:我不是 JavaFX 专家。]

我问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 ( );
    }
}

还有屏幕截图。

Screenshot of example app with a ListView showing buttons pushed to the right

我可能不认为这个解决方案是完整的。如果用户缩小窗口的宽度,按钮就会从窗口的右边缘消失。理想情况下,按钮在窗口中始终保持可见,并且太长的标签会被截断。我不知道该问题的解决方案。

将域对象绑定(bind)到您的操作按钮

also eventually I will need to figure out how to send the element the button is aligned with into the function for when the button is pressed if anyone has tips for that

将每个域对象绑定(bind)到按钮是小部件布局的正交问题。因此,您应该就该特定问题撰写一个单独的问题。

但简单来说......

请注意,您的 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 ( ) );
} );

顺便说一句,尤其是在学习时,而且通常更普遍的是,您可能会发现扩展 lambda 中的参数类型很方便。这样做有助于您清楚地了解每个点上到底有哪些对象在起作用。

所以这个:

editButton.setOnAction ( ( ActionEvent actionEvent ) -> …

...而不是这个:

editButton.setOnAction ( actionEvent -> …

关于java - HBox 内的左对齐按钮(如果重要的话,在 pagnition 内),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77298240/

相关文章:

java - "AWT-EventQueue-0"java.lang.NullPointerException 异常

java - 为基于 Hibernate 的应用程序实现数据历史记录/版本控制解决方案(有一个转折点)

java - 如何在 Java gui 应用程序中更改字体?

java - 将堆转储保存在不同驱动器中的 JVM 参数

java - JavaFX 中任何类型的动画或时间线都会占用过多的 CPU

JavaFX/CSS : Changing text color of ComboBox's selected item

javafx choicebox触发onchange方法

java - 使用 CSS 设置 BorderPane 顶部样式

java - 将 View 从 JavaFX 转换为 HTML

java - 如何仅显示可被 javafx 图表 Axis 上的刻度单位整除的数字