如何修复 JTable 中的列以使该列始终可见

发布于 2024-09-11 10:19:14 字数 95 浏览 1 评论 0原文

如何修复 JTable 中的列以使该列始终可见? 如果我使用 JViewport,则第一次表会正确,但当我第二次单击 btn 时,Jtable 中的下一列已修复,每次都会继续。

How can I fix the column in JTable so that the column is always visible ?
If I use JViewport than for the first time table is coming correct but when I click btn for the second time the next column in the Jtable is made fixed this continues each time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帥小哥 2024-09-18 10:19:14

在上面的示例中,您必须创建一个固定表和一个可滚动表,这并不是最好的。我建议这样做(我只粘贴重要的行):

public class TestPaperino extends JFrame {

public TestPaperino() throws Exception {
    super("Fixed Column Example");
    setSize(400, 150);

    Object[][] data = new Object[][] { { "1", "11", "A", "", "", "", "", "" },
            { "2", "22", "", "B", "", "", "", "" }, { "3", "33", "", "", "C", "", "", "" },
            { "4", "44", "", "", "", "D", "", "" }, { "5", "55", "", "", "", "", "E", "" },
            { "6", "66", "", "", "", "", "", "F" } };
    Object[] column = new Object[] { "fixed 1", "fixed 2", "a", "b", "c", "d", "e", "f" };

    AbstractTableModel model = new AbstractTableModel() {
        public int getColumnCount() {
            return column.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return (String) column[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public void setValueAt(Object obj, int row, int col) {
            data[row][col] = obj;
        }

        public boolean CellEditable(int row, int col) {
            return true;
        }
    };

    JTable table = new JTable(model);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setAutoCreateRowSorter(true);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    MyAdjustmentListener hListener = new MyAdjustmentListener(table, 1, 75);
    JScrollBar hBar = new JScrollBar(Adjustable.HORIZONTAL, 0, 20, 0, 500);
    hBar.addAdjustmentListener(hListener);
    JScrollPane panel = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JPanel panel2 = new JPanel(new BorderLayout());
    panel2.add(panel, BorderLayout.WEST);
    panel2.add(hBar, BorderLayout.SOUTH);
    add(panel2);

}

public static void main(String[] args) {
    TestPaperino frame;
    try {
        frame = new TestPaperino();
        frame.setSize(500, 500);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}


private class MyAdjustmentListener implements AdjustmentListener {

    private int last = 0;
    private BigDecimal ratio;
    private JTable table;
    private int lastFixedIndexCol;
    private int preferredWidth;

    public MyAdjustmentListener(JTable table, int lastFixedIndexCol, int preferredWidth) {
        this.table = table;
        this.lastFixedIndexCol = lastFixedIndexCol;
        this.preferredWidth = preferredWidth;
        this.initScrollBarListener();
    }

    private void initScrollBarListener() {
        int totCols = table.getColumnCount();
        int i = 0;
        int tableWidth = 0;
        int fixedWidth = 0;
        while (i < totCols) {

            TableColumn tableColumn = table.getColumnModel().getColumn(i);
            tableColumn.setWidth(preferredWidth);
            tableColumn.setMinWidth(preferredWidth);
            tableColumn.setMaxWidth(preferredWidth);
            tableColumn.setPreferredWidth(preferredWidth);
            int colwidth = table.getColumnModel().getColumn(i).getWidth();
            tableWidth = tableWidth + preferredWidth;
            fixedWidth = (i <= lastFixedIndexCol) ? (fixedWidth + colwidth) : fixedWidth;

            i++;
        }

        ratio = BigDecimal.valueOf(tableWidth - fixedWidth).divide(BigDecimal.valueOf(480),
                RoundingMode.HALF_UP);
        table.repaint();
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        action(e);
    }

    private void action(AdjustmentEvent e) {
        int valueOnLeft = e.getValue(); 
        int diff = valueOnLeft - last;
        if (diff == 0) {
            return;
        }

        last = valueOnLeft;
        BigDecimal val = BigDecimal.valueOf(diff > 0 ? diff : -diff).multiply(ratio);
        int realDiff = diff > 0 ? val.intValue() : -val.intValue();
        if (diff > 0) {
            toRight(realDiff);
        } else if (diff < 0) {
            toLeft(preferredWidth, realDiff);
        }

    }

    private void toRight(int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = lastFixedIndexCol + 1; i < columnModel2.getColumnCount(); i++) {

            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 == 0) {
                continue;
            }
            int appDiff = width2 - diff < 0 ? (width2) : diff;
            diff = diff - appDiff;
            action(appDiff, column, width2);
            if (diff <= 0) {
                break;
            }
        }
    }

    private void toLeft(int preferredWidth, int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = table.getColumnModel().getColumnCount() - 1; i > lastFixedIndexCol; i--) {             
            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 < preferredWidth) {
                int appDiff = width2 - diff >= preferredWidth ? (width2 - preferredWidth) : diff;
                diff = diff - appDiff;
                action(appDiff, column, width2);
            }

            if (diff >= 0) {
                break;
            }
        }
    }

