gpt4 book ai didi

java - 当您滚动超过某个点时, Swing 滚动 Pane 会发出通知

转载 作者:行者123 更新时间:2023-12-01 13:36:12 26 4
gpt4 key购买 nike

哟伙计们。我需要关于如何最好地实现某些事情的建议。我的程序:

我有一个 swing 程序,可以读取包含多个不同类型记录的文件。我将这些记录读入 java 对象,使用它们的标题和内容制作 JTable(因此每个表只有标题和 1 条记录),将这些表添加到面板中,并将面板添加到滚动 Pane 中。记录很多,大约70000条,所以我无法一次将所有内容加载到内存中。

我的计划是通过一次仅显示 100 条记录来对显示进行分页,如果您滚动经过某个点(例如第 50 个表),它将加载接下来的 100 个表并将它们添加到滚动 Pane 。

这让我想到了我的问题

1)我不知道如何通知自己我已经滚动到某个点了。因此,考虑到我有 100 个 JTable 附加到附加到滚动 Pane 的 JPanel 上。为了论证起见,我如何添加一个监听器来通知用户何时滚动过 Jtable 50。

2)我遇到的另一个问题与我如何将表格放入面板有关。我使用如下的 Swingworker:

private class TableRun extends SwingWorker<Void, JTable> {

private ArrayDeque<FileRecord> fileRecords;
private final GridBagConstraints gc;
private final JPanel parentPanel;
int counter = 1;

TableRun(ArrayDeque<FileRecord> fileRecords, GridBagConstraints gc, JPanel parentPanel) {
this.fileRecords = fileRecords;
this.gc = gc;
this.parentPanel = parentPanel;
}

@Override
protected Void doInBackground() {
Iterator<FileRecord> iterator = fileRecords.iterator();
while (iterator.hasNext()) {
publish(getTabel(iterator.next()));
}

return null;
}

@Override
protected void process(final List<JTable> tables) {
Iterator<JTable> iterator = tables.iterator();
while(iterator.hasNext()) {
JTable table = iterator.next();
gc.fill = 1;
parentPanel.add(table.getTableHeader(), gc);
gc.gridy++;
parentPanel.add(table,gc);
gc.gridy++;

//validate takes a long time so i try to not do it too often.
if(counter == 50 || (counter % 5000) ==0 || (counter == fileRecords.size())) {
validate();
}
System.out.println("Sequence Nr : " + table.getModel().getValueAt(0,1) + " - Counter :" + counter++);
}
}
}

我把我的唱片对象喂给 Swing worker 。然后,它将记录转换为具有所有必要格式的 JTable,然后将它们添加到面板中。有时它会调用 validate 来显示表,否则它不会显示它们。 (不确定是否有更好的方法来做到这一点?)

所以我的问题与滚动有关。如果我最初只将 70000 条记录中的 100 条提供给我的 swinworker,它显然会创建滚动 Pane ,认为只有 100 条记录。所以滚动条不是很小(即很明显你不能滚动很远)。我真正想要的是,即使我只显示 100 条记录,我希望滚动 Pane 的大小为 70000 条记录的大小,以便您可以根据滚动条看到记录的大小。如果将滚动条拖动到底部的某个点,它们需要拉出并显示这些记录。如何根据组件的大小创建比其中实际组件更大的滚动 Pane 尺寸?

希望我的问题有意义

谢谢

最佳答案

How can i add a listener to notify when the user has scrolled past say Jtable 50 for arguments sake.

例如(可能的方法之一,您可以测试 oneRectangle.intersects(anotherRectangle) ),(抱歉)其余问题无法回答,请注意,您必须从父级(JScrollPane 包含JPanel) 到子级包含 JTables

enter image description here

.

enter image description here

.

enter image description here

.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.RepaintManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableModel;

