Java 如何使jtable单元格的整个数据在鼠标焦点上可见?

Java 如何使jtable单元格的整个数据在鼠标焦点上可见?,java,swing,jtable,cell,tablecellrenderer,Java,Swing,Jtable,Cell,Tablecellrenderer,我用一些数据创建了一个jtable。但由于大小限制,我只能看到单元格的部分数据。如何使jtable单元格的整个数据在鼠标焦点上可见?要使单元格的显示超出其边界,需要实现TableUI类 基本上你需要自己画细胞。代码有点长,但绝对适合我 要解决此问题,请创建一个新类MyTableUI extends javax.swing.plaf.basic.BasicTableUI,覆盖其paint()方法 完整代码如下,您可以复制到ide并运行它 package me.chenyi.table; impo

我用一些数据创建了一个jtable。
但由于大小限制,我只能看到单元格的部分数据。

如何使jtable单元格的整个数据在鼠标焦点上可见?

要使单元格的显示超出其边界,需要实现TableUI类

基本上你需要自己画细胞。代码有点长,但绝对适合我

要解决此问题,请创建一个新类MyTableUI extends javax.swing.plaf.basic.BasicTableUI,覆盖其paint()方法

完整代码如下,您可以复制到ide并运行它

package me.chenyi.table;

import javax.swing.*;
import javax.swing.plaf.basic.BasicTableUI;
import javax.swing.table.*;
import java.awt.*;

public class MyBasicTableUI extends BasicTableUI
{
    @Override
    public void paint(Graphics g, JComponent c)
    {
        super.paint(g, c);

        Rectangle clip = g.getClipBounds();

        Rectangle bounds = table.getBounds();
        // account for the fact that the graphics has already been translated
        // into the table's bounds
        bounds.x = bounds.y = 0;

        //just do not want to copy too much code from BasicTableUI, so comment out following code.
        //code from BasicTableUI comment out begin
//  if (table.getRowCount() <= 0 || table.getColumnCount() <= 0 ||
//                // this check prevents us from painting the entire table
//                // when the clip doesn't intersect our bounds at all
//                !bounds.intersects(clip)) {
//
//            paintDropLines(g);
//      return;
//  }
        //code from BasicTableUI comment out end
        boolean ltr = table.getComponentOrientation().isLeftToRight();

        Point upperLeft = clip.getLocation();
        if(!ltr)
        {
            upperLeft.x++;
        }

        Point lowerRight = new Point(clip.x + clip.width - (ltr ? 1 : 0),
                                     clip.y + clip.height);
        int rMin = table.rowAtPoint(upperLeft);
        int rMax = table.rowAtPoint(lowerRight);
        // This should never happen (as long as our bounds intersect the clip,
        // which is why we bail above if that is the case).
        if(rMin == -1)
        {
            rMin = 0;
        }
        // If the table does not have enough rows to fill the view we'll get -1.
        // (We could also get -1 if our bounds don't intersect the clip,
        // which is why we bail above if that is the case).
        // Replace this with the index of the last row.
        if(rMax == -1)
        {
            rMax = table.getRowCount() - 1;
        }

        int cMin = table.columnAtPoint(ltr ? upperLeft : lowerRight);
        int cMax = table.columnAtPoint(ltr ? lowerRight : upperLeft);
        // This should never happen.
        if(cMin == -1)
        {
            cMin = 0;
        }
        // If the table does not have enough columns to fill the view we'll get -1.
        // Replace this with the index of the last column.
        if(cMax == -1)
        {
            cMax = table.getColumnCount() - 1;
        }
        paintCells(g, rMin, rMax, cMin, cMax);
    }

    private void paintCells(Graphics g, int rMin, int rMax, int cMin, int cMax)
    {
        JTableHeader header = table.getTableHeader();
        TableColumn draggedColumn = (header == null) ? null : header.getDraggedColumn();

        TableColumnModel cm = table.getColumnModel();
        int columnMargin = cm.getColumnMargin();

        Rectangle cellRect;
        TableColumn aColumn;
        int columnWidth;
        if(table.getComponentOrientation().isLeftToRight())
        {
            for(int row = rMin; row <= rMax; row++)
            {
                //code from BasicTableUI comment out begin
//                cellRect = table.getCellRect(row, cMin, false);
//                for(int column = cMin; column <= cMax; column++)
//                {
//                    aColumn = cm.getColumn(column);
//                    columnWidth = aColumn.getWidth();
//                    cellRect.width = columnWidth - columnMargin;
//                    if(aColumn != draggedColumn)
//                    {
//                        paintCell(g, cellRect, row, column);
//                    }
//                    cellRect.x += columnWidth;
//                }
                //code from BasicTableUI end
                //code written by sean begin
                cellRect = table.getCellRect(row, cMax, false);
                int maxWidth = 0;
                for(int column = cMax; column >= cMin; column--)
                {
                    aColumn = cm.getColumn(column);
                    columnWidth = aColumn.getWidth();
                    cellRect.width = columnWidth - columnMargin;
                    maxWidth += cellRect.width;
                    if(aColumn != draggedColumn)
                    {
                        paintCell(g, cellRect, row, column, maxWidth);
                    }
                    cellRect.x -= columnWidth;
                    if (table.getValueAt(row, column) != null)
                    {
                        maxWidth = 0;
                    }
                }
                //code written by sean end
            }
        }
        else
        {
            for(int row = rMin; row <= rMax; row++)
            {
                cellRect = table.getCellRect(row, cMin, false);
                aColumn = cm.getColumn(cMin);
                if(aColumn != draggedColumn)
                {
                    columnWidth = aColumn.getWidth();
                    cellRect.width = columnWidth - columnMargin;
                    paintCell(g, cellRect, row, cMin);
                }
                for(int column = cMin + 1; column <= cMax; column++)
                {
                    aColumn = cm.getColumn(column);
                    columnWidth = aColumn.getWidth();
                    cellRect.width = columnWidth - columnMargin;
                    cellRect.x -= columnWidth;
                    if(aColumn != draggedColumn)
                    {
                        paintCell(g, cellRect, row, column);
                    }
                }
            }
        }

        //just do not want to copy too much code from BasicTableUI, so comment out following code.
        //code from BasicTableUI comment out begin
        // Paint the dragged column if we are dragging.
//        if(draggedColumn != null)
//        {
//            paintDraggedArea(g, rMin, rMax, draggedColumn, header.getDraggedDistance());
//        }
        //code from BasicTableUI comment out end

        // Remove any renderers that may be left in the rendererPane.
        rendererPane.removeAll();
    }

