1

JTable に 2 つのタイプを表示する必要がある列があります: String OR ImageIcon、両方ではありません。その列の各セルには、データを計算する独自のスレッドがあります。最初に、各セルに画像(待機中のロゴなど)を配置し、次に画像を計算されたデータの文字列で置き換えます(追加しません)。デフォルトの TableCell レンダラーを拡張してみましたが、オブジェクトのアドレス(javax.swing.ImageIcon@342...)のように画像を表示し、文字列に置き換えます。別のバリアントで、画像を正しく表示しますが、空の文字列に置き換えます (または表示されませんか?)。

タイプに応じてテーブルがセルの内容を正しく表示するように設定する方法は?

現時点で私が持っているものは次のとおりです。

class IconAndStringRenderer extends DefaultTableCellRenderer {

private static final long serialVersionUID = 3606788739290618405L;

public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column) {
    super.getTableCellRendererComponent(table, value,
                          isSelected, hasFocus, row, column);
    if (value instanceof Icon) {

      setIcon((Icon) value);
      setText("");
    } 
    return this;
  }
}

Jテーブルは次のとおりです。

テーブル = 新しい JTable(モデル) {

        private static final long serialVersionUID = 8058795799817761161L;

        public Class<?> getColumnClass(int column) {
            if (column == TARGET_COLUMN)
                return ImageIcon.class;
            else
                return super.getColumnClass(column);
        }
    };

さらにいくつかの質問:

  1. 画像の後にテキストを書き込むのではなく、テキストが画像を置き換えるように設定する方法 (表示されていなくても);

  2. 文字色の設定方法 setForebackground(Color c) を使うのですが、これを使うと画像が表示されません。

  3. Jlabelで動作させることは可能ですか? セルを変更するスレッドで必要な Jlabel (画像またはテキストを含む) を設定し、setValueAt(ラベル、行、列);

4

3 に答える 3

2

デフォルトのレンダラーは、文字列とアイコンの両方を表示する方法を知っています。あなたがしなければならないのは、あなたがそれぞれ、、、から正しいクラスを返すことを確認することTableModelです。例はここにあります。getColumnClass()String.classIcon.class

補遺:デフォルトの実装に基づいて、原則を説明するための最小限の例を次に示します。

補遺:同じ列に対して異なるクラスを返す必要がある場合に機能するかどうかはわかりません

セルごとにレンダラーを本当に選択する必要がある場合は、ここprepareRenderer()に示すように、をオーバーライドします。

画像

import java.awt.EventQueue;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

/** @see https://stackoverflow.com/a/14672312/230513 */
public class Test {

    private static final Icon YES = UIManager.getIcon("InternalFrame.maximizeIcon");
    private static final Icon NO = UIManager.getIcon("InternalFrame.closeIcon");

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DefaultTableModel model = new DefaultTableModel(
            new Object[]{"Name", "Icon"}, 0) {

            @Override
            public Class<?> getColumnClass(int col) {
                if (col == 1) {
                    return Icon.class;
                } else {
                    return super.getColumnClass(col);
                }
            }
        };
        model.addRow(new Object[]{"One", YES});
        model.addRow(new Object[]{"Two", NO});
        final JTable table = new JTable(model);
        table.setRowHeight(YES.getIconHeight() +2);
        f.add(table);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}
于 2013-02-03T12:10:41.333 に答える
2

You need a custom renderer which can understand both types you use.

For example

public class IconAndStringRenderer extends DefaultTableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value,
                          boolean isSelected, boolean hasFocus, int row, int column) {
    super.getTableCellRendererComponent(table, value,
                          isSelected, hasFocus, row, column);
    if (value instanceof Icon) {
      setText("");
      setIcon((Icon) value);
    }
    return this;
  }
}

Try to set this class as your column renderer

于 2013-02-03T10:52:18.247 に答える
2

デフォルトのレンダラーを利用するには、JTable の getCellRenderer(...) メソッドをオーバーライドして、適切なレンダラーを返すことができます。何かのようなもの:

public TableCellRenderer getCellRenderer(int row, int column)
{
    int modelColumn = convertColumnIndexToModel(column);

    if (modelColumn == ???)
    {
        Class rowClass = getModel().getValueAt(row, modelColumn).getClass();
        return getDefaultRenderer( rowClass );
    }
    else
        return super.getCellRenderer(row, column);
}
于 2013-02-03T18:42:16.613 に答える