2012-10-26 61 views
5

thể trùng lặp:
Accessing a JTextField in JTableHeaderEditable JTableHeader

Làm thế nào để làm cho JTableHeader như thể chỉnh sửa. F.e. tôi làm cho ColumnHeader là JTextField. Tôi phải làm gì để có thể chỉnh sửa JTextField. Xem ví dụ:

import java.awt.*; 
import javax.swing.*; 

import javax.swing.table.*; 

import java.awt.event.*; 

public class Test extends JFrame { 

String[][] cellValues = { { "v00", "v01", "v02" }, { "v10", "v11", "v12" }, 
     { "v20", "v21", "v22" }, { "v30", "v31", "v32" }, 
     { "v40", "v41", "v42" }, { "v50", "v51", "v52" } }; 
String[] columnNames = { "v00", "v01", "v02" }; 

javax.swing.JTable jTable1 = new javax.swing.JTable(cellValues, columnNames); 

public Test() { 
    try { 
     jbInit(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private void jbInit() throws Exception { 
    this.getContentPane().add(new JScrollPane(jTable1), null); 
    for (int i = 0; i < 3; i++) 
     jTable1.getColumnModel().getColumn(i) 
       .setHeaderRenderer(new Renderer()); 
} 

public static void main(String[] args) { 
    Test frame = new Test(); 
    frame.addWindowListener(new java.awt.event.WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
      System.exit(0); 
     } 
    }); 
    frame.pack(); 
    frame.setVisible(true); 
} 

} 

class Renderer extends JPanel implements TableCellRenderer { 

JLabel label = new JLabel(" "); 
JTextField field = new JTextField("%"); 

public Renderer() { 
    super(new BorderLayout()); 
    add(label, BorderLayout.NORTH); 
    add(field, BorderLayout.CENTER); 
    setBorder(BorderFactory.createEtchedBorder()); 
} 

public Component getTableCellRendererComponent(JTable table, Object value, 
     boolean isSelected, boolean hasFocus, int row, int column) { 
    label.setText(value.toString()); 
    return (JComponent) this; 
} 

public String toString() { 
    return label.toString(); 
} 

public void setText(String text) { 
    label.setText(text); 
} 

} 
+2

Cũng xem [Truy cập vào một JTextField trong JTableHeader] (http://stackoverflow.com/q/ 12598180/1048330) – tenorsax

+1

Cũng như các [báo trước] hữu ích này (http://stackoverflow.com/a/7146216/230513). – trashgod

Trả lời

6

Dưới đây là một phương pháp đơn giản để làm tiêu đề có thể chỉnh sửa (không kết xuất đồ họa tùy chỉnh hoặc UIS bắt buộc):

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.table.*; 

public class JTableEditableHeaderDemo implements Runnable 
{ 
    private JTable table; 
    private JTableHeader header; 
    private JPopupMenu renamePopup; 
    private JTextField text; 
    private TableColumn column; 

    public static void main(String[] args) 
    { 
    SwingUtilities.invokeLater(new JTableEditableHeaderDemo()); 
    } 

    public JTableEditableHeaderDemo() 
    { 
    table = new JTable(10, 5); 
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
    table.setPreferredScrollableViewportSize(table.getPreferredSize()); 

    header = table.getTableHeader(); 
    header.addMouseListener(new MouseAdapter(){ 
     @Override 
     public void mouseClicked(MouseEvent event) 
     { 
     if (event.getClickCount() == 2) 
     { 
      editColumnAt(event.getPoint()); 
     } 
     } 
    }); 

    text = new JTextField(); 
    text.setBorder(null); 
    text.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
     renameColumn(); 
     } 
    }); 

    renamePopup = new JPopupMenu(); 
    renamePopup.setBorder(new MatteBorder(0, 1, 1, 1, Color.DARK_GRAY)); 
    renamePopup.add(text); 
    } 

    public void run() 
    { 
    JFrame f = new JFrame("Double-click header to edit"); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.getContentPane().add(new JScrollPane(table)); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 

    private void editColumnAt(Point p) 
    { 
    int columnIndex = header.columnAtPoint(p); 

    if (columnIndex != -1) 
    { 
     column = header.getColumnModel().getColumn(columnIndex); 
     Rectangle columnRectangle = header.getHeaderRect(columnIndex); 

     text.setText(column.getHeaderValue().toString()); 
     renamePopup.setPreferredSize(
      new Dimension(columnRectangle.width, columnRectangle.height - 1)); 
     renamePopup.show(header, columnRectangle.x, 0); 

     text.requestFocusInWindow(); 
     text.selectAll(); 
    } 
    } 

    private void renameColumn() 
    { 
    column.setHeaderValue(text.getText()); 
    renamePopup.setVisible(false); 
    header.repaint(); 
    } 
} 
+0

Nó chỉ hoạt động với JTextFields. Nếu tôi cố gắng làm điều tương tự với combobox, thì danh sách thả xuống sẽ không được hiển thị đúng cách. – Benas

+0

@Benas, Đó là bởi vì bạn đang cố gắng đặt một 'JComboBox' trên một' JPopupMenu', đó là một vấn đề riêng biệt hoàn toàn. Tôi khuyên bạn nên tìm kiếm diễn đàn cho câu trả lời đó hoặc bắt đầu một câu hỏi riêng. – splungebob