2017-05-11 14 views
0

고정 열과 나머지 하나를 혼합하여 성운 NatTable을 만드는 방법과 고정 폭 열의 사용자 크기를 결정할 수있는 중요한 결정적 위치는 무엇입니까?고정 너비 열의 NatTable 혼합 및 크기 조정 가능한 남은 채우기 공간에

카메라 예 :

+---------------------------------------+----------+-------+ 
|  ...fills available vert space... | 120px | 100px | 

사용자가 칼럼 (1)과 (2) 사이의 경계를 누름으로써 제 3 컬럼의 사이즈를 변경

+-----------------------------------------+-------+-------+ 
|  ...fills available vert space... | 100px | 100px | 

사용자는 좌측 열 사이의 경계 0 및 1을 눌러 중간 열의 크기를 조절 왼쪽 :

+------------------------------------+----------+----------+ 
| ...fills available vert space... | 120px | 120px | 

나는이 코드와 매우 근접해있다 :

IRowDataProvider<String> bodyDataProvider = ...; 
    DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); 
    SelectionLayer selectionLayer = new SelectionLayer(bodyDataLayer, false); 
    ViewportLayer viewportLayer = new ViewportLayer(selectionLayer); 

    bodyDataLayer.setColumnPercentageSizing(0, true); 
    bodyDataLayer.setColumnPositionResizable(0, true); 

    bodyDataLayer.setColumnWidthByPosition(1, 100); 
    bodyDataLayer.setColumnPositionResizable(1, true); 

    bodyDataLayer.setColumnWidthByPosition(2, 100); 
    bodyDataLayer.setColumnPositionResizable(2, true); 

시각적으로 무엇을 의도했는지, 컨테이너 (쉘)에서 의도 한대로 반응합니다. 고정 된 열은 100px로 유지되고 첫 번째 열만 크기가 조정됩니다. 지금까지는 좋았어. 그러나 문제가 있습니다. 열간 크기 조정에 나쁜 점이 있습니다. 나는 이상하게 반응한다. 열 0과 열 1 사이의 크기 조정 핸들러 (머리글 테두리)는 아무 작업도 수행하지 않고 크기 조정 만 표시되지만 크기 조정은 실행되지 않습니다. 열 1과 열 2 사이의 크기 조정 핸들러는 반응하지만 열 1 만 효과적으로 크기를 조정할 수 있으며 열 2는 사용자가 수행하는 모든 크기를 유지합니다.

나쁜 행동의 예 : 열 2 (세 번째 열)의 크기를 조정하여 크기를 크게하려면; 열 1과 2 사이의 경계선을 잡고 왼쪽으로 왼쪽으로 테두리 1을 왼쪽으로 효과적으로 밀어 열 2를 더 크게 만들려고합니다. 그러나 컬럼 1이 축소되는 동안 컬럼 2는 동일하게 유지됩니다!

UPDATE

내 질문에 원하는 동작을 구현하는 방법이다. 무엇을 어디서 설정하거나 다시 구현해야합니까? SizeConfig을 맞춤 설정 하시겠습니까? 방법은 유망한 것으로 들린다 : calculatePercentages()calculateAvailableSpace(). 누가 언제 전화를합니까? 열 크기 조정 이벤트를 잡는 방법? 청취자를 어딘가에 설정해야합니까? NatTable에서 사용자 정의 된 SizeConfig을 사용하려면 어떻게해야합니까? 올바른 방향으로 가고 있습니까?

+0

언급 한 (측면) 문제에 대한 버그 보고서를 만들었습니다 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=516625. 내가 왜 NatTable이 기본 설정으로 이상하게 동작하는지, 왜 바닐라 ColumnResizeCommandHandler를 사용하여 내 예제의 첫 번째 열이 실제로 unresizable인지 알아 냈습니다. – Espinosa

답변

0

당신의 문제는 당신이 오른쪽에서 왼쪽으로 생각하려고한다는 것입니다. 그러나 크기 조정은 왼쪽에서 오른쪽으로 구현됩니다. 따라서 열 1과 2 사이의 경계를 가져 가면 열 2가 아닌 열 1의 크기를 조정할 수 있습니다. 방향은 중요하지 않습니다.

이는 잘 알려진 스프레드 시트 응용 프로그램과 비슷한 동작입니다. 경계선 사이의 핸들을 사용하면 오른쪽이 아닌 왼쪽으로 열의 크기가 조정됩니다.

+0