    private void paintCell(Graphics g, Rectangle cellRect, int row, int column)
    {
        paintCell(g, cellRect, row, column, -1);
    }

    private void paintCell(Graphics g, Rectangle cellRect, int row, int column,
                           /** sean's modification begin**/
                           int maxWidth
                           /** sean's modification end**/)
    {
        if(table.isEditing() && table.getEditingRow() == row &&
            table.getEditingColumn() == column)
        {
            Component component = table.getEditorComponent();
            component.setBounds(cellRect);
            component.validate();
        }
        else
        {
            //code from BasicTableUI begin
//            TableCellRenderer renderer = table.getCellRenderer(row, column);
//            Component component = table.prepareRenderer(renderer, row, column);
//            rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y,
//                                        cellRect.width, cellRect.height, true);
            //code from BasicTableUI end
            //code written by sean begin
            TableCellRenderer renderer = table.getCellRenderer(row, column);
            Component component = table.prepareRenderer(renderer, row, column);
            int width = cellRect.width;
            int height = cellRect.height;
            Dimension preferredSize = component.getPreferredSize();
            if(preferredSize != null && preferredSize.getWidth() != 0 && preferredSize.getHeight() != 0)
            {
                if(maxWidth > 0)
                    width = Math.min(preferredSize.width, maxWidth);
                else
                    width = preferredSize.width;
            }
            rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y,
                                        width, height, true);
            //code written by sean end
        }
    }

    public static void main(String[] args)
    {

        JFrame frame = new JFrame();
        DefaultTableModel tableModel = new DefaultTableModel(2, 4);
        tableModel.setValueAt("1234567890abcdefg1234567890abcdefg90abcdefg1234567890abcdefg90abcdefg1234567890abcdefg90abcdefg1234567890abcdefg", 0, 0);
//        tableModel.setValueAt("xyz", 0, 1);//try to uncomment to see the difference
        final JTable table = new JTable(tableModel);
        final Font font = new Font("Arial", Font.PLAIN, 12);
        table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
        {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                           boolean hasFocus,
                                                           int row, int column)
            {
                Component tableCellRendererComponent =
                    super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if(tableCellRendererComponent instanceof JLabel)
                {
                    JLabel label = (JLabel)tableCellRendererComponent;
                    if(hasFocus && value != null)
                    {
                        FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
                        int width = metrics.stringWidth((String)value) + 20;
                        label.setPreferredSize(new Dimension(width, metrics.getHeight()));
//                        label.setBorder(BorderFactory.createLineBorder(Color.red));
                    }
                    else
                    {
                        label.setPreferredSize(null);
                    }
//                    label.setText("_______________");
                }
                return tableCellRendererComponent;
            }
        });

        table.setUI(new MyBasicTableUI());
        frame.getContentPane().add(table, BorderLayout.CENTER);
        frame.setSize(600, 800);
        frame.setVisible(true);
    }
}
package me.chenyi.table;
导入javax.swing.*;
导入javax.swing.plaf.basic.BasicTableUI;
导入javax.swing.table.*;
导入java.awt.*;
公共类MyBasicTableUI扩展了BasicTableUI
{
@凌驾
公共空隙涂料(图形g、J组件c)
{
超级油漆(g,c);
矩形剪辑=g.getClipBounds();
矩形边界=table.getBounds();
//说明图形已被翻译的事实
//进入桌子的边界
bounds.x=bounds.y=0;
//只是不想从BasicTableUI复制太多代码,所以请注释掉以下代码。
//BasicTableUI注释输出开始中的代码

//如果(table.getRowCount()@AndrewThompson:当然。谢谢你……你说的“鼠标焦点”到底是什么意思?没有这样的术语,这就是为什么我要问-@chenyi1976把它当作“hasFocus”(==leadSelection)。我的第一个想法是“鼠标翻转”…+1个有趣的方法:-)有几个怪癖:A)实现ui委托然后为每个实例设置ui很少是一个好主意b)不喜欢prefSize操作。但无论如何,如果需求真的是“聚焦”单元(这一点从问题中还不清楚),这是一个不错的开端