【问题标题】:javafx dynamically add tooltip to each coljavafx 为每个列动态添加工具提示
【发布时间】:2018-11-17 01:05:48
【问题描述】:

我创建了一个简单的 Tableview 应该存储笔记,一切正常,但我想为每一列添加一个工具提示。
Example of my TableView

您可以看到日期不适合单元格,我想在那里添加一个工具提示,如果您将鼠标悬停在单元格上,它应该会出现并显示整个字符串。
基本上,每行中的最后 3 个(日期、noteTitle、noteTags)单元格应该有一个工具提示,因为它们可能会溢出。

从 GUI-Class 中剪掉(创建 tableview)

        //create TableCols
        TableColumn colorCol = new TableColumn<Rectangle, String>("C");
        colorCol.setMinWidth(30.0);
        colorCol.setMaxWidth(30.0);
        TableColumn prioCol = new TableColumn<Note, String>("priority");
        prioCol.setMinWidth(70.0);
        prioCol.setMaxWidth(70.0);
        TableColumn dateCol = new TableColumn<Note, String>("date");
        dateCol.setMinWidth(150.0);
        dateCol.setMaxWidth(150.0);
        TableColumn titleCol = new TableColumn<Note, String>("title");
        titleCol.setMaxWidth(150.0);
        titleCol.setMinWidth(150.0);
        TableColumn tagsCol = new TableColumn<Note, String>("tags");
        tagsCol.setMaxWidth(100.0);
        tagsCol.setMinWidth(100.0);
        fxListView.getColumns().addAll(colorCol, prioCol, dateCol, titleCol, tagsCol); //add cols to table. fxListView is the table

        colorCol.setCellValueFactory(new PropertyValueFactory<>("rect"));
        prioCol.setCellValueFactory(new PropertyValueFactory<>("priority"));
        dateCol.setCellValueFactory(new PropertyValueFactory<>("date"));
        titleCol.setCellValueFactory(new PropertyValueFactory<>("title"));
        tagsCol.setCellValueFactory(new PropertyValueFactory<>("tags"));
        DBManager temp = new DBManager(); 
        fxListView.setItems(temp.getTableData()); // this Method just returns a ObservableList<Note> with a few test datas.

笔记类

  public class Note {
        private Rectangle rect;
        private String rectColorString;
        private String priority;
        private String date;
        private String title;
        private String note;
        private String tags;
        private String fontStyle;
        private int fontSize;

        public Note(String rectColorString, String priority,String title, String note,String tags, String fontStyle, int fontSize) {
            this.rectColorString = rectColorString;
            rect = new Rectangle(24, 24, Color.web(rectColorString));
            this.priority = priority;
            this.date =  new Date().toString();
            this.title = title;
            this.note = note;
            this.tags = tags;
            this.fontStyle = fontStyle;
            this.fontSize = fontSize;
        }
        public String getDate() {
            return this.date;
        }
        public Rectangle getRect() {
            return rect;
        }

        public void setRect(Rectangle rect) {
            this.rect = rect;
        }

        public String getRectColorString() {
            return rectColorString;
        }

        public void setRectColorString(String rectColorString) {
            this.rectColorString = rectColorString;
            this.rect = new Rectangle(24, 24, Color.web(rectColorString));
        }

        public String getPriority() {
            return priority;
        }

        public void setPriority(String priority) {
            this.priority = priority;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getNote() {
            return note;
        }

        public void setNote(String note) {
            this.note = note;
        }

        public String getTags() {
            return tags;
        }

        public void setTags(String tags) {
            this.tags = tags;
        }

        public String getFontStyle() {
            return fontStyle;
        }

        public void setFontStyle(String fontStyle) {
            this.fontStyle = fontStyle;
        }

        public int getFontSize() {
            return fontSize;
        }

        public void setFontSize(int fontSize) {
            this.fontSize = fontSize;
        }
    }

还有另一张关于我希望工具提示如何显示的图片(以防我的解释不够清楚) Result

【问题讨论】:

    标签: java javafx tableview tooltip


    【解决方案1】:

    Tooltip 添加到单元格而不是TableColumn

    public class CustomTableCell extends TableCell<Note, String>() {
    
        private final Tooltip tooltip = new Tooltip();
    
        public CustomTableCell() {
            tooltip.textProperty().bind(itemProperty());
        }
    
        @Override
        protected void updateItem(String item, boolean emtpy) {
            super.updateItem(item, empty);
            if (empty || item == null) {
                setText(null);
                setTooltip(null); // so an empty cell doesn't display a Tooltip
            } else {
                setText(item);
                setTooltip(tooltip);
            }
        }
    }
    

    然后使用column.setCellFactory(Callback) 在您的TableColumn 上设置单元工厂。

    编辑:

    answer given by fabian 在添加 Tooltip 之前还会考虑整个项目是否已经显示。

    【讨论】:

      【解决方案2】:

      您需要使用自定义的TableCell 实现来执行此操作。从列的cellFactory 返回这样的实现:

      public class TooltipTableCell<S, T> extends TableCell<S, T> {
      
          private final Tooltip tooltip = new Tooltip();
          private final Text measureText = new Text();
          private Node textDisplay;
          private final InvalidationListener listener = o -> {
              setTooltip((measureText.getBoundsInLocal().getWidth() > textDisplay.getBoundsInLocal().getWidth()) ? tooltip : null);
          };
      
          @Override
          protected void layoutChildren() {
              super.layoutChildren();
      
              measureText.boundsInLocalProperty().addListener(listener);
              Node oldTextDisplay = textDisplay;
              textDisplay = lookup("LabeledText"); // lookup node displaying the text via CSS
      
              if (oldTextDisplay != textDisplay) {
                  if (oldTextDisplay != null) {
                      oldTextDisplay.boundsInLocalProperty().removeListener(listener);
                  }
                  textDisplay.boundsInLocalProperty().addListener(listener);
                  listener.invalidated(null);
              }
          }
      
          @Override
          protected void updateItem(T item, boolean empty) {
              super.updateItem(item, empty);
      
              String newText = empty || item == null ? "" : item.toString();
              setText(newText);
              tooltip.setText(newText);
              measureText.setText(newText);
          }
      
          public static <E, F> Callback<TableColumn<E, F>, TableCell<E, F>> forTableColumn() {
              return column -> new TooltipTableCell<>();
          }
      
      }
      
      titleCol.setCellFactory(TooltipTableCell.forTableColumn());
      

      请注意,在构造函数中指定类型参数没有什么意义,但在变量的声明中却没有。最好在声明中指定它并在构造函数调用中使用菱形运算符:

      TableColumn<Note, String> dateCol = new TableColumn<>("date");
      

      (如果fxListView 的声明包含类型参数,这将导致colorCol 的编译时错误。)

      【讨论】:

        猜你喜欢
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 2022-10-23
        • 1970-01-01
        • 1970-01-01
        • 2013-12-04
        • 2012-12-21
        • 2017-05-19
        相关资源
        最近更新 更多