    private void action(int diff, TableColumn tableColumn, int width2) {
        tableColumn.setWidth(width2 - diff);
        tableColumn.setMinWidth(width2 - diff);
        tableColumn.setMaxWidth(width2 - diff);
        tableColumn.setPreferredWidth(width2 - diff);
    }

}
}

在此处输入图像描述

The above example in wich you must create a fixed table and a scrollable table is not the best. I propose this (i paste only important lines):

public class TestPaperino extends JFrame {

public TestPaperino() throws Exception {
    super("Fixed Column Example");
    setSize(400, 150);

    Object[][] data = new Object[][] { { "1", "11", "A", "", "", "", "", "" },
            { "2", "22", "", "B", "", "", "", "" }, { "3", "33", "", "", "C", "", "", "" },
            { "4", "44", "", "", "", "D", "", "" }, { "5", "55", "", "", "", "", "E", "" },
            { "6", "66", "", "", "", "", "", "F" } };
    Object[] column = new Object[] { "fixed 1", "fixed 2", "a", "b", "c", "d", "e", "f" };

    AbstractTableModel model = new AbstractTableModel() {
        public int getColumnCount() {
            return column.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return (String) column[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public void setValueAt(Object obj, int row, int col) {
            data[row][col] = obj;
        }

        public boolean CellEditable(int row, int col) {
            return true;
        }
    };

    JTable table = new JTable(model);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setAutoCreateRowSorter(true);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    MyAdjustmentListener hListener = new MyAdjustmentListener(table, 1, 75);
    JScrollBar hBar = new JScrollBar(Adjustable.HORIZONTAL, 0, 20, 0, 500);
    hBar.addAdjustmentListener(hListener);
    JScrollPane panel = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JPanel panel2 = new JPanel(new BorderLayout());
    panel2.add(panel, BorderLayout.WEST);
    panel2.add(hBar, BorderLayout.SOUTH);
    add(panel2);

}

public static void main(String[] args) {
    TestPaperino frame;
    try {
        frame = new TestPaperino();
        frame.setSize(500, 500);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setVisible(true);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}


private class MyAdjustmentListener implements AdjustmentListener {

    private int last = 0;
    private BigDecimal ratio;
    private JTable table;
    private int lastFixedIndexCol;
    private int preferredWidth;

    public MyAdjustmentListener(JTable table, int lastFixedIndexCol, int preferredWidth) {
        this.table = table;
        this.lastFixedIndexCol = lastFixedIndexCol;
        this.preferredWidth = preferredWidth;
        this.initScrollBarListener();
    }

    private void initScrollBarListener() {
        int totCols = table.getColumnCount();
        int i = 0;
        int tableWidth = 0;
        int fixedWidth = 0;
        while (i < totCols) {

            TableColumn tableColumn = table.getColumnModel().getColumn(i);
            tableColumn.setWidth(preferredWidth);
            tableColumn.setMinWidth(preferredWidth);
            tableColumn.setMaxWidth(preferredWidth);
            tableColumn.setPreferredWidth(preferredWidth);
            int colwidth = table.getColumnModel().getColumn(i).getWidth();
            tableWidth = tableWidth + preferredWidth;
            fixedWidth = (i <= lastFixedIndexCol) ? (fixedWidth + colwidth) : fixedWidth;

            i++;
        }

        ratio = BigDecimal.valueOf(tableWidth - fixedWidth).divide(BigDecimal.valueOf(480),
                RoundingMode.HALF_UP);
        table.repaint();
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        action(e);
    }

    private void action(AdjustmentEvent e) {
        int valueOnLeft = e.getValue(); 
        int diff = valueOnLeft - last;
        if (diff == 0) {
            return;
        }

        last = valueOnLeft;
        BigDecimal val = BigDecimal.valueOf(diff > 0 ? diff : -diff).multiply(ratio);
        int realDiff = diff > 0 ? val.intValue() : -val.intValue();
        if (diff > 0) {
            toRight(realDiff);
        } else if (diff < 0) {
            toLeft(preferredWidth, realDiff);
        }

    }

    private void toRight(int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = lastFixedIndexCol + 1; i < columnModel2.getColumnCount(); i++) {

            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 == 0) {
                continue;
            }
            int appDiff = width2 - diff < 0 ? (width2) : diff;
            diff = diff - appDiff;
            action(appDiff, column, width2);
            if (diff <= 0) {
                break;
            }
        }
    }

    private void toLeft(int preferredWidth, int diff) {
        TableColumnModel columnModel2 = table.getColumnModel();
        for (int i = table.getColumnModel().getColumnCount() - 1; i > lastFixedIndexCol; i--) {             
            TableColumn column = columnModel2.getColumn(i);
            int width2 = column.getWidth();
            if (width2 < preferredWidth) {
                int appDiff = width2 - diff >= preferredWidth ? (width2 - preferredWidth) : diff;
                diff = diff - appDiff;
                action(appDiff, column, width2);
            }

            if (diff >= 0) {
                break;
            }
        }
    }

    private void action(int diff, TableColumn tableColumn, int width2) {
        tableColumn.setWidth(width2 - diff);
        tableColumn.setMinWidth(width2 - diff);
        tableColumn.setMaxWidth(width2 - diff);
        tableColumn.setPreferredWidth(width2 - diff);
    }

}
}

enter image description here

痴情换悲伤 2024-09-18 10:19:14

您可以将当前的方法与此处。

You might compare your current approach to the fixed column example show here.

无声无音无过去 2024-09-18 10:19:14

还有另一种选择:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Field;
import java.math.BigDecimal;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jdesktop.swingx.JXFindBar;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTableHeader;
import org.jdesktop.swingx.decorator.AbstractHighlighter;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.search.AbstractSearchable;
import org.jdesktop.swingx.search.AbstractSearchable.SearchResult;

/*** *

 *
 * @author Elie Levy Jan 04, 2009 GPL License
 *         (http://www.gnu.org/copyleft/gpl.html)
 *
 * @author kissjava 20090812 www.blogjava.net/kissjava
 */
public class FixTableManager extends JXTableHeader implements
        PropertyChangeListener, KeyListener, ChangeListener {

private JXTable table;
private JScrollPane scrollPane;
private int col = 0;
// private Point point;
private FixedMouseListenter mouseListener;

public FixTableManager(JXTable table, JScrollPane scrollPane) {
    super(table.getTableHeader().getColumnModel());
    this.table = table;
    this.scrollPane = scrollPane;
    init();

}

private void init() {
    mouseListener = new FixedMouseListenter();
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setTableHeader(this);
    this.addMouseListener(mouseListener);
    table.addMouseListener(mouseListener);
    scrollPane.addComponentListener(new ScrolPaneComponentListener());
    table.setFillsViewportHeight(true);
}

@Override
public void paint(Graphics g) {
    super.paint(g);        
    int division = mouseListener.getDivision();
    if (division > 0) {
        Rectangle r = getVisibleRect();
        BufferedImage image = new BufferedImage(division, r.height,
                BufferedImage.TYPE_INT_RGB);
        Graphics g2 = image.getGraphics();
        g2.setClip(0, 0, division, r.height);            
        g2.fillRect(0, 0, division, r.height);
        super.paint(g2);
        g.drawImage(image, r.x, r.y, division, r.height, null);
        g2.dispose();
    }
}

public int getFixCol() {
    return col;
}

/**
 *
 **/
public void setFixCol(int fixCol) {
    this.col = fixCol;
}

private int division;

private class FixedColumnsDelegate extends JLabel {

    @Override
    public void paintComponent(Graphics g) {
        Rectangle r = table.getBounds();
        if (division > 0) {
            table.invalidate();
            table.validate();
            Rectangle visibleRect = table.getVisibleRect();
            BufferedImage image = new BufferedImage(division, r.height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics g2 = image.getGraphics();

            g2.setClip(0, visibleRect.y, division, table.getBounds().height);

            g2.setColor(Color.RED);
            g2.fillRect(0, 0, division, table.getBounds().height);

            table.paint(g2);
            g.drawImage(image, 0, 0, division, table.getBounds().height, 0,
                    visibleRect.y - 1, division,
                    visibleRect.y + table.getBounds().height-1, null);
            // g.setColor(Color.BLACK);
            // for (int i = 0; i < visibleRect.y
            // + table.getBounds().height; i += 8) {
            // g.drawLine(division - 1, i, division - 1, i + 4);
            // g.drawLine(division - 2, i, division - 2, i + 4);
            // }
            g2.dispose();
        }
    }
}

private class FixedMouseListenter extends MouseAdapter {

    private FixedColumnsDelegate fixedColumns;
    private boolean added;

    public FixedMouseListenter() {
        fixedColumns = new FixedColumnsDelegate();            
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // point = e.getPoint();
        doMosuseAction();            

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        // point = e.getPoint();
        doMosuseAction();    System.out.println("cogido");        
    }

    private void doMosuseAction() {
        // if (point !=null) {
        ajustClip();

        // }
    }

    /**
     **/
    public void freeze() {
        JLayeredPane pane = table.getRootPane().getLayeredPane();
        if (added) {
            pane.remove(fixedColumns);
        }
        pane.add(fixedColumns, JLayeredPane.POPUP_LAYER);
        setBoundsOnFrozenColumns();
        added = true;
        fixedColumns.setVisible(true);
    }



    public void setBoundsOnFrozenColumns() {
        if (col >= 0) {
            division = table.getCellRect(1, col, true).x
                    + table.getCellRect(1, col, true).width;                
            int limit = scrollPane.getBounds().width
                    - scrollPane.getVerticalScrollBar().getBounds().width
                    - 2;
            division = Math.min(division, limit);
            JLayeredPane pane = table.getRootPane().getLayeredPane();                
            Point p = scrollPane.getLocationOnScreen();
            SwingUtilities.convertPointFromScreen(p, pane);
            Rectangle scrollPaneBounds = scrollPane.getBounds();
            int headerHeight = table.getTableHeader().getBounds().height + 2;
            int hScrollHeight = (scrollPane.getHorizontalScrollBar()
                    .isVisible()) ? scrollPane.getHorizontalScrollBar()
                    .getBounds().height : 0;

            int columnMargin = table.getColumnModel().getColumnMargin();
            p.x += 2 * columnMargin;

            int scrollRowHeaderWidth = 0;
            /**
             ***/
            if (scrollPane.getRowHeader() != null) {
                scrollRowHeaderWidth = scrollPane.getRowHeader().getWidth();
                if (scrollRowHeaderWidth <= 0) {
                    scrollRowHeaderWidth = 0;
                }
            }
            p.x += scrollRowHeaderWidth;
            fixedColumns.setBounds(p.x - 1, p.y + headerHeight - 2,
                    division, scrollPaneBounds.height - headerHeight
                            - hScrollHeight+columnMargin);
            System.out.println("se repinto");
        }
    }

    public int getDivision() {
        return division;
    }

    /**
     * {@inheritDoc}
     * <p>
     *
     * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        // super.mouseClicked(e);
        if (e.getClickCount() == 2) {
            ajustClip();
        }
    }

    /**
     * {@inheritDoc} <p>
     * @see java.awt.event.MouseAdapter#mouseEntered(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
        Rectangle head = table.getTableHeader().getVisibleRect();
        head.width= getDivision();
        Rectangle lastCol = table.getTableHeader().getHeaderRect(col);
        if (head.contains(lastCol)) {
            System.out.println("contenido");
            e.consume();
        }else
        super.mouseEntered(e);

    }
}

private class ScrolPaneComponentListener implements ComponentListener {

    @Override
    public void componentHidden(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName()
                + " --- Hidden");

    }

    @Override
    public void componentMoved(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Moved");

        // setBoundsOnFrozenColumns();
    }

    @Override
    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName()
                + " --- Resized");

        ajustClip();

    }

    @Override
    public void componentShown(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Shown");

        // setBoundsOnFrozenColumns();
        // if(e.getComponent())
    }

    private void displayMessage(String msg) {
        System.out.println(msg);
    }

    private void freeze() {
        mouseListener.freeze();
    }
}

public static String columnNames[] = { "Customer Name", "City",
        "Payment Amount", "Date", "Item", "Quantity", "Related", "Price",
        "Method", "Campaign", "Affiliate" };
public static String customers[] = { "Stores", "Exxon", "Chevron",
        "General", "ConocoPhillips", "General", "Ford", "Citigroup",
        "Bank", "AT&T", "Berkshire", "J.P.", "American", "Hewlett-Packard",
        "International", "Valero", "Verizon", "McKesson", "Cardinal",
        "Goldman", "Morgan", "Home", "Procter", "CVS", "UnitedHealth",
        "Kroger", "Boeing", "AmerisourceBergen", "Costco", "Merrill",
        "Target", "State", "WellPoint", "Dell", "Johnson", "Marathon",
        "Lehman", "Wachovia", "United", "Walgreen", "Wells", "Dow",
        "MetLife", "Microsoft", "Sears", "United", "Pfizer", "Lowe's",
        "Time", "Caterpillar", "Medco", "Archer", "Fannie", "Freddie",
        "Safeway", "Sunoco", "Lockheed", "Sprint", "PepsiCo", "Intel",
        "Altria", "Supervalu", "Kraft", "Allstate", "Motorola", "Best",
        "Walt", "FedEx", "Ingram", "Sysco", "Cisco", "Johnson",
        "Honeywell", "Prudential", "American", "Northrop", "Hess", "GMAC",
        "Comcast", "Alcoa", "DuPont", "New", "Coca-Cola", "News", "Aetna",
        "TIAA-CREF", "General", "Tyson", "HCA", "Enterprise", "Macy's",
        "Delphi", "Travelers", "Liberty", "Hartford", "Abbott",
        "Washington", "Humana", "Massachusetts", "3M" };
public static String[] cities = { "Alaska", "Arizona ", "Arkansas ",
        "California ", "Colorado ", "Connecticut ", "Delaware ",
        "District of", "Florida ", "Georgia ", "Hawaii ", "Idaho ",
        "Illinois ", "Indiana ", "Iowa ", "Kansas ", "Kentucky ",
        "Louisiana ", "Maine ", "Maryland ", "Massachusetts ", "Michigan ",
        "Minnesota ", "Mississippi ", "Missouri ", "Montana ", "Nebraska ",
        "Nevada ", "New Hampshire", "New Jersey", "New Mexico", "New York",
        "North Carolina", "North Dakota", "Ohio ", "Oklahoma ", "Oregon ",
        "Pennsylvania ", "Rhode Island", "South Carolina", "South Dakota",
        "Tennessee ", "Texas ", "Utah ", "Vermont ", "Virginia ",
        "Washington ", "West Virginia", "Wisconsin ", "Wyoming " };

public static void main(String arg[]) throws Exception {
    try {
        JFrame.setDefaultLookAndFeelDecorated(true);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }
    int rows = customers.length;
    int columns = columnNames.length;
    Object data[][] = new Object[rows][columns];
    for (int i = 0; i < rows; ++i) {
        data[i][0] = customers[i];
    }
    for (int i = 0; i < rows; ++i) {
        data[i][1] = cities[i % cities.length];
    }
    for (int i = 0; i < rows; ++i) {
        data[i][2] = new BigDecimal(Math.random() * 10000);
        data[i][2] = ((BigDecimal) data[i][2]).setScale(2,
                BigDecimal.ROUND_CEILING);
    }
    for (int i = 3; i < columns; ++i) {
        for (int x = 0; x < rows; ++x) {
            data[x][i] = "element:" + x + "," + i;
        }
    }
    JXTable table = new JXTable(data, columnNames) {

        /**
         * {@inheritDoc}
         * <p>
         *
         * @see org.jdesktop.swingx.JXTable#packAll()
         */
        @Override
        public void packAll() {
            // TODO Auto-generated method stub
            super.packAll();
            firePropertyChange("packAll", "unpacked", "packAll");
        }

    };
    table.putClientProperty(AbstractSearchable.MATCH_HIGHLIGHTER,
            Boolean.TRUE);
    AbstractHighlighter match = new ColorHighlighter(
            HighlighterFactory.LINE_PRINTER, Color.BLACK);
    ((AbstractSearchable) table.getSearchable()).setMatchHighlighter(match);
    table.setColumnControlVisible(true);

    JScrollPane scrollPane = new JScrollPane(table);
    JXFindBar findBar = new JXFindBar(table.getSearchable());
    FixTableManager tableHeader = new FixTableManager(table, scrollPane);
    // 固定å‰ä¸‰åˆ—
    tableHeader.setFixCol(2);
    table.addPropertyChangeListener(tableHeader);
    table.addKeyListener(tableHeader);

    match.addChangeListener(tableHeader);
    JFrame frame = new JFrame("Test");
    frame.add(BorderLayout.SOUTH, findBar);
    frame.add("Center", scrollPane);
    frame.setSize(600, 450);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
 */
@Override
public void propertyChange(final PropertyChangeEvent evt) {
    // TODO Auto-generated method stub
    if (evt.getPropertyName().equals("packAll")) {
        ajustClip();
    }

}

/**
 *
 */
public void ajustClip() {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            mouseListener.freeze();                
        }
    });
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
 */
@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
 */
@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    int c = e.getKeyCode();
    if (c == KeyEvent.VK_LEFT) {
        adjustScroll(table.getSelectedColumn());

    }
}

