我用一些数据创建了一个 jtable。
但是由于大小限制,我只能看到单元格的部分数据。
如何使 jtable 单元格的整个数据在鼠标焦点上可见?
问问题
259 次
1 回答
2
为了使单元格可以越界显示,您需要实现 TableUI 类。
基本上你需要自己画细胞。代码有点长,但绝对适合我。
为了解决这个问题,创建一个新的 MyTableUI 类扩展 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);
}
}
截图如下。仍然需要调整代码,使绘画更好,但无论如何这是实现您想要的正确方法。
于 2012-03-19T04:56:45.213 回答