Long story short, I'm making a custom Swing component that's basically a JTable with a panel on its side. The table should of course be scrollable and have a table header, but since I only want the header to be above the actual JTable and not above the side panel, I had to pull some tricks to make it work. But that part works fine.
However, in the process I've somehow managed to break the mouse-drag-column-resizing functionality of the JTableHeader. I am completely clueless as to why and what I can do about it.
Below is a minimal working sample to illustrate my problem.
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.table.JTableHeader;
final class FooTable extends JPanel implements Scrollable {
public FooTable() {
initComponents();
}
// Generated by NetBeans IDE
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
sidePanel = new javax.swing.JPanel();
table = new javax.swing.JTable();
setLayout(new java.awt.GridBagLayout());
sidePanel.setMinimumSize(new java.awt.Dimension(70, 0));
sidePanel.setPreferredSize(new java.awt.Dimension(70, 0));
sidePanel.setLayout(null);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weighty = 1.0;
add(sidePanel, gridBagConstraints);
table.setFont(table.getFont().deriveFont(table.getFont().getSize()+1f));
table.setMode开发者_运维知识库l(new javax.swing.table.DefaultTableModel(
new Object [][] {
{"1", "A", "I", "-"},
{"2", "B", "II", "--"},
{"3", "C", "III", "---"},
{"4", "D", "IV", "----"},
{"5", "E", "V", "-----"},
{"6", "F", "VI", "------"},
{"7", "G", "VII", "-------"},
{"8", "H", "VIII", "--------"},
{"9", "I", "IX", "---------"},
{"10", "J", "X", "----------"}
},
new String [] {
"Column 1", "Column 2", "Column 3", "Column 4"
}
));
table.setRowHeight(24);
table.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
add(table, gridBagConstraints);
}// </editor-fold>
public JScrollPane createScrollView() {
JScrollPane jsp = new JScrollPane(this);
JViewport jvp = new JViewport();
final JTableHeader th = new JTableHeader();
th.setTable(table);
th.setColumnModel(table.getColumnModel());
th.setResizingAllowed(true);
jvp.setView(new JPanel() {
{
setLayout(null);
add(th);
th.setLocation(70, 0);
FooTable.this.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
th.setSize(FooTable.this.getWidth(), th.getPreferredSize().height);
}
});
setPreferredSize(new Dimension(th.getPreferredSize().width, th.getPreferredSize().height));
}
});
jsp.setColumnHeader(jvp);
return jsp;
}
// Variables declaration - do not modify
private javax.swing.JPanel sidePanel;
private javax.swing.JTable table;
// End of variables declaration
//
// Scrollable implementation
//
public Dimension getPreferredScrollableViewportSize() {
Dimension d = new Dimension();
d.width = sidePanel.getPreferredSize().width + table.getPreferredSize().width;
d.height = sidePanel.getPreferredSize().height + table.getPreferredSize().height;
return d;
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return table.getScrollableUnitIncrement(visibleRect, orientation, direction);
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return table.getScrollableBlockIncrement(visibleRect, orientation, direction);
}
public boolean getScrollableTracksViewportWidth() {
return table.getScrollableTracksViewportWidth();
}
public boolean getScrollableTracksViewportHeight() {
return table.getScrollableTracksViewportHeight();
}
//
// Test program
//
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FooTable fooTable = new FooTable();
f.add(fooTable.createScrollView());
f.pack();
f.setVisible(true);
}
}
I think what you are missing is also telling the JTable about the JTableHeader. In the method createScrollView try adding the following just before returning:
table.setTableHeader(th);
精彩评论