Skip to content

Commit

Permalink
Improve automatic sizing of columns
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasdiez committed Jan 9, 2018
1 parent 3a69091 commit e3515e9
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 36 deletions.
24 changes: 12 additions & 12 deletions src/main/java/org/jabref/gui/maintable/ColumnFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,9 @@ private TableColumn<BibEntryTableViewModel, Optional<SpecialFieldValueViewModel>
column.setGraphic(new SpecialFieldViewModel(specialField).getIcon().getGraphicNode());
column.getStyleClass().add(STYLE_ICON);
if (specialField == SpecialField.RANKING) {
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL_RANKING);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL_RANKING);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL_RANKING);
} else {
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL);
}
column.setCellValueFactory(cellData -> cellData.getValue().getSpecialField(specialField));
column.setCellFactory(
Expand All @@ -114,12 +112,17 @@ private TableColumn<BibEntryTableViewModel, Optional<SpecialFieldValueViewModel>
return column;
}

private void setExactWidth(TableColumn<?, ?> column, int widthIconCol) {
column.setMinWidth(widthIconCol);
column.setPrefWidth(widthIconCol);
column.setMaxWidth(widthIconCol);
}

private TableColumn<BibEntryTableViewModel, List<LinkedFile>> createFileColumn() {
TableColumn<BibEntryTableViewModel, List<LinkedFile>> column = new TableColumn<>();
column.setGraphic(IconTheme.JabRefIcons.FILE.getGraphicNode());
column.getStyleClass().add(STYLE_ICON);
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL);
column.setCellValueFactory(cellData -> cellData.getValue().getLinkedFiles());
column.setCellFactory(
new ValueTableCellFactory<BibEntryTableViewModel, List<LinkedFile>>()
Expand All @@ -134,8 +137,7 @@ private TableColumn<BibEntryTableViewModel, String> createIconColumn(JabRefIcon
TableColumn<BibEntryTableViewModel, String> column = new TableColumn<>();
column.setGraphic(icon.getGraphicNode());
column.getStyleClass().add(STYLE_ICON);
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL);
column.setCellValueFactory(cellData -> EasyBind.monadic(cellData.getValue().getField(firstField)).orElse(cellData.getValue().getField(secondField)));
column.setCellFactory(
new ValueTableCellFactory<BibEntryTableViewModel, String>()
Expand All @@ -147,8 +149,7 @@ private TableColumn<BibEntryTableViewModel, String> createIconColumn(JabRefIcon
TableColumn<BibEntryTableViewModel, String> column = new TableColumn<>();
column.setGraphic(icon.getGraphicNode());
column.getStyleClass().add(STYLE_ICON);
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL);
column.setCellValueFactory(cellData -> cellData.getValue().getField(field));
column.setCellFactory(
new ValueTableCellFactory<BibEntryTableViewModel, String>()
Expand All @@ -168,8 +169,7 @@ private TableColumn<BibEntryTableViewModel, List<LinkedFile>> createExtraFileCol
.map(ExternalFileType::getIcon).orElse(IconTheme.JabRefIcons.FILE)
.getGraphicNode());
column.getStyleClass().add(STYLE_ICON);
column.setMinWidth(GUIGlobals.WIDTH_ICON_COL);
column.setMaxWidth(GUIGlobals.WIDTH_ICON_COL);
setExactWidth(column, GUIGlobals.WIDTH_ICON_COL);
column.setCellValueFactory(cellData -> cellData.getValue().getLinkedFiles());
column.setCellFactory(
new ValueTableCellFactory<BibEntryTableViewModel, List<LinkedFile>>()
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/maintable/MainTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public MainTable(MainTableDataModel model, JabRefFrame frame,
})
.withContextMenu(RightClickMenu::create));
if (preferences.resizeColumnsToFit()) {
this.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
this.setColumnResizePolicy(new SmartConstrainedResizePolicy());
}
this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
this.setItems(model.getEntriesFiltered());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.jabref.gui.maintable;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javafx.scene.control.ResizeFeaturesBase;
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TableView;
import javafx.util.Callback;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* This resize policy is almost the same as {@link TableView#CONSTRAINED_RESIZE_POLICY}
* We make sure that the width of all columns sums up to the total width of the table.
* However, in contrast to {@link TableView#CONSTRAINED_RESIZE_POLICY} we size the columns initially by their preferred width.
*/
public class SmartConstrainedResizePolicy implements Callback<TableView.ResizeFeatures, Boolean> {

private static final Log LOGGER = LogFactory.getLog(SmartConstrainedResizePolicy.class);

@Override
public Boolean call(TableView.ResizeFeatures prop) {
if (prop.getColumn() == null) {
return initColumnSize(prop.getTable());
} else {
return constrainedResize(prop);
}
}

private Boolean initColumnSize(TableView<?> table) {
double tableWidth = table.getWidth();
List<? extends TableColumnBase<?, ?>> visibleLeafColumns = table.getVisibleLeafColumns();
double totalWidth = visibleLeafColumns.stream().mapToDouble(TableColumnBase::getWidth).sum();

if (Math.abs(totalWidth - tableWidth) > 1) {
double totalPrefWidth = visibleLeafColumns.stream().mapToDouble(TableColumnBase::getPrefWidth).sum();
if (totalPrefWidth > 0) {
for (TableColumnBase col : visibleLeafColumns) {
double share = col.getPrefWidth() / totalPrefWidth;
double newSize = tableWidth * share;
resize(col, newSize - col.getWidth());
}
}
}

return false;
}

private void resize(TableColumnBase column, double delta) {
// We have to use reflection since TableUtil is not visible to us
try {
Class<?> clazz = Class.forName("javafx.scene.control.TableUtil");
Method constrainedResize = clazz.getDeclaredMethod("resize", TableColumnBase.class, double.class);
constrainedResize.setAccessible(true);
constrainedResize.invoke(null, column, delta);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
LOGGER.error("Could not invoke resize in TableUtil", e);
}
}

private Boolean constrainedResize(TableView.ResizeFeatures<?> prop) {
TableView<?> table = prop.getTable();
List<? extends TableColumnBase<?, ?>> visibleLeafColumns = table.getVisibleLeafColumns();
return constrainedResize(prop,
false,
getContentWidth(table),
visibleLeafColumns);
}

private Boolean constrainedResize(TableView.ResizeFeatures prop, Boolean isFirstRun, Double contentWidth, List<? extends TableColumnBase<?, ?>> visibleLeafColumns) {
// We have to use reflection since TableUtil is not visible to us
try {
Class<?> clazz = Class.forName("javafx.scene.control.TableUtil");
Method constrainedResize = clazz.getDeclaredMethod("constrainedResize", ResizeFeaturesBase.class, Boolean.TYPE, Double.TYPE, List.class);
constrainedResize.setAccessible(true);
Object returnValue = constrainedResize.invoke(null, prop, isFirstRun, contentWidth, visibleLeafColumns);
return (Boolean) returnValue;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
LOGGER.error("Could not invoke constrainedResize in TableUtil", e);
return false;
}
}

private Double getContentWidth(TableView<?> table) {
try {
Field privateStringField = TableView.class.getDeclaredField("contentWidth");
privateStringField.setAccessible(true);
return (Double) privateStringField.get(table);
} catch (IllegalAccessException | NoSuchFieldException e) {
return 0d;
}
}
}

This file was deleted.

0 comments on commit e3515e9

Please sign in to comment.