//http://stackoverflow.com/a/8249353/714968
public class ViewPortFlickeringOriginal {

private JFrame frame = new JFrame("Table");
private JViewport viewport = new JViewport();
private Rectangle RECT = new Rectangle();
private Rectangle RECT1 = new Rectangle();
private JTable table = new JTable(50, 3);
private javax.swing.Timer timer;
private int count = 0;
private boolean topOrBottom = false;
private GradientViewPortOriginal tableViewPort;

public ViewPortFlickeringOriginal() {
tableViewPort = new GradientViewPortOriginal(table);
viewport = tableViewPort.getViewport();
viewport.addChangeListener(new ChangeListener() {

@Override
public void stateChanged(ChangeEvent e) {
if (tableViewPort.bolStart) {
RECT = table.getCellRect(0, 0, true);
RECT1 = table.getCellRect(table.getRowCount() - 1, 0, true);
Rectangle viewRect = viewport.getViewRect();
if (viewRect.intersects(RECT)) {
System.out.println("Visible RECT -> " + RECT);
tableViewPort.paintBackGround(new Color(250, 150, 150));
} else if (viewRect.intersects(RECT1)) {
System.out.println("Visible RECT1 -> " + RECT1);
tableViewPort.paintBackGround(new Color(150, 250, 150));
} else {
System.out.println("Visible RECT1 -> ???? ");
tableViewPort.paintBackGround(new Color(150, 150, 250));
}
}
}
});
frame.add(tableViewPort);
frame.setPreferredSize(new Dimension(600, 300));
frame.pack();
frame.setLocation(50, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RepaintManager.setCurrentManager(new RepaintManager() {

@Override
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
Container con = c.getParent();
while (con instanceof JComponent) {
if (!con.isVisible()) {
return;
}
if (con instanceof GradientViewPortOriginal) {
c = (JComponent) con;
x = 0;
y = 0;
w = con.getWidth();
h = con.getHeight();
}
con = con.getParent();
}
super.addDirtyRegion(c, x, y, w, h);
}
});
frame.setVisible(true);
start();
}

private void start() {
timer = new javax.swing.Timer(100, updateCol());
timer.start();
}

public Action updateCol() {
return new AbstractAction("text load action") {

private static final long serialVersionUID = 1L;

@Override
public void actionPerformed(ActionEvent e) {

System.out.println("updating row " + (count + 1));
TableModel model = table.getModel();
int cols = model.getColumnCount();
int row = 0;
for (int j = 0; j < cols; j++) {
row = count;
table.changeSelection(row, 0, false, false);
timer.setDelay(100);
Object value = "row " + (count + 1) + " item " + (j + 1);
model.setValueAt(value, count, j);
}
count++;
if (count >= table.getRowCount()) {
timer.stop();
table.changeSelection(0, 0, false, false);
java.awt.EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
table.clearSelection();
tableViewPort.bolStart = true;
}
});
}
}
};
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
ViewPortFlickeringOriginal viewPortFlickering = new ViewPortFlickeringOriginal();
}
});
}
}

class GradientViewPortOriginal extends JScrollPane {

private static final long serialVersionUID = 1L;
private final int h = 50;
private BufferedImage img = null;
private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB);
private JViewport viewPort;
public boolean bolStart = false;

public GradientViewPortOriginal(JComponent com) {
super(com);
viewPort = this.getViewport();
viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE);
viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
paintBackGround(new Color(250, 150, 150));
}

public void paintBackGround(Color g) {
Graphics2D g2 = shadow.createGraphics();
g2.setPaint(g);
g2.fillRect(0, 0, 1, h);
g2.setComposite(AlphaComposite.DstIn);
g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h,
new Color(0.1f, 0.8f, 0.8f, 0.5f)));
g2.fillRect(0, 0, 1, h);
g2.dispose();
}

@Override
public void paint(Graphics g) {
if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) {
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2 = img.createGraphics();
super.paint(g2);
Rectangle bounds = getViewport().getVisibleRect();
g2.scale(bounds.getWidth(), -1);
int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight();
g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null);
g2.scale(1, -1);
g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null);
g2.dispose();
g.drawImage(img, 0, 0, null);
}
}

关于java - 当您滚动超过某个点时, Swing 滚动 Pane 会发出通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21252587/

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