开发者

Can't drag to resize JTable columns

开发者 https://www.devze.com 2022-12-24 01:32 出处:网络
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

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消