標準のJTableを作成したいのですが、すべての行が1つの特定の列にまたがっています。そのため、その列には、レンダラーとしてJTextPaneを含むセルが1つだけ含まれている必要があります。あなたはそれをする簡単な方法を知っていますか?
注意:サードパーティのソフトウェアは必要ありません。
ありがとう。
@MvG のある種のオーバーレイのアイデアによってトリガーされたのは、JLayer を使用した概念実証です (jdk7 でコアに追加されました。以前のバージョンでは、SwingLabsで非常によく似た JXLayer を使用します)。
基本的な成分:
少なくともそれを機能させるのは驚くほど簡単です。ただし、いくつかの粗いエッジがあります。
いくつかのコード:
public static class RowSpanUI extends LayerUI<JTable> {
public static String COLUMN_TO_SPAN_KEY = "Table.columnToSpan";
private JLayer layer;
private JTextArea area;
@Override
public void installUI(JComponent c) {
super.installUI(c);
this.layer = (JLayer) c;
installTextArea();
installListeners();
}
@Override
public void doLayout(JLayer<? extends JTable> l) {
super.doLayout(l);
l.getGlassPane().doLayout();
}
private void installTextArea() {
area = new JTextArea(10, 20);
layer.getGlassPane().setBorder(BorderFactory.createLineBorder(Color.RED));
layer.getGlassPane().setLayout(new ColumnLayoutManager(this));
layer.getGlassPane().add(area);
layer.getGlassPane().setVisible(true);
}
public JTable getView() {
return (JTable) layer.getView();
}
public int getViewColumnToSpan() {
Object clientProperty = getView().getClientProperty(COLUMN_TO_SPAN_KEY);
if (clientProperty instanceof Integer) {
return getView().convertColumnIndexToView((int) clientProperty);
}
return -1;
}
/**
* Install listeners to manually trigger a layout of the glassPane.
* This is incomplete, just the minimum for demonstration!
*/
protected void installListeners() {
ComponentListener compL = new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
doLayout(layer);
}
@Override
public void componentResized(ComponentEvent e) {
doLayout(layer);
}
@Override
public void componentMoved(ComponentEvent e) {
doLayout(layer);
}
@Override
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
};
layer.addComponentListener(compL);
TableColumnModelListener columnL = new TableColumnModelListener() {
@Override
public void columnRemoved(TableColumnModelEvent e) {
doLayout(layer);
}
@Override
public void columnMoved(TableColumnModelEvent e) {
doLayout(layer);
}
@Override
public void columnMarginChanged(ChangeEvent e) {
doLayout(layer);
}
@Override
public void columnAdded(TableColumnModelEvent e) {
doLayout(layer);
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
};
getView().getColumnModel().addColumnModelListener(columnL);
}
}
public static class ColumnLayoutManager implements LayoutManager {
private RowSpanUI ui;
public ColumnLayoutManager(RowSpanUI ui) {
this.ui = ui;
}
@Override
public void layoutContainer(Container parent) {
Component child = parent.getComponent(0);
child.setBounds(getColumnBounds());
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return ui.getView().getSize();
}
protected Rectangle getColumnBounds() {
int viewColumn = ui.getViewColumnToSpan();
if (viewColumn < 0) {
return new Rectangle();
}
Rectangle r = ui.getView().getCellRect(0, viewColumn, false);
r.height = ui.getView().getHeight();
return r;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
}
// usage
JTable table = new JTable(myModel);
table.putClientProperty(RowSpanUI.COLUMN_TO_SPAN_KEY, 2);
JLayer layer = new JLayer(table, new RowSpanUI());
セルの四角形へのクリッピングを含むのレンダリングは、問題のプラグイン可能なルック アンド フィールのユーザー インターフェイス実装JTable
の奥深くに埋もれています。物事を変更すると厄介なビジネスになり、実際の JFC の実装に大きく依存します。
代わりに、それらの卵のセルを好きなように描画し、テーブルの上に別の透明なペインを用意して、説明したスパンされたコンテンツでそれらの領域をオーバーレイすることをお勧めします. まだ厄介で、おそらくかなりの作業ですが、移植可能になる可能性が高くなります。