2016-08-19 8 views
0

行ヘッダーと列ヘッダーを含むテーブルを含むJFrameが必要です。 私のテーブルは、3つのパネル(行ヘッダー、列ヘッダー、およびグリッド)で構成されたカスタムコンポーネントです。 パネルは、MigLayoutにJButtonまたはJLabelのいずれかを含む通常のJPanelです。 グリッドとヘッダーを同時にスクロールするために、このコンポーネントをJScrollPane内に表示します。 この部分はうまく動作します。ヘッダーを含むJScrollPaneを拡大する

これで、ユーザーは自分のコンポーネントをズームすることができます。

私はpbjar JXLayerを使用しようとしましたが、レイヤー内にJScrollPane全体を配置すると、すべてが拡大され、イベントはスクロールバーになります。

JScrollPaneの各viewPortに1つずつ、3つのJXLayersを使用しようとしました。しかし、このソリューションは、ビューポート内のパネルが左上に配置されるのではなく、中央に配置されるので、私のレイアウトをちょっと混乱させます。

import org.jdesktop.jxlayer.JXLayer; 
import org.pbjar.jxlayer.demo.TransformUtils; 
import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel; 

public class Matrix extends JScrollPane { 

    private Grid grid; 
    private Header rowHeader; 
    private Header columnHeader; 

    private DefaultTransformModel zoomTransformModel; 
    private double zoom = 1; 

