對不起,這是一個漫長的一段下面的示例代碼,但這裏的問題:JScrollPane的「跳樓」時滾動條開始使用
我有一個背景下,我積極繪圖(我可能是聰明,繪製一次,然後按比例縮放,但這也顯示了問題)。
您可以使用鼠標滾輪放大和縮小圖像。
這個想法是做一個「谷歌地圖」縮放,它放大鼠標指針下。我注意到,它似乎並沒有真正的行爲,直到圖像大到足以使用兩個滾動條。在此之前,你的形象變得越來越大,但鎖定在原點。
「正確的」行爲應該是移動視圖位置,即使滾動條尚未被超大圖像使用。
我不知道如何解決這個問題(或者如果這是正確的和預期的),而不在圖像後面繪製更大的背景,因此它不僅填充視口。
由於(我認爲)同一個問題,它在一個或另一個滾動條參與之後「跳轉」。
想法?
package com.hostigr.raw.io.client.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
public class TestFrame extends JFrame {
public static void main(String[] arg) {
new TestFrame();
}
public TestFrame() {
initComponents();
setVisible(true);
}
private void initComponents() {
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 600);
setPreferredSize(new Dimension(600, 600));
add(new TopPanel());
}
private class TopPanel extends JPanel {
JScrollPane scrollPane;
public TopPanel() {
setPreferredSize(new Dimension(500,500));
scrollPane = new JScrollPane(new InteriorPanel());
scrollPane.setPreferredSize(new Dimension(500,500));
scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(10,490));
scrollPane.getHorizontalScrollBar().setPreferredSize(new Dimension(490,10));
scrollPane.setWheelScrollingEnabled(false);
scrollPane.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
}
}
private class InteriorPanel extends JPanel {
private double scale = 10.0;
private final double scaleModifier = 0.1;
private final int width = 10;
private Point loc = new Point(0,0);
private final int SIZE = 10;
public InteriorPanel() {
super(true);
setPreferredSize(new Dimension((int)(scale * width * SIZE),
(int)(scale * width * SIZE)));
this.addMouseWheelListener(new MapMouseWheelListener());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2D.scale(scale,scale);
for (int row = 0; row <= SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
if ((col + row) % 2 == 0) {
g2D.setColor(Color.white);
} else {
g2D.setColor(Color.black);
}
g2D.fillRect(col * width, row * width, width, width);
}
}
}
private void incrementScale(int notches) {
double modifier = 0;
double prevScale = scale;
if (notches != 0) {
modifier = 1.0 + -notches/Math.abs(notches) * scaleModifier;
}
scale = scale * Math.pow(modifier, Math.abs(notches));
/*if (scale * width < 1) {
scale = 1.0/width;
} else if (scale * width * 3 > parentHeight || scale * width * 3 > parentWidth) {
if (parentHeight > parentWidth) {
scale = parentWidth/3.0/width;
} else {
scale = parentHeight/3.0/width;
}
} else if (scale * width * SIZE < parentWidth) {
scale = parentWidth/(double)SIZE/width;
} else if (scale * width * SIZE < parentHeight) {
scale = parentHeight/(double)SIZE/width;
}*/
this.repaint();
setPreferredSize(new Dimension((int)(scale * width * SIZE),
(int)(scale * width * SIZE)));
JViewport viewport = ((JViewport)(getParent().getParent().getComponent(0)));
Point orig = viewport.getViewPosition();
viewport.setViewPosition(new Point(
orig.x - (int)Math.round(loc.x*(1 - scale/prevScale)),
orig.y - (int)Math.round(loc.y*(1 - scale/prevScale))));
System.out.println(orig + "\n " + loc + "\n " + (1 - scale/prevScale));
revalidate();
}
private class MapMouseWheelListener implements MouseWheelListener {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
loc = e.getPoint();
incrementScale(e.getWheelRotation());
}
}
}
}
結束,我想我認識的方式來闡述問題:視口正在設置一個可見的矩形/在滾動面板中的組件內。如果組件小於可視矩形,那麼這種範例顯然沒有任何意義。但是,我覺得你應該/仍然/能夠以某種方式改變內部部件相對於可視矩形的位置?或者,我唯一的答案是繪製比視口大的不透明邊框,因此它比滾動窗格保持「更大」? – AndyMac
噢,即使我限制最小尺寸以使其等於視口的大小,仍然會發生不連續性......縮放步驟/滾動條之後的一個小「跳躍」和I我不確定是什麼原因造成的。 – AndyMac
對不起,我看不到任何更新在你身邊,如果包含矩形或點,請勿隨JViewPort移動, – mKorbel