gpt4 book ai didi

java - JTable扩展后无法向下滚动?

转载 作者:行者123 更新时间:2023-11-30 02:51:45 24 4
gpt4 key购买 nike

我扩展了 JTable,因此它可以按字母顺序对数据进行排序,并根据数据的首字母按部分分隔数据。

See this question and marked answer for more clarification

扩展表工作正常。然而,当排序时,通过单击表格的标题,向下滚动表格(使用鼠标滚轮)时我遇到问题。 enter image description here

这是扩展表的代码。 (注意:您还可以在上面的超链接中找到此代码)。

import java.awt.BorderLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.table.TableModel;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;



public class SectionedTable
extends JTable {

private static final long serialVersionUID = 1;

private final NavigableMap<Integer, String> sectionHeadings
= new TreeMap<>();

private final NavigableMap<Integer, Integer> rowTopEdges
= new TreeMap<>();

// Used when calling SwingUtilities.layoutCompoundLabel.
private final Rectangle iconBounds = new Rectangle();
private final Rectangle textBounds = new Rectangle();

public SectionedTable() {
init();
}

public SectionedTable(TableModel model) {
super(model);
init();
}

private void init() {
setShowGrid(false);
setAutoCreateRowSorter(true);

recomputeSections();
recomputeRowPositions();
}

private void recomputeSections() {
if (sectionHeadings == null) {
return;
}

sectionHeadings.clear();

RowSorter<? extends TableModel> sorter = getRowSorter();
if (sorter == null) {
return;
}

for (RowSorter.SortKey key : sorter.getSortKeys()) {
SortOrder order = key.getSortOrder();
if (order != SortOrder.UNSORTED) {
int sortColumn = key.getColumn();

String lastSectionStart = "";
int rowCount = getRowCount();
for (int row = 0; row < rowCount; row++) {
System.out.println("row er : " + row);
System.out.println("rowcount er : " + rowCount);
System.out.println("sortColumn er : " + sortColumn);
Object value = getValueAt(row, sortColumn);
if (value == null) {
value = "?";
}

String s = value.toString();
if (s.isEmpty()) {
s = "?";
}

String sectionStart = s.substring(0,
s.offsetByCodePoints(0, 1));
sectionStart = sectionStart.toUpperCase();

if (!sectionStart.equals(lastSectionStart)) {
sectionHeadings.put(row, sectionStart);
lastSectionStart = sectionStart;
}
}
break;
}
}
}

private void recomputeRowPositions() {
if (rowTopEdges == null) {
return;
}

rowTopEdges.clear();

int y = getInsets().top;
int rowCount = getRowCount();
int rowHeight = getRowHeight();
for (int row = 0; row < rowCount; row++) {
rowTopEdges.put(y, row);
y += getRowHeight(row);
if (sectionHeadings.containsKey(row)) {
y += rowHeight;
}
}
}

@Override
public void tableChanged(TableModelEvent event) {
//super.tableChanged(event);
recomputeSections();
recomputeRowPositions();
super.tableChanged(event);
}

@Override
public void sorterChanged(RowSorterEvent event) {
recomputeSections();
recomputeRowPositions();
super.sorterChanged(event);
}

@Override
public void validate() {
super.validate();
recomputeRowPositions();
}

@Override
public int rowAtPoint(Point location) {
Map.Entry<Integer, Integer> entry = rowTopEdges.floorEntry(location.y);
if (entry != null) {
int row = entry.getValue();
return row;
}
return -1;
}

@Override
public Rectangle getCellRect(int row,
int column,
boolean includeSpacing) {

Rectangle rect = super.getCellRect(row, column, includeSpacing);

int sectionHeadingsAbove = sectionHeadings.headMap(row, true).size();
rect.y += sectionHeadingsAbove * getRowHeight();

return rect;
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);

boolean ltr = getComponentOrientation().isLeftToRight();

int rowHeight = getRowHeight();
FontMetrics metrics = g.getFontMetrics();
int ascent = metrics.getAscent();
for (Map.Entry<Integer, String> entry : sectionHeadings.entrySet()) {
int row = entry.getKey();
String heading = entry.getValue();

Rectangle bounds = getCellRect(row, 0, true);
bounds.y -= rowHeight;
bounds.width = getWidth();
bounds.grow(-6, 0);

iconBounds.setBounds(0, 0, 0, 0);
textBounds.setBounds(0, 0, 0, 0);
String text = SwingUtilities.layoutCompoundLabel(this,
metrics, heading, null,
SwingConstants.CENTER, SwingConstants.LEADING,
SwingConstants.CENTER, SwingConstants.CENTER,
bounds, iconBounds, textBounds, 0);

g.drawString(text, textBounds.x, textBounds.y + ascent);

int lineY = textBounds.y + ascent / 2;
if (ltr) {
g.drawLine(textBounds.x + textBounds.width + 12, lineY,
getWidth() - getInsets().right - 12, lineY);
} else {
g.drawLine(textBounds.x - 12, lineY,
getInsets().left + 12, lineY);
}
}
}

public static void main(String[] args) {

DefaultTableModel model;
Object[][] data = new Object[50][5];
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};

for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
data[i][j] = "Amy";
}
}

for (int i = 10; i < 20; i++) {
for (int j = 0; j < 5; j++) {
data[i][j] = "Bob";
}
}

for (int i = 20; i < 30; i++) {
for (int j = 0; j < 5; j++) {
data[i][j] = "Joe";
}
}

for (int i = 30; i < 50; i++) {
for (int j = 0; j < 5; j++) {
data[i][j] = "M";
}
}

SectionedTable table = new SectionedTable();
model = new DefaultTableModel(data, columnNames);
table.setModel(model);

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new SectionedTable();
table.setModel(model);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(500, 500);
frame.setVisible(true);
}
});
}
}

我一直在努力找出可能导致此问题的原因,但还没有找到任何解决方案。我认为它可能在 rowAtPoint() 或 getCellRect() 处,但我不确定。有人能在代码中发现这个问题可能出在哪里吗?

最佳答案

我注意到当滚动停止运行时,getScrollableUnitIncrement(...) 方法返回 0

作为一个快速技巧,我将以下内容添加到您的表格中:

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
{
int increment = super.getScrollableUnitIncrement(visibleRect, orientation, direction);

if (increment == 0)
increment = 16;

return increment;
}

不知道会不会引起其他问题。由此我可以确定返回了 0,因此没有进行滚动。

关于java - JTable扩展后无法向下滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38424797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com