/**
 * @param co
 */
private void adjustScroll(int co) {
    if (co >= 0) {
        Rectangle r = table.getCellRect(1, co, true);
        Point p = new Point(r.x - r.width, r.y);
        Point copy = SwingUtilities.convertPoint(table, p, scrollPane);
        Rectangle visiblearea = (Rectangle) scrollPane.getVisibleRect()
                .clone();
        visiblearea.x = mouseListener.getDivision();
        if (!visiblearea.contains(copy)) {
            Rectangle rect = table.getVisibleRect();
            rect.x = p.x - mouseListener.getDivision();
            table.scrollRectToVisible(rect);
        }
    }
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
 */
@Override
public void keyReleased(KeyEvent e) {
    // No es necesario implementar
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
 */
@Override
public void stateChanged(ChangeEvent e) {
    // El searchResult del searchable de la tabla es privado por lo que se
    // utiliza refelexion para acceder a el y obtener la columna donde esta
    // el resultado

    try {
        Field atributo = AbstractSearchable.class
                .getDeclaredField("lastSearchResult");
        atributo.setAccessible(true);

        SearchResult search = (SearchResult) atributo.get((table
                .getSearchable()));
        adjustScroll(search.getFoundColumn());

    } catch (NoSuchFieldException | SecurityException
            | IllegalArgumentException | IllegalAccessException e1) {
        // No se han presentado estas excepciones

    }

}

}

我找到了这段代码并解决了许多问题,但还有其他问题我无法解决(在最后滚动时调整标题大小)。我希望人们能够使用它并改进它。该代码需要 SwingX 库

there is another alternative:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Field;
import java.math.BigDecimal;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jdesktop.swingx.JXFindBar;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTableHeader;
import org.jdesktop.swingx.decorator.AbstractHighlighter;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.search.AbstractSearchable;
import org.jdesktop.swingx.search.AbstractSearchable.SearchResult;

/*** *

 *
 * @author Elie Levy Jan 04, 2009 GPL License
 *         (http://www.gnu.org/copyleft/gpl.html)
 *
 * @author kissjava 20090812 www.blogjava.net/kissjava
 */
public class FixTableManager extends JXTableHeader implements
        PropertyChangeListener, KeyListener, ChangeListener {

private JXTable table;
private JScrollPane scrollPane;
private int col = 0;
// private Point point;
private FixedMouseListenter mouseListener;

public FixTableManager(JXTable table, JScrollPane scrollPane) {
    super(table.getTableHeader().getColumnModel());
    this.table = table;
    this.scrollPane = scrollPane;
    init();

}

private void init() {
    mouseListener = new FixedMouseListenter();
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setTableHeader(this);
    this.addMouseListener(mouseListener);
    table.addMouseListener(mouseListener);
    scrollPane.addComponentListener(new ScrolPaneComponentListener());
    table.setFillsViewportHeight(true);
}

@Override
public void paint(Graphics g) {
    super.paint(g);        
    int division = mouseListener.getDivision();
    if (division > 0) {
        Rectangle r = getVisibleRect();
        BufferedImage image = new BufferedImage(division, r.height,
                BufferedImage.TYPE_INT_RGB);
        Graphics g2 = image.getGraphics();
        g2.setClip(0, 0, division, r.height);            
        g2.fillRect(0, 0, division, r.height);
        super.paint(g2);
        g.drawImage(image, r.x, r.y, division, r.height, null);
        g2.dispose();
    }
}

public int getFixCol() {
    return col;
}

/**
 *
 **/
public void setFixCol(int fixCol) {
    this.col = fixCol;
}

private int division;

private class FixedColumnsDelegate extends JLabel {

    @Override
    public void paintComponent(Graphics g) {
        Rectangle r = table.getBounds();
        if (division > 0) {
            table.invalidate();
            table.validate();
            Rectangle visibleRect = table.getVisibleRect();
            BufferedImage image = new BufferedImage(division, r.height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics g2 = image.getGraphics();

            g2.setClip(0, visibleRect.y, division, table.getBounds().height);

            g2.setColor(Color.RED);
            g2.fillRect(0, 0, division, table.getBounds().height);

            table.paint(g2);
            g.drawImage(image, 0, 0, division, table.getBounds().height, 0,
                    visibleRect.y - 1, division,
                    visibleRect.y + table.getBounds().height-1, null);
            // g.setColor(Color.BLACK);
            // for (int i = 0; i < visibleRect.y
            // + table.getBounds().height; i += 8) {
            // g.drawLine(division - 1, i, division - 1, i + 4);
            // g.drawLine(division - 2, i, division - 2, i + 4);
            // }
            g2.dispose();
        }
    }
}

private class FixedMouseListenter extends MouseAdapter {

    private FixedColumnsDelegate fixedColumns;
    private boolean added;

    public FixedMouseListenter() {
        fixedColumns = new FixedColumnsDelegate();            
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // point = e.getPoint();
        doMosuseAction();            

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        // point = e.getPoint();
        doMosuseAction();    System.out.println("cogido");        
    }

    private void doMosuseAction() {
        // if (point !=null) {
        ajustClip();

        // }
    }

    /**
     **/
    public void freeze() {
        JLayeredPane pane = table.getRootPane().getLayeredPane();
        if (added) {
            pane.remove(fixedColumns);
        }
        pane.add(fixedColumns, JLayeredPane.POPUP_LAYER);
        setBoundsOnFrozenColumns();
        added = true;
        fixedColumns.setVisible(true);
    }



    public void setBoundsOnFrozenColumns() {
        if (col >= 0) {
            division = table.getCellRect(1, col, true).x
                    + table.getCellRect(1, col, true).width;                
            int limit = scrollPane.getBounds().width
                    - scrollPane.getVerticalScrollBar().getBounds().width
                    - 2;
            division = Math.min(division, limit);
            JLayeredPane pane = table.getRootPane().getLayeredPane();                
            Point p = scrollPane.getLocationOnScreen();
            SwingUtilities.convertPointFromScreen(p, pane);
            Rectangle scrollPaneBounds = scrollPane.getBounds();
            int headerHeight = table.getTableHeader().getBounds().height + 2;
            int hScrollHeight = (scrollPane.getHorizontalScrollBar()
                    .isVisible()) ? scrollPane.getHorizontalScrollBar()
                    .getBounds().height : 0;

            int columnMargin = table.getColumnModel().getColumnMargin();
            p.x += 2 * columnMargin;

            int scrollRowHeaderWidth = 0;
            /**
             ***/
            if (scrollPane.getRowHeader() != null) {
                scrollRowHeaderWidth = scrollPane.getRowHeader().getWidth();
                if (scrollRowHeaderWidth <= 0) {
                    scrollRowHeaderWidth = 0;
                }
            }
            p.x += scrollRowHeaderWidth;
            fixedColumns.setBounds(p.x - 1, p.y + headerHeight - 2,
                    division, scrollPaneBounds.height - headerHeight
                            - hScrollHeight+columnMargin);
            System.out.println("se repinto");
        }
    }

    public int getDivision() {
        return division;
    }

    /**
     * {@inheritDoc}
     * <p>
     *
     * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        // super.mouseClicked(e);
        if (e.getClickCount() == 2) {
            ajustClip();
        }
    }

    /**
     * {@inheritDoc} <p>
     * @see java.awt.event.MouseAdapter#mouseEntered(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
        Rectangle head = table.getTableHeader().getVisibleRect();
        head.width= getDivision();
        Rectangle lastCol = table.getTableHeader().getHeaderRect(col);
        if (head.contains(lastCol)) {
            System.out.println("contenido");
            e.consume();
        }else
        super.mouseEntered(e);

    }
}

private class ScrolPaneComponentListener implements ComponentListener {

    @Override
    public void componentHidden(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName()
                + " --- Hidden");

    }

    @Override
    public void componentMoved(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Moved");

        // setBoundsOnFrozenColumns();
    }

    @Override
    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName()
                + " --- Resized");

        ajustClip();

    }

    @Override
    public void componentShown(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Shown");

        // setBoundsOnFrozenColumns();
        // if(e.getComponent())
    }

    private void displayMessage(String msg) {
        System.out.println(msg);
    }

    private void freeze() {
        mouseListener.freeze();
    }
}

public static String columnNames[] = { "Customer Name", "City",
        "Payment Amount", "Date", "Item", "Quantity", "Related", "Price",
        "Method", "Campaign", "Affiliate" };
public static String customers[] = { "Stores", "Exxon", "Chevron",
        "General", "ConocoPhillips", "General", "Ford", "Citigroup",
        "Bank", "AT&T", "Berkshire", "J.P.", "American", "Hewlett-Packard",
        "International", "Valero", "Verizon", "McKesson", "Cardinal",
        "Goldman", "Morgan", "Home", "Procter", "CVS", "UnitedHealth",
        "Kroger", "Boeing", "AmerisourceBergen", "Costco", "Merrill",
        "Target", "State", "WellPoint", "Dell", "Johnson", "Marathon",
        "Lehman", "Wachovia", "United", "Walgreen", "Wells", "Dow",
        "MetLife", "Microsoft", "Sears", "United", "Pfizer", "Lowe's",
        "Time", "Caterpillar", "Medco", "Archer", "Fannie", "Freddie",
        "Safeway", "Sunoco", "Lockheed", "Sprint", "PepsiCo", "Intel",
        "Altria", "Supervalu", "Kraft", "Allstate", "Motorola", "Best",
        "Walt", "FedEx", "Ingram", "Sysco", "Cisco", "Johnson",
        "Honeywell", "Prudential", "American", "Northrop", "Hess", "GMAC",
        "Comcast", "Alcoa", "DuPont", "New", "Coca-Cola", "News", "Aetna",
        "TIAA-CREF", "General", "Tyson", "HCA", "Enterprise", "Macy's",
        "Delphi", "Travelers", "Liberty", "Hartford", "Abbott",
        "Washington", "Humana", "Massachusetts", "3M" };
public static String[] cities = { "Alaska", "Arizona ", "Arkansas ",
        "California ", "Colorado ", "Connecticut ", "Delaware ",
        "District of", "Florida ", "Georgia ", "Hawaii ", "Idaho ",
        "Illinois ", "Indiana ", "Iowa ", "Kansas ", "Kentucky ",
        "Louisiana ", "Maine ", "Maryland ", "Massachusetts ", "Michigan ",
        "Minnesota ", "Mississippi ", "Missouri ", "Montana ", "Nebraska ",
        "Nevada ", "New Hampshire", "New Jersey", "New Mexico", "New York",
        "North Carolina", "North Dakota", "Ohio ", "Oklahoma ", "Oregon ",
        "Pennsylvania ", "Rhode Island", "South Carolina", "South Dakota",
        "Tennessee ", "Texas ", "Utah ", "Vermont ", "Virginia ",
        "Washington ", "West Virginia", "Wisconsin ", "Wyoming " };

public static void main(String arg[]) throws Exception {
    try {
        JFrame.setDefaultLookAndFeelDecorated(true);
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }
    int rows = customers.length;
    int columns = columnNames.length;
    Object data[][] = new Object[rows][columns];
    for (int i = 0; i < rows; ++i) {
        data[i][0] = customers[i];
    }
    for (int i = 0; i < rows; ++i) {
        data[i][1] = cities[i % cities.length];
    }
    for (int i = 0; i < rows; ++i) {
        data[i][2] = new BigDecimal(Math.random() * 10000);
        data[i][2] = ((BigDecimal) data[i][2]).setScale(2,
                BigDecimal.ROUND_CEILING);
    }
    for (int i = 3; i < columns; ++i) {
        for (int x = 0; x < rows; ++x) {
            data[x][i] = "element:" + x + "," + i;
        }
    }
    JXTable table = new JXTable(data, columnNames) {

        /**
         * {@inheritDoc}
         * <p>
         *
         * @see org.jdesktop.swingx.JXTable#packAll()
         */
        @Override
        public void packAll() {
            // TODO Auto-generated method stub
            super.packAll();
            firePropertyChange("packAll", "unpacked", "packAll");
        }

    };
    table.putClientProperty(AbstractSearchable.MATCH_HIGHLIGHTER,
            Boolean.TRUE);
    AbstractHighlighter match = new ColorHighlighter(
            HighlighterFactory.LINE_PRINTER, Color.BLACK);
    ((AbstractSearchable) table.getSearchable()).setMatchHighlighter(match);
    table.setColumnControlVisible(true);

    JScrollPane scrollPane = new JScrollPane(table);
    JXFindBar findBar = new JXFindBar(table.getSearchable());
    FixTableManager tableHeader = new FixTableManager(table, scrollPane);
    // 固定å‰ä¸‰åˆ—
    tableHeader.setFixCol(2);
    table.addPropertyChangeListener(tableHeader);
    table.addKeyListener(tableHeader);

    match.addChangeListener(tableHeader);
    JFrame frame = new JFrame("Test");
    frame.add(BorderLayout.SOUTH, findBar);
    frame.add("Center", scrollPane);
    frame.setSize(600, 450);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
 */
@Override
public void propertyChange(final PropertyChangeEvent evt) {
    // TODO Auto-generated method stub
    if (evt.getPropertyName().equals("packAll")) {
        ajustClip();
    }

}

/**
 *
 */
public void ajustClip() {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            mouseListener.freeze();                
        }
    });
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
 */
@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
 */
@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    int c = e.getKeyCode();
    if (c == KeyEvent.VK_LEFT) {
        adjustScroll(table.getSelectedColumn());

    }
}

