2013-02-26 10 views
5

Ich habe die Mehrheit der JTable/JComboBox Antworten auf andere Fragen dieser Art gelesen, aber habe noch keine Lösung für mein Problem gefunden.JComboBox kann in JTable TableHeader nicht erweitert werden

Ich habe eine Tabelle mit JComboBox TableHeader-Elementen erstellt. Keines der JComboBox-Elemente wird geöffnet, um eine Liste von Elementen anzuzeigen. Wie bekomme ich die Artikellisten für die einzelnen JComboBox-Elemente zur Anzeige?

Bitte beachten Sie, dass ein Unterscheidungsmerkmal dieser Frage darin besteht, dass die JComboBox im TableHeader liegt und nicht in eine JTable-Zelle eingebettet ist.

Jede Hilfe wird geschätzt.

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 für die Aufnahme eines SSCCE, ohne vorher gefragt zu haben. – mre

+0

in keinem Zusammenhang: a) [nicht verwenden setXXSize] (http://stackoverflow.com/a/7229519/203657) b) keine JSomething verlängern, wenn Sie das gleiche Ziel durch den Einsatz erreichen kann es c) setSize hat entweder keine Wirkung oder Sie tun etwas grundsätzlich falsch (indem Sie keinen LayoutManager verwenden) – kleopatra

+1

@kleopatra - Ich bevorzuge Zusammensetzung über Vererbung, wie Sie vorschlagen. Ich nutzte dies als Testumgebung, um herauszufinden, was die JComboBox daran hinderte, sich zu entfalten, also keinen LayoutManager. Ich versuche nur, das Einfache in SSCCE zu behalten. – Todd

Antwort

4

Genau dies tatsächlich funktioniert wie erwartet. Ich denke, der Schlüssel ist TableCellRenderer.

Renderer sind normalerweise nicht interaktive Komponenten. Sie sind normalerweise nur ein "Schnappschuss" der Komponente, die auf eine Oberfläche gemalt wird, und es gibt normalerweise keine Möglichkeit für einen Benutzer, mit ihnen zu interagieren.

Dies ist das erwartete Verhalten.

Um editierbare Funktionalität auf den Tabellenkopf zu liefern, werden Sie Ihre Implementierung eines JTableHeader

Werfen Sie einen Blick auf diese example für einige Ideen

+0

Siehe auch dieses [Q & A] (http://stackoverflow.com/q/7137786/230513). – trashgod

+0

@MadProgrammer - danke für die Klärung, dass für mich. Ich dachte, ein Renderer würde eine vollständig funktionale Komponente darstellen, nicht nur seine visuellen Aspekte. – Todd

+0

@trashgod - ich hatte zu diesem Artikel vor der Veröffentlichung gesucht, aber ich deutete es, eine Lösung auf die Tabellenzellen auf Basis zur Verfügung zu stellen, nicht der Kopf, obwohl das ursprüngliche Thema über den Header war. Ich sehe jetzt, dass ich falsch war. Vielen Dank. – Todd

0

Here ist ein Beispiel müssen gehen liefern, verwendet eine JComboBox in einem JTable TableHeader.

Für andere Arten von Komponenten ist einfacher, werfen Sie einen Blick here.

enter image description here

Verwandte Themen