我用JScrollPane构建了一个程序,这个滚动窗格包含另一个带有null Layout的JPanel,这个面板包含了一些其他JPanel [我将它们命名为子面板](带有一些绘制的东西和JLabel) 那些子面板使用setBounds(int,int,int,int)方法定位在面板中(我不想改变它)
在寻找缩放的好解决方案后,我找到了两个选项 - 缩放paint / paintComponent方法(很糟糕,因为绘制的东西被更改但不是x,y轴的比例,而不是那些子面板的高度和高度 - >我的mouselisteners不起作用(在错误的地方) ) - 使用JScrollPane的视口缩放(根本不起作用(我在谷歌上找到的等等)。)
所以我正在寻找放大和缩小JPanel的好方法
这里有一些代码可以想象我的意思
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class MyAppFrame extends JFrame {
private JScrollPane scroll;
private JPanel nullLayoutPanel;
private JPanel subPanel;
private double zoomFactor;
private double lastScale;
private static Point pressed;
public MyAppFrame(){
setSize(200, 200);
setLocation(50, 50);
zoomFactor = 1.0;
lastScale = 1.0;
nullLayoutPanel = new JPanel(){
//when you try it with the paint method you'll see my problem
//move the rect by dragging it around then
//scroll out or in and try to move the rect
//you'll see that the position of the logical rect doesn't fit with the painted one
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
//g2d.translate(nullLayoutPanel.getWidth()/2, nullLayoutPanel.getHeight()/2);
g2d.scale(zoomFactor, zoomFactor);
//g2d.translate(-nullLayoutPanel.getWidth()/2, -nullLayoutPanel.getHeight()/2);
//super.paint(g2d);
g2d.dispose();
}
@Override
public Dimension getPreferredSize(){
return new Dimension((int)(nullLayoutPanel.getWidth()*zoomFactor), (int)(nullLayoutPanel.getHeight()*zoomFactor));
}
};
nullLayoutPanel.setPreferredSize(new Dimension(400,400));
nullLayoutPanel.setLayout(null);
nullLayoutPanel.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL){
if((.1 * e.getWheelRotation()) > 0 && zoomFactor < 2.0){
zoomFactor += (.1 * e.getWheelRotation());
} else if((.1 * e.getWheelRotation()) < 0 && zoomFactor > 0.1){
zoomFactor += (.1 * e.getWheelRotation());
}
zoomFactor = Math.round(zoomFactor*10.0)/10.0;
zoom(e.getPoint());
}
}
});
scroll = new JScrollPane(nullLayoutPanel);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
getContentPane().add(scroll);
subPanel = new JPanel(){
@Override
public void paint(Graphics g){
g.setColor(Color.BLUE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
}
};
subPanel.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
pressed = e.getPoint();
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
});
subPanel.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent e) {
Point pPoint;
pPoint = subPanel.getLocation();
int x = (int)(pPoint.x - pressed.getX()+e.getX());
int y = (int)(pPoint.y - pressed.getY()+e.getY());
if(x>0&&y>0)
subPanel.setLocation(x,y);
repaint();
}
});
subPanel.setBounds(10, 10, 10, 10);
nullLayoutPanel.add(subPanel);
setVisible(true);
}
public void alignViewPort(Point mousePosition) {
// if the scale didn't change there is nothing we should do
if (zoomFactor != lastScale) {
// compute the factor by that the image zoom has changed
double scaleChange = zoomFactor / lastScale;
// compute the scaled mouse position
Point scaledMousePosition = new Point(
(int)Math.round(mousePosition.x * scaleChange),
(int)Math.round(mousePosition.y * scaleChange)
);
// retrieve the current viewport position
Point viewportPosition = scroll.getViewport().getViewPosition();
// compute the new viewport position
Point newViewportPosition = new Point(
viewportPosition.x + scaledMousePosition.x - mousePosition.x,
viewportPosition.y + scaledMousePosition.y - mousePosition.y
);
// update the viewport position
// IMPORTANT: This call doesn't always update the viewport position. If the call is made twice
// it works correctly. However the screen still "flickers".
scroll.getViewport().setViewPosition(newViewportPosition);
// debug
if (!newViewportPosition.equals(scroll.getViewport().getViewPosition())) {
System.out.println("Error: " + newViewportPosition + " != " + scroll.getViewport().getViewPosition());
}
// remember the last scale
lastScale = zoomFactor;
}
}
public void zoom(Point p){
alignViewPort(p);
nullLayoutPanel.revalidate();
scroll.repaint();
}
/**
* @param args
*/
public static void main(String[] args) {
new MyAppFrame();
}
}
我希望你理解我的问题......
编辑:更改了一些代码(视口事物)