Java 为什么JScrollPane中的JPanel不滚动?
我在Java 为什么JScrollPane中的JPanel不滚动?,java,swing,jscrollpane,Java,Swing,Jscrollpane,我在JScrollPane中放置了一个JPanel(黄色) 当我在JTextPane中输入一些文本时,它会调整大小,但垂直滚动条仍然不活动yelowPanel.getSize()返回与以前相同的值。`(您可以在redPanel上看到它) 那么如何刷新黄色面板?我想垂直滚动面板。 我试图: panelCreating.revalidate(); panelCreating.invalidate(); panelCreating.repaint(); 仅适用于panelCreating.set
JScrollPane
中放置了一个JPanel
(黄色)
当我在JTextPane
中输入一些文本时,它会调整大小,但垂直滚动条仍然不活动yelowPanel.getSize()
返回与以前相同的值。`(您可以在redPanel上看到它)
那么如何刷新黄色面板?我想垂直滚动面板。
我试图:
panelCreating.revalidate();
panelCreating.invalidate();
panelCreating.repaint();
仅适用于panelCreating.setPreferredSize(新维度(333777))代码>但我不知道该设置什么尺寸。这取决于内容
有一个小例子:
package swingtest;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class SwingTest extends JFrame {
public SwingTest() {
initComponents();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new SwingTest().setVisible(true);
}
});
}
private JPanel panelCenter, panelCreating;
private JScrollPane scrollPaneCreating, scrollPaneCenter;
private JTextPane textPane1, textPane2;
private JButton button1;
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(300, 300));
panelCreating = new JPanel();
panelCreating.setMinimumSize(new Dimension(160, 200));
panelCreating.setPreferredSize(new Dimension(160, 200));
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textPane1 = new JTextPane();
textPane1.setText("a\na");
textPane2 = new JTextPane();
textPane2.setText("b\nb");
button1 = new JButton("+++");
panelCenter = new JPanel();
panelCenter.setBackground(Color.blue);
scrollPaneCenter = new JScrollPane(panelCenter);
// ----------------- Left Panel Init -----------------------
panelCreating.setLayout(new GridBagLayout());
panelCreating.setBackground(Color.ORANGE);
panelCreating.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0, 0, 4, 4);
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.weightx = c.weighty = 0;
c.gridx = 0;
c.gridy = GridBagConstraints.RELATIVE;
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = 1;
c.fill = GridBagConstraints.BOTH;
panelCreating.add(textPane1, c);
button1.addActionListener(new ActionListener() {
int height = 50;
@Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
textPane2.setPreferredSize(new Dimension(150, height));
height += 30;
panelCreating.revalidate();
panelCreating.repaint();
scrollPaneCreating.revalidate();
}
});
panelCreating.add(button1, c);
panelCreating.add(textPane2, c);
// -------------------------------------------------------
getContentPane().setLayout(new GridBagLayout());
c = new GridBagConstraints();
c.ipadx = c.ipady = 0;
c.insets = new Insets(0, 0, 0, 0);
c.weighty = 0;
c.gridheight = 1;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.weightx = 0;
c.fill = GridBagConstraints.BOTH;
getContentPane().add(scrollPaneCreating, c);
c.gridx = 1;
c.gridy = 1;
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
getContentPane().add(scrollPaneCenter, c);
}
}
黄色面板也使用GridBagLayout。
对不起,我的英语是JPanel
的默认布局是FlowLayout
。尝试GridLayout
。有一个相关的例子。比如说,
panelCreating = new JPanel(new GridLayout());
scrollPaneCreating = new JScrollPane(panelCreating);
附录:也考虑嵌套布局。下面的示例使用左面板的
BoxLayout
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
/** @see https://stackoverflow.com/questions/9184476 */
public class SwingTest extends JFrame {
private static final int N = 8;
public SwingTest() {
initComponents();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new SwingTest().setVisible(true);
}
});
}
private JPanel panelCenter, panelCreating;
private JScrollPane scrollPaneCreating, scrollPaneCenter;
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panelCreating = new JPanel();
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panelCenter = new JPanel();
panelCenter.setBackground(Color.blue);
scrollPaneCenter = new JScrollPane(panelCenter);
// ----------------- Left Panel Init -----------------------
panelCreating.setLayout(new BoxLayout(panelCreating, BoxLayout.Y_AXIS));
panelCreating.setBackground(Color.orange);
panelCreating.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
panelCreating.add(createTextPane());
panelCreating.add(Box.createVerticalStrut(N));
panelCreating.add(createTextPane());
panelCreating.add(Box.createVerticalStrut(N));
panelCreating.add(createTextPane());
// -------------------------------------------------------
setLayout(new GridLayout(1, 0));
add(scrollPaneCreating);
add(scrollPaneCenter);
pack();
}
private JTextPane createTextPane() {
JTextPane pane = new JTextPane();
pane.setText(""
+ "Twas brillig and the slithy toves\n"
+ "Did gyre and gimble in the wabe;\n"
+ "All mimsy were the borogoves,\n"
+ "And the mome raths outgrabe.");
pane.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
return pane;
}
}
不要在面板creating
上设置首选大小,而是在滚动面板creating
上设置它。并且不要在文本组件上设置首选大小,它们会随着您添加新的文本行而增长。这样做的目的是让滚动窗格中的面板按需要增大,并限制滚动窗格本身的大小
// [...]
panelCreating = new JPanel();
//panelCreating.setMinimumSize(new Dimension(160, 200));
//panelCreating.setPreferredSize(new Dimension(160, 200));
scrollPaneCreating = new JScrollPane(panelCreating,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPaneCreating.setMinimumSize(new Dimension(160, 200));
scrollPaneCreating.setPreferredSize(new Dimension(160, 200));
// [...]
@Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
//textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
//textPane2.setPreferredSize(new Dimension(150, height));
//height += 30;
// This isn't necessary either
//panelCreating.revalidate();
//panelCreating.repaint();
//scrollPaneCreating.revalidate();
}
编辑以添加:另一种选择是在附加到滚动窗格的JViewport
上设置大小。视口是显示内容的位置。您可以将滚动窗格视为由视口和滚动条组成。如果滚动窗格设置为固定大小,则通过减去滚动条大小来确定视口大小。但如果视口设置为固定大小,则滚动窗格大小将通过将滚动条大小添加到视口大小来确定。如果要精确控制屏幕上显示的内容量,最好在视口中设置固定大小,因为滚动条大小可能因操作系统而异
scrollPaneCreating.getViewport().setMinimumSize(new Dimension(160, 200));
scrollPaneCreating.getViewport().setPreferredSize(new Dimension(160, 200));
我修复了添加一行时出现的问题
panelCreating.setPreferredSize(new Dimension((int) panelCreating.getPreferredSize().getWidth(),
(int)(panelCreating.getPreferredSize().getHeight()+30)));
该行必须插入以下行之后
@Override
public void actionPerformed(ActionEvent e) {
textPane1.setText(textPane1.getText() + "\na");
textPane1.setPreferredSize(new Dimension(150, height));
textPane2.setText(textPane2.getText() + "\nb");
textPane2.setPreferredSize(new Dimension(150, height));
height += 30;
说明:
当您在网格袋布局中设置文本窗格的首选大小时,网格袋布局不会设置其窗格的首选大小,但滚动窗格仅根据其中窗格的首选大小进行滚动。因此,每次更改窗格中组件的大小时,都必须设置窗格的新首选大小,这样滚动窗格将确切地知道他必须做什么。这就是我所做的,添加了一行,增加了creatingPanel的首选大小,这是scrollPanel内部的一行当其中的组件仅垂直增长时,为什么水平滚动条会自动启用?请包括一个,因为它不清楚你在问什么(至少对我来说)。对不起,我指的是垂直滚动条。@alaster请你用表单中的代码编辑你的帖子,因为这可能是一个教训,为什么JScrollPane不能使用绝对布局,+1来记录这个奇怪的问题。我只使用了GridBagLayout“Done”:对不起,完成了什么?我看到2个SSCCE请求,但没有SSCCE。我只使用GridBagLayout。内部和外部面板。但是当我在附加的SSCCE中使用GridBagLayout
时,我遇到了同样的问题。这是我的错误。我甚至不需要更改布局。谢谢