
एक कस्टम TableCellRenderer का उपयोग प्रदान की रखने बदसूरत लग जाता है:
// column 1
col = table.getColumnModel().getColumn(1);
col.setHeaderRenderer(new EditableHeaderRenderer(new JButton("Button")));
// column 2
col = table.getColumnModel().getColumn(2);
col.setHeaderRenderer(new EditableHeaderRenderer(new JToggleButton("Toggle")));
// column 3
col = table.getColumnModel().getColumn(3);
col.setHeaderRenderer(new EditableHeaderRenderer(new JCheckBox("CheckBox")));
class EditableHeaderRenderer implements TableCellRenderer {
private JTable table = null;
private MouseEventReposter reporter = null;
private JComponent editor;
EditableHeaderRenderer(JComponent editor) {
this.editor = editor;
this.editor.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
if (table != null && this.table != table) {
this.table = table;
final JTableHeader header = table.getTableHeader();
if (header != null) {
this.editor.setForeground(header.getForeground());
this.editor.setBackground(header.getBackground());
this.editor.setFont(header.getFont());
reporter = new MouseEventReposter(header, col, this.editor);
header.addMouseListener(reporter);
}
}
if (reporter != null) reporter.setColumn(col);
return this.editor;
}
static public class MouseEventReposter extends MouseAdapter {
private Component dispatchComponent;
private JTableHeader header;
private int column = -1;
private Component editor;
public MouseEventReposter(JTableHeader header, int column, Component editor) {
this.header = header;
this.column = column;
this.editor = editor;
}
public void setColumn(int column) {
this.column = column;
}
private void setDispatchComponent(MouseEvent e) {
int col = header.getTable().columnAtPoint(e.getPoint());
if (col != column || col == -1) return;
Point p = e.getPoint();
Point p2 = SwingUtilities.convertPoint(header, p, editor);
dispatchComponent = SwingUtilities.getDeepestComponentAt(editor, p2.x, p2.y);
}
private boolean repostEvent(MouseEvent e) {
if (dispatchComponent == null) {
return false;
}
MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent);
dispatchComponent.dispatchEvent(e2);
return true;
}
@Override
public void mousePressed(MouseEvent e) {
if (header.getResizingColumn() == null) {
Point p = e.getPoint();
int col = header.getTable().columnAtPoint(p);
if (col != column || col == -1) return;
int index = header.getColumnModel().getColumnIndexAtX(p.x);
if (index == -1) return;
editor.setBounds(header.getHeaderRect(index));
header.add(editor);
editor.validate();
setDispatchComponent(e);
repostEvent(e);
}
}
@Override
public void mouseReleased(MouseEvent e) {
repostEvent(e);
dispatchComponent = null;
header.remove(editor);
}
}
}
कृपया ध्यान दें कि popupmenu (जैसे JComboBox या JMenu) के साथ घटक अच्छी तरह से काम नहीं करते हैं। देखें: JComboBox fails to expand in JTable TableHeader)। लेकिन आप TableHeader में एक MenuButton उपयोग कर सकते हैं:

class MenuButtonTableHeaderRenderer extends JPanel implements TableCellRenderer {
private int column = -1;
private JTable table = null;
private MenuButton b;
MenuButtonTableHeaderRenderer(String name, JPopupMenu menu) {
super(new BorderLayout());
b = new MenuButton(ResourceManager.ARROW_BOTTOM, menu);
b.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
JLabel l = new JLabel(name);
l.setFont(l.getFont().deriveFont(Font.PLAIN));
l.setBorder(BorderFactory.createEmptyBorder(1,5,1,1));
add(b, BorderLayout.WEST);
add(l, BorderLayout.CENTER);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
if (table != null && this.table != table) {
this.table = table;
final JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int col = header.getTable().columnAtPoint(e.getPoint());
if (col != column || col == -1) return;
int index = header.getColumnModel().getColumnIndexAtX(e.getPoint().x);
if (index == -1) return;
setBounds(header.getHeaderRect(index));
header.add(MenuButtonTableHeaderRenderer.this);
validate();
b.doClick();
header.remove(MenuButtonTableHeaderRenderer.this);
header.repaint();
}
});
}
}
column = col;
return this;
}
}
हम्म ... वास्तव में क्या सवाल है, विशेष रूप से, क्या आप अच्छी तरह से व्यवहार मतलब है है? हम सभी जानते हैं कि शीर्षलेख में "लाइव" घटकों के लिए कोई समर्थन नहीं है, सभी को स्वयं द्वारा किया जाना चाहिए :-) टॉगल बटन का उपयोग करने के लिए, यह नहीं पता कि उपयोगकर्ता समझते हैं कि यह क्या करता है और कब - गलती से क्लिक करना सेल कॉलम – kleopatra
@ क्लोपेट्रा में सभी मौजूदा डेटा खो देगा: अच्छा बिंदु; मैं अनुमान लगाता हूं कि किसी को इस तरह के डिवाइस की आवश्यकता पर सवाल उठाना चाहिए। – trashgod