Java 如何创建具有可滚动内容的JTable单元格

Java 如何创建具有可滚动内容的JTable单元格,java,swing,jtable,scroll,tablecellrenderer,Java,Swing,Jtable,Scroll,Tablecellrenderer,我想用JTable来显示一些数据。有时数据可能稍大一些,因此有必要能够在JTable的单元格内滚动 我试着用下面的代码来实现这一点。创建的表看起来很好,不幸的是它不工作。滚动条似乎对鼠标点击没有反应 没有滚动条“冻结”我怎么做 谢谢 托尔斯滕 package main; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPa

我想用JTable来显示一些数据。有时数据可能稍大一些,因此有必要能够在JTable的单元格内滚动

我试着用下面的代码来实现这一点。创建的表看起来很好,不幸的是它不工作。滚动条似乎对鼠标点击没有反应

没有滚动条“冻结”我怎么做

谢谢

托尔斯滕

package main;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class ScrollableCellTableTest extends JPanel {

    JTable table;
    String val = "This is my totally cool test data. ";


    public ScrollableCellTableTest() {

        setLayout(new BorderLayout());

        for (int t=0; t<10; t++)
            val+=val;

        table = new JTable(new String[][]{{val}}, new String[]{"colname"}) {
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        table.getColumnModel().getColumn(0)
                .setCellRenderer(new ScrollableCellRenderer());

        add(new JScrollPane(table), BorderLayout.CENTER);

    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        ScrollableCellTableTest scrollableCellTable = new ScrollableCellTableTest();
        frame.getContentPane().setLayout(new BorderLayout());
        frame.getContentPane().add(scrollableCellTable, BorderLayout.CENTER);
        frame.pack();
        frame.setLocation(500, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}
packagemain;
导入java.awt.BorderLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
公共类ScrollableCellTableTest扩展了JPanel{
JTable表;
String val=“这是我最酷的测试数据。”;
公共ScrollableCellTableTest(){
setLayout(新的BorderLayout());

对于(int t=0;t您的方法永远不会起作用,因为渲染器仅用于渲染单元格内容。无法与渲染器交互。您只能使用编辑器提供与单元格内容的交互。不幸的是,您同时只能有一个编辑器。在实际单元格中提供滚动的唯一方法是安装鼠标使当前指向的单元格可编辑的侦听器(可能有一点延迟)。在侦听器中,您必须监视以下事件:移动(使点处的单元格可编辑)、进入(与移动相同)和退出(如果存在,请删除当前编辑器)。可能这种方法在没有侦听器的情况下也可以使用:界面CellEditor定义了方法
isCellEditable(EventObject anEvent)
。在这里,您应该尝试检查事件是否是鼠标事件,其ID是否正在进入、移动或退出。并且不要忘记在表模型中将适当的单元格定义为可编辑

有时数据可能会稍大一些

如果只“稍微”大一点,那么最简单的解决方案是使用工具提示。有两种方法可以做到这一点:

  • 创建自定义渲染器并在渲染器中调用
    setToolTipText(…)
    方法
  • 重写JTable的
    getToolTiptText(…)
    方法以返回工具提示

  • 渲染器仅用于绘图。请阅读有关TableCellEditor的信息
    package main;
    
    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextArea;
    import javax.swing.table.TableCellRenderer;
    
    /**
     * Scrollable Cell Renderer.
     */
    public class ScrollableCellRenderer extends JPanel implements
            TableCellRenderer {
        private List rowColHeight = new ArrayList();
        JScrollPane jScrollPane;
        JTextArea textArea = new JTextArea();
    
        public ScrollableCellRenderer() {
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
    
            setLayout(new BorderLayout());
            add(textArea, BorderLayout.CENTER);
            jScrollPane = new JScrollPane(this);
        }
    
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
    
            textArea.setText(value.toString());
    
            adjustRowHeight(table, row, column);
    
            return new JScrollPane(this);
        }
    
        /**
         * Calculate the new preferred height for a given row, and sets the height
         * on the table.
         */
        private void adjustRowHeight(JTable table, int row, int column) {
    
            int cWidth = table.getTableHeader().getColumnModel().getColumn(column)
                    .getWidth();
            setSize(new Dimension(cWidth, 1000));
            int prefH = getPreferredSize().height;
    
            // Limit the height, so scrollbars become neccessary
            prefH = Math.min(prefH, 100);
    
    
            while (rowColHeight.size() <= row) {
                rowColHeight.add(new ArrayList(column));
            }
            List colHeights = (List) rowColHeight.get(row);
            while (colHeights.size() <= column) {
                colHeights.add(new Integer(0));
            }
            colHeights.set(column, new Integer(prefH));
            int maxH = prefH;
            for (int t = 0; t < colHeights.size(); t++) {
                int colHeight = ((Integer) colHeights.get(t)).intValue();
                if (colHeight > maxH)
                    maxH = colHeight;
            }
            if (table.getRowHeight(row) != maxH) {
                table.setRowHeight(row, maxH);
            }
    
        }
    }