java jScrollPane 无法添加组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14149608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jScrollPane can't add component
提问by Feanaro
I have a jScrollPane
and a button on a form. The button adds a component to the jScrollPane
. I'm using a FlowLayout
with a center alignment to arrange the components within the jScrollPane
.
我jScrollPane
在表单上有一个和一个按钮。该按钮将一个组件添加到jScrollPane
. 我正在使用FlowLayout
带有中心对齐的 a 来排列jScrollPane
.
The first component has no problems appearing and is aligned perfectly. When I then hit the button again, nothing seems too happen. When I follow the debugger it shows that everything happens precisely as before.
第一个组件没有出现问题并且完美对齐。当我再次按下按钮时,似乎什么也没有发生。当我跟随调试器时,它表明一切都和以前一样发生。
The code that's being executed when the button is clicked:
单击按钮时正在执行的代码:
jScrollPane.getViewport().add(new Component());
This is how I setup the FlowLayout
on the Viewport
of the jScrollPane
:
这就是我在FlowLayout
上设置Viewport
的方式jScrollPane
:
jScrollPane.getViewport().setLayout(new FlowLayout(FlowLayout.CENTER));
回答by MadProgrammer
You're mixing heavy weight (AWT) components with light weight (Swing) components, this is inadvisable as they don't tend to play well together.
您将重量级 (AWT) 组件与轻量级 (Swing) 组件混合在一起,这是不可取的,因为它们往往不能很好地协同工作。
JScrollPane
contains a JViewPort
onto which you can add a child component, AKA the view.
JScrollPane
包含一个JViewPort
您可以在其上添加子组件,也就是视图。
(image from the JavaDocs)
(来自JavaDocs 的图像)
So the call jScrollPane.getViewport().setLayout(new FlowLayout(FlowLayout.CENTER));
is actually setting the JViewPort
's layout manager, which really isn't advisable.
所以调用jScrollPane.getViewport().setLayout(new FlowLayout(FlowLayout.CENTER));
实际上是设置JViewPort
的布局管理器,这确实是不可取的。
What you should do is create the component you want to add to the scrollpane, set it's layout and add all it's child components to it and then add it to the scroll pane. You can add components to the "view" at later stage if you want, but that's up to you...
您应该做的是创建要添加到滚动窗格的组件,设置其布局并将其所有子组件添加到其中,然后将其添加到滚动窗格。如果需要,您可以在稍后阶段将组件添加到“视图”,但这取决于您...
// Declare "view" as a class variable...
view = new JPanel(); // FlowLayout is the default layout manager
// Add the components you need now to the "view"
JScrollPane scrollPane = new JScrollPane(view);
Now you can add new components to the view as you need...
现在您可以根据需要向视图添加新组件...
view.add(...);
If you don't want to maintain a reference to view
, you can access it by calling JViewport#getView
which will return the component been managed by the view port.
如果您不想维护对 的引用view
,您可以通过调用来访问它,JViewport#getView
这将返回由视口管理的组件。
JPanel view = (JPanel)scrollPane.getViewPort().getView();
Working Example
工作示例
This works fine for me...
这对我来说很好用...
nb - I added view.validate()
to my code, which you may not have had, after I added a new component...
nb -view.validate()
在我添加了一个新组件之后,我添加了我的代码,你可能没有
public class TestScrollPane01 {
public static void main(String[] args) {
new TestScrollPane01();
}
public TestScrollPane01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
private JScrollPane scrollPane;
private int count;
public MainPane() {
setLayout(new BorderLayout());
scrollPane = new JScrollPane(new JPanel());
((JPanel)scrollPane.getViewport().getView()).add(new JLabel("First"));
add(scrollPane);
JButton add = new JButton("Add");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JPanel view = ((JPanel)scrollPane.getViewport().getView());
view.add(new JLabel("Added " + (++count)));
view.validate();
}
});
add(add, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}