I have a JFrame with dimension 500 X 500: it contains a JComponent with size 1000 X 1000 and this JComponent is contained into a JScrollBar with scrollbar always present. The screenshot
The code
/**component */
public class LinesComponent extends JPanel
....
/***other class: CommandPanel contains the LinesComponents*/
public class CommandPanel extends JPanel{
....
private LinesComponent panel;
/*JScrollPanel*/
private void buildScrollPanel(Container container) {
JScrollPane scroll = new JScrollPane(panel);
scroll.setSize(1000,1000);
scroll.setBorder(new LineBorder(Color.BLACK));
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
container.add(scroll);
}
/**JFrame*/
private void buildFrame(String title) {
this.testFrame = new JFrame(title);
this.testFrame.setLayout(new FlowLayout());
this.testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.testFrame.setLocationRelativeTo(null);
this.testFrame.setSize(500,500);
this.testFrame.setBackground(EnumColor.BACKGROUND_PANEL.getValue());
}
//end CommandPanel
As showed into screenshot, the window has the scrollbar but it isn't working.
I tried to change the dimensions of JPanel and JFrame but the situation doesn't change.
I know that the scroll appears when the dimension of JComponent are greater of dimensione of JPanel container, but in this moment I see that I lose some information but I don't understand what is.
Do you have any suggest, please?
PS into screenshot I show that the scroll doesn't work, but in my desiderata the scroll has to work in vertical and horizontal senses
PS PS all my code in only one class
package testDebug;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.LineBorder;
public class AllClasses {
public static void main(String[] a){
CommandPanel commandPanel=new CommandPanel("test", new ArrayList<MyPoint>());
}
}
class LinesComponent extends JPanel{
private static final long serialVersionUID = 1L;
private final LinkedList<Line> lines = new LinkedList<Line>();
private static class Line {
final int x1;//x del primo punto
final int y1;//y del primo punto
final int x2;//x del secondo punto
final int y2;//y del secondo punto
final Color color;
final int pressure;
public Line(int x1, int y1, int x2, int y2, Color color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.color = color;
this.pressure=3;
}
public Line(int x1, int y1, int x2, int y2, int newPressure, Color color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.pressure=newPressure;
this.color = color;
}
}//Line
public LinesComponent(){
setBorder(new LineBorder(Color.BLACK));
setBackground(Color.WHITE);
setPreferredSize(new Dimension(400, 400));
}
public void clearLines() {
this.lines.clear();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : this.lines) {
g.setColor(line.color);
g.fillOval(line.x1,line.y1, line.pressure, line.pressure);
}
}
public void addPoint(MyPoint p, Color randomColor) {
//call addLine(double x, double y, double xtilt, double ytilt, Color randomColor);
}
private void addLine(double x, double y, double xtilt, double ytilt, Color randomColor) {
this.lines.add(new Line((int) x, (int) y, (int) xtilt, (int) ytilt, randomColor));
repaint();
}
}
enum EnumButton {
DECREASE_X("-"),
INCREASE_X("+"),
DECREASE_Y("-"),
INCREASE_Y("+"),
DECREASE_ZOOM("-"),
INCREASE_ZOOM("+");
private JButton button;
public JButton button(){
return this.button;
}
private EnumButton(String s){
this.button=new JButton(s);
}
public void addActionListener(ActionListener a){
this.button().addActionListener(a);
}
}
class CommandPanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final String INITIAL_POSITION="0";
private JFrame testFrame = null;
private LinesComponent panelSignature;
private JTextField positionX=new JTextField(5);
private JTextField positionY=new JTextField(5);
public CommandPanel(String title, List<MyPoint> newPoints) {
super();
positionX.setText(INITIAL_POSITION);
positionY.setText(INITIAL_POSITION);
buildFrame(title);
Container container = testFrame.getContentPane();
this.panelSignature=initPanel();
buildScrollPanel(container);
paintLine(newPoints);
allignButtons();
defineFrame();
}
private void buildScrollPanel(Container container) {
JScrollPane scroll = new JScrollPane(panelSignature);
scroll.setSize(300,300);
scroll.setBorder(new LineBorder(Color.BLACK));
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
container.add(scroll);
}
private void defineFrame() {
this.testFrame.pack();
this.testFrame.setVisible(true);
}
private void paintLine(List<MyPoint> points) {
Iterator<MyPoint> iterator = points.iterator();
while (iterator.hasNext()) {
MyPoint point = iterator.next();
this.panelSignature.addPoint(point,Color.BLUE);
}
}//disegnaLinea
private void allignButtons() {
JPanel buttonPanel = new JPanel(new FlowLayout());
sectionHorizontalMovement(buttonPanel);
sectionVerticalMovement(buttonPanel);
sectionZoom(buttonPanel);
this.testFrame.add(buttonPanel);
}
private void sectionZoom(JPanel buttonPanel) {
buttonPanel.add(EnumLabel.ZOOM.label());
buttonPanel.add(EnumButton.INCREASE_ZOOM.button());
buttonPanel.add(EnumButton.DECREASE_ZOOM.button());
buttonPanel.add(EnumLabel.ZOOM_DIRECTION.label());
buttonPanel.add(EnumLabel.EMPTY.label());
}//sezioneZoom
private void sectionVerticalMovement(JPanel pannelloPulsanti) {
pannelloPulsanti.add(EnumLabel.MOVE_UP_DOWN.label());
pannelloPulsanti.add(EnumButton.INCREASE_Y.button());
pannelloPulsanti.add(EnumButton.DECREASE_Y.button());
pannelloPulsanti.add(EnumLabel.Y_DIRECTION.label());
pannelloPulsanti.add(EnumLabel.MAX_Y_ALLOWED.label());
}//sezioneSpostamentoVerticale
private void sectionHorizontalMovement(JPanel pannelloPulsanti) {
pannelloPulsanti.add(EnumLabel.MOVE_RIGHT_LEFT.label());
pannelloPulsanti.add(EnumButton.INCREASE_X.button());
pannelloPulsanti.add(EnumButton.DECREASE_X.button());
pannelloPulsanti.add(EnumLabel.X_DIRECTION.label());
pannelloPulsanti.add(EnumLabel.MAX_X_ALLOWED.label());
}//sezioneSpostamentoOrizzontale
public LinesComponent initPanel() {
LinesComponent linesComponent= new LinesComponent();
linesComponent.setBorder(new LineBorder(Color.GRAY));
return linesComponent;
}
private void buildFrame(String titolo) {
this.testFrame = new JFrame(titolo);
this.testFrame.setLayout(new FlowLayout());
this.testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.testFrame.setLocationRelativeTo(null);
this.testFrame.setSize(700,700);
this.testFrame.setBackground(Color.WHITE);
}
}
enum EnumLayout {
FRAME(new FlowLayout()), BUTTON_PANEL(new GridLayout(3, 5));
private LayoutManager value;
private EnumLayout(LayoutManager manager){
this.value=manager;
}
public LayoutManager layout() {
return value;
}
}
enum EnumLabel {
MOVE_RIGHT_LEFT("Sposta in orizzontale"),
MOVE_UP_DOWN("Sposta in verticale"),
ZOOM("Zoom"), EMPTY(""),
MAX_X_ALLOWED("LARGHEZZA: 600"), MAX_Y_ALLOWED("ALTEZZA: 600"),
X_DIRECTION("0"), Y_DIRECTION("0"), ZOOM_DIRECTION("1")
;
private JLabel label;
private EnumLabel(String lab){
this.label=new JLabel(lab);
}
public JLabel label (){
return this.label;
}
}
class MyPoint {
// class with the data: useless for position of panel
}
Scrollpane and its scrollbars entirely rely on the size of the component in the viewport, which, by default, depends of the preferred size of that component.
Check this code which shows you a basic example of how this all works:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TestScrollPane {
public static class CustomComponent extends JPanel {
private static final int RADIUS = 20;
private int x = 0;
private int y = 0;
private double speed = 18;
private double dx;
private double dy;
public CustomComponent() {
dx = speed;
dy = speed;
Timer t = new Timer(20, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x += dx;
y += dy;
if (x + RADIUS > getWidth()) {
x = getWidth() - RADIUS;
dx = -speed;
} else if (x < 0) {
x = 0;
dx = speed;
}
if (y + RADIUS > getHeight()) {
y = getHeight() - RADIUS;
dy = -speed;
} else if (y < 0) {
y = 0;
dy = speed;
}
repaint();
}
});
t.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(x, y, RADIUS, RADIUS);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
}
protected void initUI() {
JFrame window = new JFrame(TestScrollPane.class.getSimpleName());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scroll = new JScrollPane(new CustomComponent(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
window.add(scroll);
window.setSize(600, 500);
window.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestScrollPane().initUI();
}
});
}
}