问题
I've found some examples scattered around the internet involving getting an image or a textbox to display scroll bars, but they all involve a program that basically displays its entire contents in a scroll pane. What I need to get it to do is stick a JPanel somewhere, pile a bunch of text, icons, etc into that panel until its too big for the space I've got for it, and then scroll across it.
I'm probably going to need to be able to null-layout that panel, too, because I'm probably going to have to manually position things within it sooner or later.
So I tried to make a pretty simply program that would put three colored blocks in a space big enough for two, and display a scrollbar that would let you scroll down to see the third one. It doesn't add the scroll bar.
The imports are a bit of a mess and redundant, because this is cobbled together from a couple different files, but they're not generating any errors.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
public class ScrollDemo extends JFrame {
JScrollPane scrollpane;
public ScrollDemo() {
super("JScrollPane Demonstration");
setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
init();
setVisible(true);
}
public void init() {
setLayout(null);
JPanel innerPanel = new JPanel();
JPanel outerPanel = new JPanel();
getContentPane().setBounds(0,0,800,600);
outerPanel.setBounds(400,0,400,400);
innerPanel.setBounds(0,0,600,600);
innerPanel.setLayout(null);
JPanel greenPanel = new JPanel();
JPanel yellowPanel = new JPanel();
JPanel bluePanel = new JPanel();
greenPanel.setBounds(0,0,200,200);
yellowPanel.setBounds(0,200,200,200);
bluePanel.setBounds(0,400,200,200);
greenPanel.setBackground(Color.GREEN);
yellowPanel.setBackground(Color.YELLOW);
bluePanel.setBackground(Color.BLUE);
innerPanel.add(greenPanel);
innerPanel.add(yellowPanel);
innerPanel.add(bluePanel);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(innerPanel);
scrollPane.setBounds(200,0,200,400);
add(scrollPane);
}
public static void main(String args[]) {
new ScrollDemo();
}
}
回答1:
Better that you should use layout managers to your advantage and to let these managers do the heavy lifting of calculating component sizes and placements for you. For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class ScrollDemo2 extends JPanel {
public static final Color[] COLORS = {Color.green, Color.red, Color.blue};
private static final Dimension PANEL_SIZE = new Dimension(300, 300);
public ScrollDemo2() {
JPanel innerPanel = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < COLORS.length; i++) {
JPanel colorPanel = new JPanel();
colorPanel.setPreferredSize(PANEL_SIZE);
colorPanel.setBackground(COLORS[i]);
innerPanel.add(colorPanel);
}
JScrollPane scrollPane = new JScrollPane(innerPanel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getViewport().setPreferredSize(PANEL_SIZE);
int eb = 10;
setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
}
private static void createAndShowGui() {
ScrollDemo2 mainPanel = new ScrollDemo2();
JFrame frame = new JFrame("ScrollDemo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
回答2:
In Swing, sizing and positioning of children is the exclusive job of a LayoutManager. Choose one that supports your requirements, as a last resort implement a highly specialized one. Children collaborate by reporting sizing hints, so implement any custom components to return something reasonable in the getXXSize methods.
When you feel an irresistable urge to manually interfere, at least let the manager do as much as possible. In your context that might be to take over the positioning but let the manager handle the sizing, particularly calculating the sizing hints of the parent. Here's a code snippet using Rob's DragLayout:
DragLayout layout = new DragLayout();
JComponent field = new JPanel(layout);
JComponent player = new JLabel("I'm moving around");
field.add(player);
player.setLocation(200, 200);
frame.add(new JScrollPane(field));
frame.pack();
frame.setVisible(true);
回答3:
Figures. Soon as I post I realize what's wrong.
Because innerPanel has a null Layout it needs to have its preferred size explicitly declared.
innerPanel.setPreferredSize(new Dimension(200,600));
fixes it.
来源:https://stackoverflow.com/questions/11379533/im-having-trouble-getting-jscrollpanes-to-actually-display-scroll-bars