    public Matrix() { 
     super(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 

     this.zoomTransformModel1 = new DefaultTransformModel(); 
     this.zoomTransformModel1.setScaleToPreferredSize(true); 
     this.zoomTransformModel1.setScale(1); 
     this.zoomTransformModel2 = new DefaultTransformModel(); 
     this.zoomTransformModel2.setScaleToPreferredSize(true); 
     this.zoomTransformModel2.setScale(1); 
     this.zoomTransformModel3 = new DefaultTransformModel(); 
     this.zoomTransformModel3.setScaleToPreferredSize(true); 
     this.zoomTransformModel3.setScale(1); 

     this.grid = new Grid(); 

     this.setViewportView(TransformUtils.createTransformJXLayer(this.grid, 
       zoomTransformModel1);); 
     this.matrixRowHeader = new Header(Orientation.VERTICAL); 
     this.setRowHeader(new JViewport(
       TransformUtils.createTransformJXLayer(
        this.rowHeader, zoomTransformModel2))); 

     this.matrixColumnHeader = new Header(Orientation.HORIZONTAL); 
     this.setColumnHeader(new JViewport(
       TransformUtils.createTransformJXLayer(
        this.columnHeader, zoomTransformModel2))); 
    } 

    public void setScale(double scale) { 
     this.zoomTransformModel1.setScale(scale); 
     this.zoomTransformModel2.setScale(scale); 
     this.zoomTransformModel3.setScale(scale); 
    } 
} 

どのように私は、スクロールバー上のズームせずに、私のレイアウトをめちゃくちゃせずに私の側JScrollPane上のズームを扱うことができますか?

答えて

0

まず、MigLayoutはJXLayerと互換性がないようです。両方を使用している場合、MigLayoutを使用するパネルのコンポーネントは予測できない動作をします。

元のpbjar JXLayerでは、レイヤーペインの中央にコンポーネントを配置することしかできません。 Pbjarソースはon githubをダウンロードできます。これは公式のPiet Blokリポジトリではないことに注意してください。

Iが見出さ溶液はTransformLayoutを変更することで、TransformUI、及びTranformModelクラス:

Alignment列挙は、層中の成分のための可能な整列を与えます。

TransformLayout
public enum Alignment { 
    TOP, 
    BOTTOM, 
    LEFT, 
    RIGHT, 
    CENTER 
} 

TransformUI
@Override 
public void layoutContainer(Container parent) { 
    JXLayer<?> layer = (JXLayer<?>) parent; 
    LayerUI<?> layerUI = layer.getUI(); 
    if (layerUI instanceof CustomTransformUI) { 
     JComponent view = (JComponent) layer.getView(); 
     JComponent glassPane = layer.getGlassPane(); 
     if (view != null) { 
     Rectangle innerArea = new Rectangle(); 
     SwingUtilities.calculateInnerArea(layer, innerArea); 
     view.setSize(view.getPreferredSize()); 
     Rectangle viewRect = new Rectangle(0, 0, view.getWidth(), view 
      .getHeight()); 
     int x; 
     int y; 
     Alignment alignX = ((CustomTransformUI) layerUI).getAlignX(); 
     Alignment alignY = ((CustomTransformUI) layerUI).getAlignY(); 
     if(alignX == Alignment.LEFT) { 
      x = (int) (innerArea.getX() - viewRect.getX()); 
     } else if(alignX == Alignment.RIGHT) { 
      x = (int) (innerArea.getX()+innerArea.getWidth()-viewRect.getWidth()-viewRect.getX()); 
     } else { 
      x = (int) Math.round(innerArea.getCenterX() 
        - viewRect.getCenterX()); 
     } 
     if(alignY == Alignment.TOP) { 
      y = (int) (innerArea.getY() - viewRect.getY()); 
     } else if(alignY == Alignment.BOTTOM) { 
      y = (int) (innerArea.getY()+innerArea.getHeight()-viewRect.getHeight()-viewRect.getY()); 
     } else { 
      y = (int) Math.round(innerArea.getCenterY() 
        - viewRect.getCenterY()); 
     } 
     viewRect.translate(x, y); 
     view.setBounds(viewRect); 

     } 
     if (glassPane != null) { 
     glassPane.setLocation(0, 0); 
     glassPane.setSize(layer.getWidth(), layer.getHeight()); 
     } 
     return; 
    } 
    super.layoutContainer(parent); 
} 

TransformModel
private Alignment alignX; // horizontal alignment 
private Alignment alignY; // verticalalignment 

public TransformUI(TransformModel model, Alignment alignX, Alignment alignY) { 
    super(); 
    this.setModel(model); 
    this.alignX = alignX; 
    this.alignY = alignY; 
} 

public Alignment getAlignX() { 
    return alignX; 
} 

public Alignment getAlignY() { 
    return alignY; 
} 

private Alignment alignX = Alignment.CENTER; 
private Alignment alignY = Alignment.CENTER; 

public CustomTransformModel(Alignment alignX, Alignment alignY) { 
    super(); 
    this.alignX = alignX; 
    this.alignY = alignY; 
} 

@Override 
public AffineTransform getTransform(JXLayer<? extends JComponent> layer) { 
    JComponent view = (JComponent)layer.getView(); 
    /* 
    * Set the current actual program values in addition to the user 
    * options. 
    */ 
    this.setValue(Type.LayerWidth, layer == null ? 0 : layer.getWidth()); 
    this.setValue(Type.LayerHeight, layer == null ? 0 : layer.getHeight()); 
    this.setValue(Type.ViewWidth, view == null ? 0 : view.getWidth()); 
    this.setValue(Type.ViewHeight, view == null ? 0 : view.getHeight()); 
    /* 
    * If any change to previous values, recompute the transform. 
    */ 
    if (!Arrays.equals(this.prevValues, this.values)) { 
     System.arraycopy(this.values, 0, this.prevValues, 0, this.values.length); 
     this.transform.setToIdentity(); 
     if (view != null) { 
      double scaleX; 
      double scaleY; 
      double centerX; 
      if(this.alignX == Alignment.LEFT) { 
       centerX = 0.0; 
      } else if (this.alignX == Alignment.RIGHT){ 
       centerX = layer == null ? 0.0 : (double)layer.getWidth(); 
      } else { 
       centerX = layer == null ? 0.0 : (double)layer.getWidth()/2.0; 
      } 
      double centerY; 
      if(this.alignY == Alignment.TOP) { 
       centerY = 0.0; 
      } else if(this.alignY == Alignment.BOTTOM){ 
       centerY = layer == null ? 0.0 : (double)layer.getHeight(); 
      } else { 
       centerY = layer == null ? 0.0 : (double)layer.getHeight()/2.0; 
      } 
      AffineTransform nonScaledTransform = this.transformNoScale(centerX, centerY); 
      if (((Boolean)this.getValue(Type.ScaleToPreferredSize)).booleanValue()) { 
       scaleY = scaleX = ((Double)this.getValue(Type.PreferredScale)).doubleValue(); 
      } else { 
       Area area = new Area(new Rectangle2D.Double(0.0, 0.0, view.getWidth(), view.getHeight())); 
       area.transform(nonScaledTransform); 
       Rectangle2D bounds = area.getBounds2D(); 
       scaleX = layer == null ? 0.0 : (double)layer.getWidth()/bounds.getWidth(); 
       scaleY = layer == null ? 0.0 : (double)layer.getHeight()/bounds.getHeight(); 
       if (((Boolean)this.getValue(Type.PreserveAspectRatio)).booleanValue()) { 
        scaleY = scaleX = Math.min(scaleX, scaleY); 
       } 
      } 
      this.transform.translate(centerX, centerY); 
      this.transform.scale((Boolean)this.getValue(Type.Mirror) != false ? - scaleX : scaleX, scaleY); 
      this.transform.translate(- centerX, - centerY); 
      this.transform.concatenate(nonScaledTransform); 
     } 
    } 
    return this.transform; 
} 

あなたは今設定でズーム可能なパネルを作成することができます調整可能なアライメント:

TransformModel model = new TransformModel(Alignment.LEFT, Alignment.TOP); 
TransformUI ui = new TransformUI(model, Alignment.LEFT, Alignment.TOP); 
new JXLayer((Component)component, (LayerUI)ui) 

これはクイックフィックスです。それはおそらく改善することができます。

関連する問題