문제

좋아, 간단한 맞춤 Jcomponent를 만드는 방법을 알고 있습니다. 나는 식탁보를 무시하는 방법을 알고 있습니다. 나는 둘을 결합 할 수없는 것 같다.

다음은 샘플입니다 JComponent 내가 만들었다:

public static class BarRenderer extends JComponent
{
    final private double xmin;
    final private double xmax;
    private double xval;
    public BarRenderer(double xmin, double xmax)
    {
        this.xmin=xmin;
        this.xmax=xmax;
    }

    @Override protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Rectangle r = g.getClipBounds();
        g.drawRect(r.x, r.y,
                (int)(r.width * ((xval-xmin)/(xmax-xmin))), r.height);
    }

    public void setXval(double x) { 
        this.xval = x;
        repaint();
    }
    public double getXval() { return xval; }
}

독립형 jcomponent로 잘 작동합니다. 나는 전화한다 setXval(something) 그리고 그것은 잘 업데이트됩니다. (편집 : 데이터를 정기적으로 업데이트하는 스윙 타이머가 있습니다)

그러나이 구성 요소가 TablecellRenderer.GetTableCellrenderComponent ()에서 반환하는 경우 문제의 셀을 클릭하면 다시 인쇄됩니다. 무엇을 제공합니까? 나는 정말로 간단한 것을 떠나야한다.

도움이 되었습니까?

해결책

성능의 이유로 jtable은 렌더러 구성 요소를 재사용하여 여러 셀을 페인트합니다. 따라서 JTable의 구성 요소를 볼 때 실제로 위치에있는 컨테이너의 구성 요소의 전통적인 의미에 있지 않습니다. 이것은 렌더러 구성 요소에서 Repaint ()을 호출하는 것이 아무것도하지 않음을 의미합니다.

가장 효과적인 옵션은 막대의 정수 값을 탁자에 저장하는 것입니다. Tablecellrenderer는 다음과 같이 보입니다.

public class BarTableCellRenderer implements TableCellRenderer {
    private final BarRenderer rendererComponent = new BarRenderer(0, 10);

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        rendererComponent.setXval((Integer)value);
        return rendererComponent;
    }
}

그런 다음 테이블 모드에서 정수를 변경하면 막대의 리 페인트를 트리거 할 수 있습니다 (테이블 모드가 필요할 수 있습니다. 파이어 블레 셀러드가 사용중인 테이블 모드 구현에 따라).

다른 팁

둘 다 (Russ Hayward와 Andrew)가 도움을 주었고, 열쇠는 본질적으로 다음을 수행하는 것이 었습니다.

  • 렌더러가 아닌 테이블 모드 자체에 보일 상태를 보관하십시오.
  • Tablemodel의 상태가 변할 때 fireTableCellUpdated() 호출됩니다
  • 만 가지고 있습니다 하나 Tablecellrenderer 객체 및 하나 내 사용자 정의 열의 jcomponent (셀당 하나가 아님)
    • 이내에 TableCellRenderer.getTableCellRendererComponent() 곧 렌더링 될 목적으로 셀의 상태를 저장합니다 (장기 저장소는 탁자에 있습니다)
    • 그 상태를 Jcomponent에게 제공하십시오
    • jcomponent를 반환하십시오
    • 우세하다 JComponent.PaintComponent()
  • 편리한 가능성 중 하나는 사용자 정의 렌더러가 jcomponent를 확장하고 Tablecellrenderer를 구현 한 다음 TableCellRenderer.getTableCellRendererComponent() 당신은 셀의 상태를 보관합니다 return this;

다음은 현재 작동하는 내 코드의 관련 발췌문입니다.

class TraceControlTableModel extends AbstractTableModel {
    /* handle table state here */

    // convenience method for setting bar value (table model's column 2)
    public void setBarValue(int row, double x)
    {
        setValueAt(x, row, 2);
    }
}

// one instance of BarRenderer will be set as the
// TableCellRenderer for table column 2
public static class BarRenderer extends JComponent 
    implements TableCellRenderer 
{
    final private double xmin;
    final private double xmax;
    private double xval;
    public BarRenderer(double xmin, double xmax)
    {
        super();
        this.xmin=xmin;
        this.xmax=xmax;
    }

    @Override protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Rectangle r = g.getClipBounds();
        g.drawRect(r.x, r.y,
                (int)(r.width * ((xval-xmin)/(xmax-xmin))), r.height);
    }

    @Override
    public Component getTableCellRendererComponent(JTable arg0,
            Object value, 
            boolean isSelected, boolean hasFocus,
            int row, int col)
    {
        // save state here prior to returning this object as a component
        // to be painted
        this.xval = (Double)value;
        return this;
    }
}

각각 다른 xval을 갖는 3 행으로 테이블을 만들면 처음에는 렌더러가 올바르게 올바르게 나타납니다. 즉, 각 셀에 다른 모양의 막대가 있습니다.

클릭하지 않으면 다시 칠하지 않는다고 말할 때, 데이터 (렌더링 된 막대)의 시각적 표시가 변경 될 수있는 기본 데이터에 어떤 일이 발생 했습니까?

데이터가 변경되었지만 테이블이 즉시 재 렌더링되지 않으면 Tablemodel이 제대로 작동하지 않는다고 말합니다.

기본 데이터 변경 -> Tablemodel 변경 -> Fires Tablemodelevent-> jtable Re -Renders

Tablemodel tuturial을보십시오 : http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#data

모든 일을 정확하게하고 있는지 확인합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top