Centrér på bestemt pixel ved zoom
Hej eksperterJeg er ved at implementere en zoom funktion hvor man i et jscrollpane kan zoome ind og ud på et billede. Når man foretager et zoom skal viewporten centreres på den pixel der blev klikket på, dvs. både ved zoom ind og ud.
Jeg har isoleret et eksempel her hvor zoom ind funktionen ser ud til at virke perfekt. Zoom ud funktionen derimod zoomer ud, men den hopper rundt på JPaneler istedet for at centrere omkring den rigtige pixel. Jeg forstår det ikke eftersom de er implementeret helt ens bare omvendt. Desuden synes jeg umiddelbart de koordinater jeg udregner er korrekte, men alligvel scrolles til forkert position når scrollRectToVisible(..) kaldes.
Jeg håber nogle af jer eksperter kan hjælpe mig.
Mange hilsner herfra og tak på forhånd.
Implementering følger: (Kan køres direkte, husk dog at ski sti og navn på billede)
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class ScrollPaneBidule extends JPanel implements MouseListener{
private java.awt.image.BufferedImage editI = null;
private Graphics2D editg; //graphics object for mask image
private JScrollPane theScrollPane = null;
private Rectangle rect = null;
private JComponent component = null;
private boolean firsttime=true;
private double factor=1;
public ScrollPaneBidule(Image I) {
editI=new BufferedImage(I.getWidth(null),I.getHeight(null),BufferedImage.TYPE_INT_RGB);
editg=editI.createGraphics();
editg.drawImage(I, 0, 0, this); // Copy image to the buffered edit Image
setPreferredSize(new Dimension(I.getWidth(null),I.getHeight(null)));
addMouseListener(this);
}
public void registerScrollPanel(JScrollPane p){
theScrollPane=p;
}
protected void paintComponent(Graphics g){
//g.drawImage(editI, 0, 0, this);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(editI, new AffineTransform(factor,0,0,factor,0,0), null);//
}
public void mousePressed(MouseEvent arg0){
int X=arg0.getPoint().x,Y=arg0.getPoint().y;
if(firsttime)component = (JComponent)theScrollPane.getViewport().getView();
firsttime=false;
double newZoom=1.0;
if(arg0.getButton()==MouseEvent.BUTTON1){ factor*=2;newZoom=2.0;}//Zoom in on left click
else if(arg0.getButton()==MouseEvent.BUTTON3){ factor/=2;newZoom=1.0/2.0;}//Zoom out on right click
rect = component.getVisibleRect();
rect.x = (int)((((double)(getPreferredSize().width *newZoom))*(((double)X)/((double)getPreferredSize().width )))-((double)(rect.width/2 )));
rect.y = (int)((((double)(getPreferredSize().height*newZoom))*(((double)Y)/((double)getPreferredSize().height)))-((double)(rect.height/2)));
System.out.println("__________________________________________________________");
System.out.println("PanelPreferredSize: {width: "+editI.getWidth()+", height: "+editI.getWidth()*factor+"} newZoom={"+newZoom+"}, X={"+X+"}, Y={"+Y+"} , rect: "+rect);
System.out.println("Size of new image(editI scaled): width: "+editI.getWidth()+", height: "+editI.getWidth()*factor+", factor: "+factor);
setPreferredSize(new Dimension((int)(((double)editI.getWidth())*factor),(int)(((double)editI.getHeight())*factor)));
revalidate();
repaint();
component.scrollRectToVisible(rect);
rect = component.getVisibleRect();
System.out.println(" rect after scroll:"+rect);
System.out.println("__________________________________________________________");
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JFrame frame = new JFrame(ScrollPaneBidule.class.getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ScrollPaneBidule s = new ScrollPaneBidule(new ImageIcon(java.awt.Toolkit.getDefaultToolkit().getImage("C:\\Users\\bdi\\workspace\\SpectrumAnnotater\\images\\testbillede.jpg")).getImage());
JScrollPane scrollPane = new JScrollPane(s);
s.registerScrollPanel(scrollPane);
scrollPane.setPreferredSize(new Dimension(900,700));
frame.setContentPane(scrollPane);
frame.pack();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}