/**
 * @param co
 */
private void adjustScroll(int co) {
    if (co >= 0) {
        Rectangle r = table.getCellRect(1, co, true);
        Point p = new Point(r.x - r.width, r.y);
        Point copy = SwingUtilities.convertPoint(table, p, scrollPane);
        Rectangle visiblearea = (Rectangle) scrollPane.getVisibleRect()
                .clone();
        visiblearea.x = mouseListener.getDivision();
        if (!visiblearea.contains(copy)) {
            Rectangle rect = table.getVisibleRect();
            rect.x = p.x - mouseListener.getDivision();
            table.scrollRectToVisible(rect);
        }
    }
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
 */
@Override
public void keyReleased(KeyEvent e) {
    // No es necesario implementar
}

/**
 * {@inheritDoc}
 * <p>
 *
 * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
 */
@Override
public void stateChanged(ChangeEvent e) {
    // El searchResult del searchable de la tabla es privado por lo que se
    // utiliza refelexion para acceder a el y obtener la columna donde esta
    // el resultado

    try {
        Field atributo = AbstractSearchable.class
                .getDeclaredField("lastSearchResult");
        atributo.setAccessible(true);

        SearchResult search = (SearchResult) atributo.get((table
                .getSearchable()));
        adjustScroll(search.getFoundColumn());

    } catch (NoSuchFieldException | SecurityException
            | IllegalArgumentException | IllegalAccessException e1) {
        // No se han presentado estas excepciones

    }

}

}

i found this code and solve many problems, but there are others that i can´t solve ( resize header when scroll at the end) . I hope that people can use it and imporve it. The code requiered the SwingX lib

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文