Thật lạ khi JScrollPane
không có phương thức addAdjustmentListener()
. Tuy nhiên, adjustListener được cho là được sử dụng với thanh cuộn. Tôi muốn một cái gì đó xảy ra bất cứ khi nào JScrollPane
được cuộn theo một trong hai cách. Làm thế nào để đạt được một điều như vậy?Sự kiện cuộn của JScrollPane
15
A
Trả lời
9
Tại sao bạn không nhận thanh cuộn thực tế và sau đó thêm trình điều chỉnh cho người nghe? JScrollBar
có phương thức được gọi là addAdjustmentListener()
.
Và bạn có thể sử dụng getVerticalScrollBar()
và getHorizontalScrollBar()
để có được một JScrollBar
từ một JScrollPane
14
Thay vì cố gắng lắng nghe những thay đổi từ JScrollPane, có khung nhìn cho rằng ô cuộn thêm một người biết lắng nghe sự thay đổi với nó:
1
ví dụ (old.good.forums.sun.com)
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class TilePainter extends JPanel implements Scrollable {
private static final long serialVersionUID = 1L;
private final int TILE_SIZE = 50;
private final int TILE_COUNT = 100;
private final int visibleTiles = 10;
private final boolean[][] loaded;
private final boolean[][] loading;
private final Random random;
public TilePainter() {
setPreferredSize(new Dimension(TILE_SIZE * TILE_COUNT, TILE_SIZE * TILE_COUNT));
loaded = new boolean[TILE_COUNT][TILE_COUNT];
loading = new boolean[TILE_COUNT][TILE_COUNT];
random = new Random();
}
public boolean getTile(final int x, final int y) {
boolean canPaint = loaded[x][y];
if (!canPaint && !loading[x][y]) {
loading[x][y] = true;
Timer timer = new Timer(random.nextInt(500),
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loaded[x][y] = true;
repaint(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
});
timer.setRepeats(false);
timer.start();
}
return canPaint;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle clip = g.getClipBounds();
int startX = clip.x - (clip.x % TILE_SIZE);
int startY = clip.y - (clip.y % TILE_SIZE);
for (int x = startX; x < clip.x + clip.width; x += TILE_SIZE) {
for (int y = startY; y < clip.y + clip.height; y += TILE_SIZE) {
if (getTile(x/TILE_SIZE, y/TILE_SIZE)) {
g.setColor(Color.GREEN);
} else {
g.setColor(Color.RED);
}
g.fillRect(x, y, TILE_SIZE - 1, TILE_SIZE - 1);
}
}
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(visibleTiles * TILE_SIZE, visibleTiles * TILE_SIZE);
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return TILE_SIZE * Math.max(1, visibleTiles - 1);
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return TILE_SIZE;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Tiles");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(new TilePainter()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
+0
+1 cho lịch sử. – trashgod
5
Theo Jesse Barnum:
// requiring that you already have JPanel additionsPane inside
// JScrollPane additionsScrollPane inside JFrame frame ...
additionsScrollPane.getViewport().addChangeListener(new ListenAdditionsScrolled());
public class ListenAdditionsScrolled implements ChangeListener{
public void stateChanged(ChangeEvent e){
additionsPane.revalidate();
frame.repaint();
}
}
Tôi thấy đây là cách tốt nhất. Tôi thậm chí còn dán mã hỗ trợ của tôi ở bên dưới. Cảm ơn, Eugene. – ekerner