我试图在 JPanel
子类上绘制一些树结构,该子类是 JScrollPane
的客户端(ViewPort View )。我可以很好地绘制树,但即使它比视口(viewport)大,JScrollPane
也不会滚动。客户端是 JTextArea
的相同 JScrollPane
工作正常。
下面的代码创建了一个框架,其中有 2 个并排的滚动 Pane - 一个可以工作,另一个则不能。 (为了简单起见,我只是绘制文本。)我是 Swing GUI 的新手,所以我无疑做了一些愚蠢的事情,但是几天的搜索和阅读并没有告诉我我的错误。
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.Graphics;
public class ScrollTest extends javax.swing.JFrame {
public ScrollTest() {
initComponents();
prepComponents();
}
void prepComponents() {
leftScrollPaneContent = new JTextArea();
leftScrollPane.setViewportView(leftScrollPaneContent);
rightScrollPaneContent = new TestPanel();
rightScrollPane.setViewportView(rightScrollPaneContent);
String s = "Test of JTextArea setText()\n\n";
for (int i = 1; i < 30; i++) {
s += "Line " + i + ": This is a test.\n";
}
leftScrollPaneContent.setText(s);
rightScrollPaneContent.repaint();
}
@SuppressWarnings("unchecked")
private void initComponents() {
leftPanel = new javax.swing.JPanel();
jPanelLabel = new javax.swing.JLabel();
leftScrollPane = new javax.swing.JScrollPane();
rightPanel = new javax.swing.JPanel();
subclassLabel = new javax.swing.JLabel();
rightScrollPane = new javax.swing.JScrollPane();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanelLabel.setText("JTextArea in a ScrollPane");
leftScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
leftScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
javax.swing.GroupLayout leftPanelLayout = new javax.swing.GroupLayout(leftPanel);
leftPanel.setLayout(leftPanelLayout);
leftPanelLayout.setHorizontalGroup(
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(leftPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(leftScrollPane)
.addContainerGap())
.addGroup(leftPanelLayout.createSequentialGroup()
.addGap(101, 101, 101)
.addComponent(jPanelLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(114, Short.MAX_VALUE))
);
leftPanelLayout.setVerticalGroup(
leftPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(leftPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanelLabel)
.addGap(18, 18, 18)
.addComponent(leftScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE)
.addContainerGap())
);
subclassLabel.setText("JPanel subclass in a ScrollPane");
rightScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
rightScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
javax.swing.GroupLayout rightPanelLayout = new javax.swing.GroupLayout(rightPanel);
rightPanel.setLayout(rightPanelLayout);
rightPanelLayout.setHorizontalGroup(
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(rightPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(rightScrollPane)
.addContainerGap())
.addGroup(rightPanelLayout.createSequentialGroup()
.addGap(66, 66, 66)
.addComponent(subclassLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(77, Short.MAX_VALUE))
);
rightPanelLayout.setVerticalGroup(
rightPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(rightPanelLayout.createSequentialGroup()
.addComponent(subclassLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(rightScrollPane)
.addContainerGap())
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(leftPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(rightPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(14, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(leftPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGap(17, 17, 17)
.addComponent(rightPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addContainerGap())
);
pack();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ScrollTest().setVisible(true);
}
});
}
private javax.swing.JLabel jPanelLabel;
private javax.swing.JPanel leftPanel;
private javax.swing.JScrollPane leftScrollPane;
private javax.swing.JPanel rightPanel;
private javax.swing.JScrollPane rightScrollPane;
private javax.swing.JLabel subclassLabel;
// End of variables declaration
private JTextArea leftScrollPaneContent;
private JPanel rightScrollPaneContent;
public class TestPanel extends JPanel {
public void paint(Graphics g) {
super.paint(g);
g.drawString("Test of JPanel g.drawString()\n", 10, 20);
for (int i = 3; i < 33; i++) {
g.drawString("Line " + (i-2) + ": This is a test.", 10, 20 * i);
}
}
}
}
最佳答案
您的 JTextArea leftScrollPaneContent
覆盖
getPreferredSize()
巧妙地返回大小
来自实际文本和字体。
周围的 JScrollPane
使用这个大小来决定
如果需要滚动条。
此外,JTextArea
(因为从JTextComponent
扩展)
还实现了Scrollable
界面。
这为周围的 JSollPane
提供了一些额外的提示
以获得更好的滚动行为。
您的TestPanel rightScrollPaneContent
不执行任何操作。
因此它从 JPanel
继承了 getPreferredSize()
方法
仅返回一个很小的 10x10 尺寸(这对于
空的JPanel
,没有子组件)。
因此周围的 JScrollPane
决定没有
需要为这个据称很小的内容显示任何滚动条。
因此,最重要的是,在您的 TestPanel
中,您需要覆盖
getPreferredSize()
并在那里返回一个合理的大尺寸。
作为奖励(为了更好的滚动行为),您还可以实现
可滚动
界面。
或者您选择从另一个类(class)扩展您的类(class)
它已经实现了 Scrollable
接口(interface)。
关于java - 当我在 ViewPort 中绘制 JPanel 时,JScrollPane 不滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53823324/