2013-05-24 2 views
5

Я пытаюсь «умно» аббревиатура/обрезать содержимое столбца, вложенного в TableView. Я пробовал использовать UNCONSTRAINED_RESIZE_POLICY, но на самом деле предпочитаю CONSTRAINED_RESIZE_POLICY, так как он автоматически изменяет размеры столбцов на основе размера окна.JavaFX TableView Column Width Contents auto-truncating

То, что я пытаюсь выполнить:

String one = "SomeVeryLongString"; 

// Displayed in the column where user has shrunk it too narrow 

+-------------+ 
| Some...ring | 
+-------------+ 

// and if the user shrunk it a bit more 

+-----------+ 
| Som...ing | 
+-----------+ 

// and if they stretch it a bit 

+---------------+ 
| SomeV...tring | 
+---------------+ 

// etc... 

Я исследовал возможность чтения длины String и делать свое собственное усечение, но это не возможно, чтобы это динамически обновлять, как пользователь сжимается/растягивает gui. Моя кишка говорит, что это должно быть сделано с JavaFX Classes, так как оно будет тесно связано с TableView, однако я не нашел способ.

Как это сделать, используя JavaFX?

ответ

7

Решение

по умолчанию перерасход поведение стандартного TableCell является усечение это строка и дисплей ... в конце строки, чтобы указать, что строка была усечена. Все элементы управления Labeled в JavaFX работают таким образом.

Примеры в вашем вопросе имеют ... эллипсы в середине строк. Для достижения этой цели, set the overrun style на клетку, порожденной соответствующей ячейку завод:

setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS); 

текстовая строка отображается ellipsises также может быть доработана путем setting a new ellipsis string на клетки, порожденных соответствующей ячейка завод:

setEllipsisString(ellipsisString); 

простая ячейка таблицы, которая демонстрирует это:

class CenteredOverrunTableCell extends TableCell<Person, String> { 
    public CenteredOverrunTableCell() { 
     this(null); 
    } 

    public CenteredOverrunTableCell(String ellipsisString) { 
     super(); 
     setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS); 
     if (ellipsisString != null) { 
      setEllipsisString(ellipsisString); 
     } 
    } 

    @Override protected void updateItem(String item, boolean empty) { 
     super.updateItem(item, empty); 
     setText(item == null ? "" : item); 
    } 
} 

Пример приложения

CenteredOverrunTableCell используется в следующем примере приложения.

  1. Столбец Имени elides текста в центре и использует пользовательское многоточие строки <--->
  2. Последний столбец Имени elides текста в центре, но не обеспечивает строки пользовательского многоточия.
  3. В столбце «Электронная почта» используется политика перерасхода по умолчанию и эллипсисовая строка, которая помещает нулевой символ ... в конец строки переполнения.

elidedtableview

import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.*; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class ElidedTableViewSample extends Application { 
    private TableView<Person> table = new TableView<>(); 
    private final ObservableList<Person> data = 
     FXCollections.observableArrayList(
      new Person("Jacob", "Smith", "[email protected]"), 
      new Person("Isabella", "Johnson", "[email protected]"), 
      new Person("Ethangorovichswavlowskikaliantayaprodoralisk", "Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch", "[email protected]ch.com"), 
      new Person("Emma", "Jones", "[email protected]"), 
      new Person("Michael", "Brown", "[email protected]") 
     ); 

    public static void main(String[] args) { launch(args); } 

    @Override public void start(Stage stage) { 
     stage.setTitle("Table View Sample"); 
     stage.setWidth(470); 
     stage.setHeight(500); 

     final Label label = new Label("Address Book"); 
     label.setFont(new Font("Arial", 20)); 

     TableColumn firstNameCol = new TableColumn("First Name"); 
     firstNameCol.setCellValueFactory(
       new PropertyValueFactory<Person, String>("firstName")); 
     firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() { 
      @Override public TableCell<Person, String> call(TableColumn<Person, String> p) { 
       return new CenteredOverrunTableCell("<--->"); 
      } 
     }); 

     TableColumn lastNameCol = new TableColumn("Last Name"); 
     lastNameCol.setCellValueFactory(
       new PropertyValueFactory<Person, String>("lastName")); 
     lastNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() { 
      @Override public TableCell<Person, String> call(TableColumn<Person, String> p) { 
       return new CenteredOverrunTableCell(); 
      } 
     }); 

     TableColumn emailCol = new TableColumn("Email"); 
     emailCol.setCellValueFactory(
       new PropertyValueFactory<Person, String>("email")); 

     table.setItems(data); 
     table.getColumns().addAll(
      firstNameCol, 
      lastNameCol, 
      emailCol 
     ); 

     final VBox vbox = new VBox(); 
     vbox.setSpacing(5); 
     vbox.setPadding(new Insets(10)); 
     vbox.getChildren().addAll(label, table); 

     table.setColumnResizePolicy(
      TableView.CONSTRAINED_RESIZE_POLICY 
     ); 

     Scene scene = new Scene(vbox); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    class CenteredOverrunTableCell extends TableCell<Person, String> { 
     public CenteredOverrunTableCell() { 
      this(null); 
     } 

     public CenteredOverrunTableCell(String ellipsisString) { 
      super(); 
      setTextOverrun(OverrunStyle.CENTER_WORD_ELLIPSIS); 
      if (ellipsisString != null) { 
       setEllipsisString(ellipsisString); 
      } 
     } 

     @Override protected void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 
      setText(item == null ? "" : item); 
     } 
    } 

    public static class Person { 
     private final SimpleStringProperty firstName; 
     private final SimpleStringProperty lastName; 
     private final SimpleStringProperty email; 

     private Person(String fName, String lName, String email) { 
      this.firstName = new SimpleStringProperty(fName); 
      this.lastName = new SimpleStringProperty(lName); 
      this.email = new SimpleStringProperty(email); 
     } 

     public String getFirstName() { 
      return firstName.get(); 
     } 

     public void setFirstName(String fName) { 
      firstName.set(fName); 
     } 

     public String getLastName() { 
      return lastName.get(); 
     } 

     public void setLastName(String fName) { 
      lastName.set(fName); 
     } 

     public String getEmail() { 
      return email.get(); 
     } 

     public void setEmail(String fName) { 
      email.set(fName); 
     } 
    } 
} 
+0

'setTextOverrun()' это именно то, что я искал! Большое спасибо за очень хорошо собрал ответ! +10, если бы я мог! – SnakeDoc