2013-02-26 28 views
5

Tôi đã đọc qua phần lớn các câu trả lời của JTable/JComboBox cho các câu hỏi khác về ilk này, nhưng chưa tìm ra giải pháp cho vấn đề của tôi.JComboBox không mở rộng trong JTable TableHeader

Tôi đã tạo một bảng có các phần tử TableHeader JComboBox. Không có phần tử JComboBox nào sẽ mở ra để hiển thị danh sách các mục. Làm thế nào để có được danh sách các mục cho các phần tử JComboBox riêng lẻ để hiển thị?

Xin lưu ý rằng yếu tố phân biệt của câu hỏi này là JComboBox nằm trong TableHeader, không được nhúng trong một ô JTable.

Mọi trợ giúp đều được đánh giá cao.

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 để bao gồm SSCCE mà không cần phải được hỏi trước. – mre

+0

không liên quan: a) [không sử dụng setXXSize] (http://stackoverflow.com/a/7229519/203657) b) không mở rộng một JSomething nếu bạn có thể đạt được cùng một mục tiêu bằng cách sử dụng nó c) setSize có một trong hai không có hiệu lực hoặc bạn đang làm một cái gì đó về cơ bản sai (bằng cách không sử dụng một LayoutManager) – kleopatra

+1

@ kleopatra - Tôi thích thành phần hơn thừa kế như bạn đề nghị. Tôi đã sử dụng điều này như một chiếc giường thử nghiệm để khám phá những gì đã ngăn chặn JComboBox từ việc mở ra, do đó, không có LayoutManager. Chỉ cần cố gắng giữ cho Simple trong SSCCE. – Todd

Trả lời

4

này thực sự hoạt động chính xác như mong đợi. Tôi nghĩ đầu mối là TableCellRenderer.

Trình kết xuất thường là các thành phần không tương tác. Chúng thường chỉ là "snap-shot" của thành phần được vẽ trên bề mặt và thường không có cách nào để người dùng tương tác với chúng.

Đây là hành vi mong đợi.

Để cung cấp chức năng chỉnh sửa tiêu đề bảng, bạn sẽ cần phải cung cấp thực hiện của bạn của một JTableHeader

Có một cái nhìn tại example này cho một số ý tưởng

+0

Xem thêm [Hỏi đáp] này (http://stackoverflow.com/q/7137786/230513). – trashgod

+0

@MadProgrammer - cảm ơn vì đã làm rõ điều đó đối với tôi. Tôi nghĩ rằng một trình kết xuất sẽ hiển thị một thành phần hoàn toàn chức năng, không chỉ các khía cạnh trực quan của nó. – Todd

+0

@trashgod - Tôi đã xem mục đó trước khi đăng, nhưng tôi đã giải thích nó để cung cấp giải pháp dựa trên các ô bảng, không phải là tiêu đề, mặc dù chủ đề ban đầu là về tiêu đề. Tôi thấy bây giờ tôi đã sai. Cảm ơn. – Todd

0

Here là một ví dụ mà sử dụng một JComboBox trong một Table Table Jeader.

Đối với các loại linh kiện khác dễ hơn, hãy xem here.

enter image description here

Các vấn đề liên quan