신속한 응답에 감사드립니다. 난 그냥 LibreOffice Calc와 SWT Tree로 테스트 해봤습니다. 왼쪽의 경계를 드래그하면서 왼쪽 컬럼을 축소시키면서 오른쪽으로 왼쪽으로 옮깁니다. 또한 스프레드 시트를 사용하여 제한된 경험을 할 때 모든 열은 사실 고정 된 유형 열이므로 비유가 제한적입니다. 어쨌든, 그것은 요점이 아닙니다. 원하는 동작을 구현하려면 어떻게해야합니까? – Espinosa

1

나는 그것을 스스로 알아 냈다. 결국 그것은 그다지 어렵지 않았습니다. 사용자 지정 ColumnResizeCommand 처리기를 등록하고 구현해야합니다.코드의 NatTable 창조 블록에

추가 :

bodyDataLayer.registerCommandHandler(
    new BetweenColumnResizeCommandHandler(bodyDataLayer)); 

그것은 어디서든 할 수있다, 내가 열이

이 기본값으로 설정되어있는 기본 BodyDataLayer 설정을 재정의를 정의 직후에 그것을 가지고 메서드에서 ColumnResizeCommandHandler 클래스입니다. 레지스터는 맵 기반이므로 반복적으로 오버라이드 될 수 있습니다. 레지스터는 클래스 명령 클래스 (이벤트를 나타내는)를 주어진 레이어 (이벤트/명령의 터미널 사용자)에 대한 작업 (처리기)에 매핑합니다.

여기 BetweenColumnResizeCommandHandler 클래스의 내 구현 :

import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler; 
import org.eclipse.nebula.widgets.nattable.layer.DataLayer; 
import org.eclipse.nebula.widgets.nattable.resize.command.ColumnResizeCommand; 
import org.eclipse.nebula.widgets.nattable.resize.command.ColumnResizeCommandHandler; 

/** 
* Customised version of {@link ColumnResizeCommandHandler}. 
* 
* It implements "between" resizing mode, that is border is moved between two 
* adjacent column only, having no effects on any other columns; that is any 
* gain in size of the left side column is lost in size for right side column 
* and vice versa. 
* 
* @author Espinosa 
*/ 
public class BetweenColumnResizeCommandHandler extends AbstractLayerCommandHandler<ColumnResizeCommand> { 

    private final DataLayer dataLayer; 

    public BetweenColumnResizeCommandHandler(DataLayer dataLayer) { 
     this.dataLayer = dataLayer; 
    } 

    @Override 
    public Class<ColumnResizeCommand> getCommandClass() { 
     return ColumnResizeCommand.class; 
    } 

    @Override 
    protected boolean doCommand(ColumnResizeCommand command) { 
     int leftSideColumn = command.getColumnPosition(); 
     int rightSideColumn = leftSideColumn + 1; 

     int oldLeftSideColumnWidth = this.dataLayer.getColumnWidthByPosition(leftSideColumn); 
     int newLeftSideColumnWidth = command.getNewColumnWidth(); 
     int dragWidth = newLeftSideColumnWidth - oldLeftSideColumnWidth; 
     // dragWidth has to be re-calculated back because it is lost in ColumnResizeCommandHandler :( 

     int oldRightSideColumnWidth = this.dataLayer.getColumnWidthByPosition(rightSideColumn); 
     int newRightSideColumnWidth = oldRightSideColumnWidth - dragWidth; 

     this.dataLayer.setColumnWidthByPosition(leftSideColumn, newLeftSideColumnWidth); 
     if (rightSideColumn < this.dataLayer.getColumnCount()) { 
      this.dataLayer.setColumnWidthByPosition(rightSideColumn, newRightSideColumnWidth); 
     } 
     return true; 
    } 
} 

.. 그리고 그것은 위의 예에 따라, 내가 원하는 무엇을 정확하게한다.

+0

그건 정확히 내 대답이었을거야. :) –

+0

@Dirk 열 정렬, 순서 변경 또는 열이 숨겨져있는 경우 내 솔루션이 작동하는지 확실하지 않습니다. 여전히 'rightSideColumn = leftSideColumn + 1'이됩니다. 또한 GUIHelper.convertVerticalDpiToPixel()을 올바르게 사용하는 방법을 모르겠습니다. '. 언제든지 검토하고, 의견을 개진하십시오! – Espinosa

+1

DataLayer에 IDragMode를 등록하면 DataLayer가 레이어 스택의 가장 아래쪽 레이어이기 때문에 숨겨진 열이나 재 배열 된 열을 알 수 없습니다. 그리고 위의 예제에서는'GUIHelper.convertVerticalDpiToPixel()'의 사용법을 보지 못했습니다. NatTable은'ColumnResizeDragMode'에서 내부적으로이를 사용하여 DPI 값에서 픽셀 값을 계산하기 위해 확대 된 디스플레이 해상도를 처리합니다. 당신이 그것을 위해 필요한 것을 확신하지 못합니다. –