问题
Currently, I have to JComponents contained in a JPanel with a vertical box layout. This way, I can have the first component centered, as shown below, and have the bottom component (which is quite long) below. However, since the bottom component is very long I wanted to add a slider just for that specific component. This way, the user can see all of the bottom component with the upper component remaining centered. However, my code below doesn't fix anything and the scrollbar never even works. The only information about GPComponent and GPinfinity you need to know is they override the preferredSize, minimumSize, maximumSize, and paintComponent methods (they extend JComponent).
JFrame frame = new JFrame();
JPanel panel = new JPanel();
GPComponent gp = new GPComponent(n, k);
GPinfinityComponent gpi = new GPinfinityComponent(n, k);
Box box = new Box(BoxLayout.Y_AXIS);
panel.add(Box.createVerticalGlue());
panel.add(gp);
panel.add(Box.createVerticalGlue());
JScrollPane thePane = new JScrollPane(gpi, JScrollPane.VERTICAL_SCROLLBAR_NEVER,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
panel.add(thePane);
frame.pack();6
frame.add(panel, BorderLayout.CENTER); // just to be clear
frame.setVisible(true);
final int FRAME_WIDTH = 600;
final int FRAME_HEIGHT = 600;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("GP("+n+", "+k+")");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Also: the maximumSize=minimumSize=preferredSize for both components For the circular one the dimensions are (350, 350) and for the other the dimensions are (5000, 150).
回答1:
You state:
...and for the other the dimensions are (5000, 150).
If this is the component that is supposed to show the scrollbars, the Java is telling you otherwise, that it is in fact much shorter than you suppose it to be. I wonder if you're setting size instead of preferredSize. You actually should not be setting either but rather should override getPreferredSize()
and have it return a dimension appropriate for the component.
For more detailed help, consider creating and posting a minimal example program.
Edit
For example, my MCVE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import javax.swing.*;
@SuppressWarnings("serial")
public class PreferredSizeEg extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
public PreferredSizeEg() {
JPanel centerPanel = new JPanel(new GridBagLayout());
centerPanel.add(new CenterImagePanel());
JScrollPane scrollpane = new JScrollPane(new LongImagePanel(),
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setLayout(new BorderLayout());
add(centerPanel, BorderLayout.CENTER);
add(scrollpane, BorderLayout.PAGE_END);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class LongImagePanel extends JPanel {
private static final int LI_PREF_W = 5000;
private static final int LI_PREF_H = 150;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int index = 0;
int spriteWidth = 50;
while ((index) * spriteWidth < getWidth()) {
Color c = index % 2 == 0 ? Color.green : Color.red;
g.setColor(c);
int x = 2 + index * spriteWidth;
int y = 2;
int width = getHeight() - 4;
int height = width;
g.fillOval(x, y, width, height);
index++;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(LI_PREF_W, LI_PREF_H);
}
}
private class CenterImagePanel extends JPanel {
private static final int CIP_PREF_W = 200;
private static final int CIP_PREF_H = CIP_PREF_W;
public CenterImagePanel() {
setBorder(BorderFactory.createLineBorder(Color.BLACK));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.green);
int x = 5;
int y = x;
int width = getWidth() - 2 * x;
int height = getHeight() - 2 * y;
g.fillOval(x, y, width, height);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(CIP_PREF_W, CIP_PREF_H);
}
}
private static void createAndShowGui() {
PreferredSizeEg mainPanel = new PreferredSizeEg();
JFrame frame = new JFrame("PreferredSizeEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
}
});
}
}
Which displays as:
来源:https://stackoverflow.com/questions/24770777/how-to-add-a-scrollbar-for-long-jcomponents-in-a-jpanel-how-to-center-a-jcompon