JavaFX: ячейка TableView pixelates ImageView - как отменить преобразование? - PullRequest
2 голосов
/ 21 марта 2019

Редактировать: Этот вопрос был полностью переработан в свете новой информации.

Это использует javafx8 и SceneBuilder2.

Я обнаружил, что превращение TableView в дочерний элемент AnchorPane для аккордеона, а затем (в SceneBuilder) щелчок правой кнопкой мыши на TableView и нажатие «fit-to-parent» приводит к искажению и ухудшению качества изображений, отображаемых в ячейках таблицы; все выглядит смелым. Я передал это изображение enter image description here в конструктор таблицы для отображения. Тот, что слева, до того, как был применен «соответствовать контенту»; тот, что справа был после.

enter image description here

Кто-нибудь имеет представление о том, как я могу обойти это? Потому что мне нужен стол в гармошке для динамического изменения размера по горизонтали с окном без потери качества изображения.

Минимальный пример ниже

контроллер первый

package application;

import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import java.net.URL;

public class SampleController implements Initializable
{
    @FXML private TableView<SomeTableItems> someTable;      
    @FXML private TableColumn<SomeTableItems, String> imagesRow;
    @FXML private TableColumn<SomeTableItems, String> description;
    @FXML private TableColumn<SomeTableItems, String> modified;
    @FXML private TableColumn<SomeTableItems, String> created;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) 
    {           
        imagesRow.setCellValueFactory(new PropertyValueFactory<SomeTableItems, String>("imagesRow"));
        description.setCellValueFactory(new PropertyValueFactory<SomeTableItems, String>("description"));
        modified.setCellValueFactory(new PropertyValueFactory<SomeTableItems, String>("modified"));
        created.setCellValueFactory(new PropertyValueFactory<SomeTableItems, String>("created"));   

        someTable.setItems(getSomeTableItems());
    }

    private ObservableList<SomeTableItems> getSomeTableItems()
    {
        ObservableList<SomeTableItems> itemsToReturn = FXCollections.observableArrayList();
        itemsToReturn.add(new SomeTableItems("/imageAssets/tableImage1.png","secondContent", "thirdContent", "fourthContent"));

        return itemsToReturn;
    }
}

Предположим, у вас есть пакет imageAssets, содержащий изображение с названием "tableImage1.png" для приведенного выше кода. Конструктор для SomeTableItems приведен ниже.

package application;

import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class SomeTableItems 
{
    private Node imagesRow;
    private SimpleStringProperty description;
    private SimpleStringProperty modified;
    private SimpleStringProperty created;

    public Node getImagesRow()
    {
        return imagesRow;
    }

    public String getDescription() 
    {
        return description.get();
    }

    public String getModified() {
        return modified.get();
    }

    public String getCreated() 
    {
        return created.get();
    }

    public void setImagesRow(String pathToImage)
    {
        this.imagesRow = new ImageView(new Image(getClass().getResourceAsStream(pathToImage)));
    }

    public void setDescription(SimpleStringProperty description) 
    {
        this.description = description;
    }

    public void setModified(SimpleStringProperty modified) 
    {
        this.modified = modified;
    }

    public void setCreated(SimpleStringProperty created) 
    {
        this.created = created;
    }

    public SomeTableItems()
    {
        this.imagesRow =  new ImageView(new Image(getClass().getResourceAsStream("/imageAssets/tableImage1.png")));
        this.description = new SimpleStringProperty("-");
        this.modified = new SimpleStringProperty("-");
        this.created = new SimpleStringProperty("-");
    }

    public SomeTableItems(String pathToImage, String description, String modified, String created)
    {
        this.imagesRow =  new ImageView(new Image(getClass().getResourceAsStream(pathToImage)));
        this.description = new SimpleStringProperty(description);
        this.modified = new SimpleStringProperty(modified);
        this.created = new SimpleStringProperty(created);
    }
}

Ниже приведен fxml, созданный в SceneBuilder2

  <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane prefHeight="206.0" prefWidth="384.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
   <center>
      <Accordion BorderPane.alignment="CENTER">
        <panes>
          <TitledPane animated="false" text="untitled 3">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <TableView fx:id="someTable" prefHeight="180.0" prefWidth="382.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" BorderPane.alignment="CENTER">
                          <columns>
                            <TableColumn fx:id="imagesRow" prefWidth="75.0" text="C1" />
                            <TableColumn fx:id="description" prefWidth="75.0" text="C2" />
                            <TableColumn fx:id="modified" prefWidth="75.0" text="C3" />
                            <TableColumn fx:id="created" prefWidth="75.0" text="C4" />
                          </columns>
                        </TableView>
                     </children>
                  </AnchorPane>
            </content>
          </TitledPane>
        </panes>
      </Accordion>
   </center>
</BorderPane>

Приведенный выше код воспроизводит ошибку, показанную на скриншоте в начале. Если вы посмотрите на строку в fxml, где объявлен TableView, вы можете отменить эффект соответствия родительскому элементу, заменив строку приведенным ниже кодом. Это разница между жирным «глюком», происходящим или нет.

<TableView fx:id="someTable" prefHeight="200.0" prefWidth="402.0" BorderPane.alignment="CENTER">

И Main является общим. Я с радостью включу основную по запросу, хотя.

Спасибо всем, кто заинтересован и готов помочь мне. Я очень ценю ваше время.

1 Ответ

2 голосов
/ 23 марта 2019

Почти никогда нет веских причин использовать AnchorPane. Несмотря на то, что AnchorPane может иметь законное использование, на практике гораздо чаще используется AnchorPane так же, как в AWT / Swing используются нулевые макеты: для точного указания местоположения и размера узла.

Принудительное изменение размера таблицы приводит к тому, что размер изображения (немного) изменяется.

Самое простое решение - использовать макет, который будет учитывать предпочтительный размер его дочернего узла, такой как BorderPane или StackPane:

<BorderPane>
    <center>
        <TableView fx:id="someTable" …
            …
        </TableView>
    </center>
</BorderPane>
...