2013-02-26 11 views
5

このilkの他の質問に対するJTable/JComboBoxの回答の大部分を読んだことがありますが、私の問題の解決策はまだ見つかりませんでした。JComboBoxがJTable TableHeaderで展開できない

私はJComboBox TableHeader要素を持つテーブルを作成しました。アイテムのリストを表示するためにJComboBoxのどの要素も開きません。表示する個々のJComboBox要素の項目リストを取得するにはどうすればよいですか?

この質問の特徴は、JComboBoxがTableHeaderにあり、JTableセルに埋め込まれていないことです。

何か助けていただければ幸いです。

SSCE

import java.awt.Component; 
import java.awt.Dimension; 
import java.util.Enumeration; 

import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.ListSelectionModel; 
import javax.swing.SwingUtilities; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumn; 

public class ComboHeaderTest extends JScrollPane { 

private static final Dimension DEFAULT_SIZE = new Dimension(200, 200); 

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

     @Override 
     public void run() { 
      new ComboHeaderTest().initComponents(); 
     } 
    }); 
} 

private ComboHeaderTest() { 

    final String[][] data = { {"Header 1", "Header 2", "Header 3"}, 
           {"A", "B", "C"}, 
           {"D", "E", "F"}, 
           {"G", "H", "I"}}; 

    setViewportView(getTable(data)); 
    setPreferredSize(DEFAULT_SIZE); 
} 

private void initComponents() { 

    JFrame frame = new JFrame("ComboHeaderTest"); 
    frame.add(this); 
    frame.pack(); 
    frame.setVisible(true); 
} 

private JTable getTable(final String[][] data) { 
    final String[] items = data[0]; 

    final ComboHeaderRenderer[] columnHeaders = new ComboHeaderRenderer[items.length]; 
    for(int i = 0; items.length > i; ++i) { 
     columnHeaders[i] = new ComboHeaderRenderer(items); 
    } 

    final JTable table = new JTable(data, columnHeaders); 

    final Enumeration<TableColumn> tableEnum = table.getColumnModel().getColumns(); 
    for (int columnIndex = 0; tableEnum.hasMoreElements(); ++columnIndex) { 
     final TableColumn column = tableEnum.nextElement(); 

     final ComboHeaderRenderer combo = columnHeaders[columnIndex]; 
     column.setHeaderValue(combo.getItemAt(columnIndex)); 
     column.setHeaderRenderer(combo); 
    } 

    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    table.setRowSelectionAllowed(true); 
    table.setColumnSelectionAllowed(false); 
    table.setCellSelectionEnabled(false); 
    table.setFillsViewportHeight(true); 

    table.setSize(DEFAULT_SIZE); 
    table.validate(); 

    return table; 
} 

private static class ComboHeaderRenderer extends JComboBox implements TableCellRenderer{ 
    public ComboHeaderRenderer(final String[] entries) { 
     for (int i = 0; entries.length > i; ++i) { 
      addItem(entries[i]); 
     } 
    } 

    @Override 
    public Component getTableCellRendererComponent(final JTable table, final Object value, 
      final boolean isSelected, final boolean hasFocus, final int row, final int column) { 
     setSelectedItem(value); 
     return this; 
    } 
} 
} 
+0

+1。 – mre

+0

無関係:a)[setXXSizeを使用しない](http://stackoverflow.com/a/7229519/203657)b)JSomethingを使用して同じ目標に到達できる場合、JSomethingを拡張しないc)setSizeは何も効果がないか、基本的に間違っている(LayoutManagerを使用していない) – kleopatra

+1

@kleopatra - 私はあなたが提案したように継承を超える構成を好みます。私はこれをテストベッドとして使用して、JComboBoxの展開を妨げていたものを発見しました。そのため、LayoutManagerはありません。シンプルなSSCCEを維持しようとしています。 – Todd

答えて

4

これは実際には期待どおりに動作します。私はその手がかりがTableCellRendererだと思う。

レンダラーは通常、非インタラクティブなコンポーネントです。これらは通常、サーフェスに塗りつぶされたコンポーネントの「スナップショット」であり、通常はユーザーがそれらとやりとりする方法はありません。

これは予期された動作です。

テーブルヘッダに編集可能な機能性を供給するために、あなたはJTableHeader

の実装を提供する必要があるとしているが、いくつかのアイデア

+0

この[Q&A](http://stackoverflow.com/q/7137786/230513)も参照してください。 – trashgod

+0

@MadProgrammer - それを明確にしてくれてありがとう。レンダラーは、視覚的な面だけでなく、完全に機能的な要素をレンダリングすると考えました。 – Todd

+0

@trashgod - 私は投稿する前にそのアイテムを見ていましたが、ヘッダーではなくテーブルセルに基づいて解決策を提供するように解釈しましたが、元のトピックはヘッダーに関するものでした。今私が間違っていることがわかります。ありがとう。 – Todd

0

Hereため、このexampleを見ている例であるがありますJTable TableHeaderでJComboBoxを使用します。

他のタイプのコンポーネントについては、より簡単です。hereをご覧ください。最初に頼まれることなくSSCCEを含むため

enter image description here