這是我的 ScrollPane 代碼
public class CustomScrollPane extends JScrollPane {
private static CustomScrollPane instance = null;
public CustomScrollPane () {
super(panel.getInstance()); // a panel that the scrollpane wraps around
this.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// hide the vertical scroll bar
this.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
}
public static CustomScrollPane getInstance() {
if (instance == null)
instance = new CustomScrollPane ();
return instance;
}
我嘗試這樣做getVerticalScrollbar.setValue(getVerticalScrollbar().getMaximum()),但是當我向其中添加 JLabels 時它不會滾動到最后。我正在嘗試使它在新的 JLabel 添加到面板后始終滾動到螢屏底部。我不使用 JTextArea,因為我希望每行都有不同的前景色,所以我使用了 JLabels。
我也嘗試添加此方法
public void scrollToBottom() { getVerticalScrollbar().getMaximum(); }
但它只是凍結了 ScrollPane,我無法滾動。
任何幫助,將不勝感激!
uj5u.com熱心網友回復:
我不確定您希望通過擴展來實作什么JScrollPane,不確定它是否真的是它的核心職責,畢竟,您可以讓它的“視口視圖”自己完成,例如......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JPanel contentPane = new JPanel(new GridLayout(-1, 8));
for (int index = 0; index < 1000; index ) {
contentPane.add(new SqaurePane());
}
add(new JScrollPane(contentPane));
JButton top = new JButton("Top");
JButton bottom = new JButton("Bottom");
JPanel actionPane = new JPanel();
actionPane.add(top);
actionPane.add(bottom);
add(actionPane, BorderLayout.SOUTH);
top.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
contentPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
}
});
bottom.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
contentPane.scrollRectToVisible(new Rectangle(0, contentPane.getHeight(), 0, 0));
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
static List<Color> COLORS = new ArrayList<>(Arrays.asList(new Color[] {
Color.BLACK,
Color.BLUE,
Color.CYAN,
Color.DARK_GRAY,
Color.GRAY,
Color.GREEN,
Color.LIGHT_GRAY,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.RED,
Color.WHITE,
Color.YELLOW,
}));
public class SqaurePane extends JPanel {
public SqaurePane() {
Collections.shuffle(COLORS);
setBackground(COLORS.get(0));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
}
}
魔法就在這里……
top.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
contentPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
}
});
bottom.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
contentPane.scrollRectToVisible(new Rectangle(0, contentPane.getHeight(), 0, 0));
}
});
在這里,我要求contentPane(這是包含所有正方形的容器)根據我的需要“滾動到可見的矩形”
現在,在您的情況下,當您將新組件添加到“容器”時,您需要指示組件滾動到顯示新組件的位置。
This is going to be a little more complicated as you will need to trigger a layout pass first, so you can get the new size of the container
Dynamic addition to the container...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JPanel contentPane = new JPanel(new GridLayout(-1, 8));
add(new JScrollPane(contentPane));
for (int index = 0; index < 8 * 8; index ) {
contentPane.add(new SqaurePane());
}
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SqaurePane sqaurePane = new SqaurePane();
contentPane.add(sqaurePane);
contentPane.revalidate();
// There is an issue with how the layout pass runs, this
// "seems" to be getting pushed onto the EDT later, which
// is messing up the scroll logic.
// So, instead, we push this on to the EDT to be executed
// "later" after the layout pass has run. Yes, I tried
// calling doLayout directly, but, for the first element
// of each row, it wouldn't work correctly
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
contentPane.scrollRectToVisible(new Rectangle(0, sqaurePane.getY(), 1, sqaurePane.getHeight()));
}
});
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
static List<Color> COLORS = new ArrayList<>(Arrays.asList(new Color[]{
Color.BLACK,
Color.BLUE,
Color.CYAN,
Color.DARK_GRAY,
Color.GRAY,
Color.GREEN,
Color.LIGHT_GRAY,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.RED,
Color.WHITE,
Color.YELLOW,}));
public class SqaurePane extends JPanel {
public SqaurePane() {
Collections.shuffle(COLORS);
setBackground(COLORS.get(0));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
}
}
Now, if you really wanted to decouple the concept, you could us a ContainerListener and react to the new component been added via it
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/434902.html
下一篇:我們如何比較兩個字串并獲取重復值
