基于 jpanel 内容的滚动条
Scrollbars based on the content of a jpanel
我有一个 500x500 的 jpanel,用作 canvas(在其上绘制)。滚动条(根据需要)在面板上以 510x510 开始(它永远不会在视觉上达到,但会根据内容超过)并且 500x500 表示为 1:1(比例)
下面是一条线的放大图,可以看出,视图 window 保持不变并且没有弹出滚动条,将滚动条设置为始终会导致禁用条。
JScrollPane scrollPanel = new JScrollPane(JPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
如何让滚动条读取此面板的内容并变得可滚动?我找不到与此相关的任何内容
附加的面板变大了,但是滚动条没有读取这个变化。是否有某种我需要调用但我没有的更新(考虑一下我没有明确地调用更新?但也找不到与此相关的任何内容)
您需要为您的面板实现可滚动界面,该界面放置在 JScrollPane 中并覆盖方法 getPreferredSize()
。这是例子
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;
}
}
我有一个 500x500 的 jpanel,用作 canvas(在其上绘制)。滚动条(根据需要)在面板上以 510x510 开始(它永远不会在视觉上达到,但会根据内容超过)并且 500x500 表示为 1:1(比例)
下面是一条线的放大图,可以看出,视图 window 保持不变并且没有弹出滚动条,将滚动条设置为始终会导致禁用条。
JScrollPane scrollPanel = new JScrollPane(JPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
如何让滚动条读取此面板的内容并变得可滚动?我找不到与此相关的任何内容
附加的面板变大了,但是滚动条没有读取这个变化。是否有某种我需要调用但我没有的更新(考虑一下我没有明确地调用更新?但也找不到与此相关的任何内容)
您需要为您的面板实现可滚动界面,该界面放置在 JScrollPane 中并覆盖方法 getPreferredSize()
。这是例子
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;
}
}