I have a jpanel that is 500x500 and acts as a canvas (draw all over it). Scrollbars kick in (as needed) at 510x510 on the panel (which it will never reach visually, but will surpass based on content) and 500x500 is represented as 1:1 (scale)
Below is a representation of a line zoomed in, as can be seen, the view window stays same and no scrollbars popup, setting scrollbars to always results in disabled bars.
JScrollPane scrollPanel = new JScrollPane(JPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
How would I go about having the scrollbars read the contents of this panel and become scrollable? I cannot find anything relevant for this
The attached panel gets bigger, but the scrollbar doesnt read this change. Is there some sort of update i need to call which i dont have (Thinking on it I dont explicitly have anything calling an update? but could not find anything relevant on this either)
What you need is to implement scrollable interface for your panel, that is placed in the JScrollPane and override the method getPreferredSize()
. Here is the example
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class ZoomPanel extends JPanel implements Scrollable {
private static final int DEFAULT_SIZE = 500;
private float zoom = 1f;
@Override
public Dimension getPreferredSize() {
int size = Math.round(zoom * DEFAULT_SIZE);
return new Dimension(size, size);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int size = Math.round(zoom * DEFAULT_SIZE);
g.drawOval(0, 0, size, size);
}
private static class ZoomRenderer extends BasicComboBoxRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Object val = value;
if (value instanceof Number) {
val = Math.round(((Number) value).doubleValue() * 100) + "%";
}
return super.getListCellRendererComponent(list, val, index, isSelected, cellHasFocus);
}
}
public static void main(String[] args) {
JFrame frm = new JFrame("Zoom panel");
ZoomPanel z = new ZoomPanel();
JScrollPane scroller = new JScrollPane(z);
Float[] zooms = {.5f, .75f, 1f, 1.5f, 2f, 4f};
JComboBox<Float> combo = new JComboBox<>(zooms);
combo.setSelectedIndex(2);
combo.setRenderer(new ZoomRenderer());
combo.addActionListener(e -> {
Float v = (Float) combo.getSelectedItem();
if (v != null) {
z.zoom = v;
scroller.revalidate();
scroller.repaint();
}
});
JPanel comboPanel = new JPanel();
comboPanel.add(combo);
frm.add(comboPanel, BorderLayout.NORTH);
frm.add(scroller);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 5;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 20;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}