想实现一个放大缩小的功能容器是 类Canvas extend JPanel,里面包括一个Icon对象(extends JButton)。Icon可以由鼠标拖动定位。尽管调用zoomIn()函数时,整个容器和对象是放大了,放大后,点击放大的Icon却不响应鼠标事件。在原来坐标处还有一个未放大的Icon,鼠标点击后就会显示。请各位帮忙解答一下!
源程序如下:
Painter.java:import java.awt.Dimension;
public class Painter {
public static void main(String[] args) {
// TODO Auto-generated method stub
PaintFrame frame = new PaintFrame(); 
frame.setTitle("Paint Test!");
Dimension d = frame.getToolkit().getScreenSize();
frame.setBounds(d.width/4,d.height/4,d.width/2,d.height/2);
frame.show();
}
}
PaintFrame.javaimport javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
public class PaintFrame extends JFrame { /**
 * 
 */
private static final long serialVersionUID = 1L;
public PaintFrame() {
super();
// TODO Auto-generated constructor stub
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
initComponents();
}
private void initComponents(){
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem open = new JMenuItem("Open");
JMenuItem save = new JMenuItem("Save");
JMenuItem exit = new JMenuItem("Exit");
exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
             System.exit(0);
            }
           });
file.add(open);
file.add(save);
file.add(exit);
menuBar.add(file);
this.setJMenuBar(menuBar);
toolBar = new JToolBar();
toolBar.add(new ZoomInAction("++"));
toolBar.add(new ZoomOutAction("--"));
getContentPane().add(toolBar,BorderLayout.NORTH);
canvas = new Canvas();
getContentPane().add(new JScrollPane(canvas,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),BorderLayout.CENTER);
}

public class ZoomInAction extends AbstractAction{
private static final long serialVersionUID = 1L;

public ZoomInAction(){            
        }
        public ZoomInAction(String name) {
            putValue(Action.NAME, name);
        }
        
        public ZoomInAction(String name, javax.swing.Icon icon) {
            this(name);
            putValue(Action.SMALL_ICON, icon);
        }
        /** Invoked when an action occurs.
         */
        public void actionPerformed(ActionEvent e) {
         canvas.zoomIn();
        }
    }
public class ZoomOutAction extends AbstractAction{
private static final long serialVersionUID = 1L;

public ZoomOutAction(){            
        }
        public ZoomOutAction(String name) {
            putValue(Action.NAME, name);
        }
        
        public ZoomOutAction(String name, javax.swing.Icon icon) {
            this(name);
            putValue(Action.SMALL_ICON, icon);
        }
        /** Invoked when an action occurs.
         */
        public void actionPerformed(ActionEvent e) {
         canvas.zoomOut();
        }
    }
private JToolBar toolBar;
private Canvas canvas;
}Canvas.java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Canvas extends JPanel { /**
 * 
 */
private static final long serialVersionUID = 1L;
public Canvas(){
super();
setBackground(new java.awt.Color(230, 240, 255));
setLayout(null);
//setSize(800,600);
Dimension d = new Dimension(800,600);
this.setPreferredSize(d);
this.setMaximumSize(d);
this.setMinimumSize(d);
initComponents();
zoom = 1.0;
}
private void initComponents(){
Icon icon = new Icon("Icon");
add(icon);
icon.setLocation(100,100);
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
((Graphics2D)g).scale(zoom,zoom);
Graphics2D g2 = (Graphics2D)g;
for (int l = 0; l < 10; l++){//网格,用于显示容器是否放大
            for (int m = 0; m < 10; m++){
                int q1 = l*120;  //60*2
                int q2 = m*80;  //40*2
                g2.setColor(Color.gray);
                g2.drawLine(0,q2,1680,q2);
                g2.drawLine(q1,0,q1,1600);
            }
        }
}
public void zoomIn(){
zoom = zoom*2;
repaint();
}
public void zoomOut(){
zoom = zoom/2;
repaint();
}
private double zoom;
}Icon.java
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import javax.swing.JButton;
public class Icon extends JButton implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener{ /**
 * 
 */
private static final long serialVersionUID = 1L;
public Icon(String text) {
super(text);
// TODO Auto-generated constructor stub
setSize(80,60);
        setBackground(new java.awt.Color(200, 240, 255));
        this.setBorder(new javax.swing.border.MatteBorder(new java.awt.Insets(3, 3, 3, 3), new java.awt.Color(102, 204, 255)));
addMouseListener(this);
addMouseMotionListener(this);
}
public void mouseDragged(java.awt.event.MouseEvent e) {       
        
        int locationX=e.getPoint().x+this.getX()-last_x;//-this.getSize().width/2;
        int locationY=e.getPoint().y+this.getY()-last_y;//-this.getSize().height/2;
        setLocation(locationX,locationY);
        checkPostion(); 
        Rectangle d = getBounds();
        getParent().repaint(d.x,d.y,d.width,d.height);
    }
    public void mousePressed(java.awt.event.MouseEvent e) {
     last_x = e.getPoint().x;
     last_y = e.getPoint().y;
    }
private void checkPostion() {
// TODO: Add your code here
int x=getX();
int y=getY();
int width=getParent().getSize().width;
int height=getParent().getSize().height;
if(x+getSize().width>width){
x=width-getSize().width-2;
}
if(x<0){
x=2;
}
if(y+getSize().height>height){
y=height-getSize().height-2;
}
if(y<0){
y=2;
}
setLocation(x,y);
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
AffineTransform at = ((Graphics2D)getParent().getGraphics()).getTransform();
((Graphics2D)g).scale(at.getScaleX(),at.getScaleY());
}
    private int last_x, last_y;
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub

}
}

解决方案 »

  1.   

    这段代码里的放大并不是真正的放大了组件,而是将当前视口区域放大显示,所以会有你的问题。protected void paintComponent(Graphics g){
    super.paintComponent(g);
    ((Graphics2D)g).scale(zoom,zoom);
    Graphics2D g2 = (Graphics2D)g;
    for (int l = 0; l < 10; l++){//网格,用于显示容器是否放大
                for (int m = 0; m < 10; m++){
                    int q1 = l*120;  //60*2
                    int q2 = m*80;  //40*2
                    g2.setColor(Color.gray);
                    g2.drawLine(0,q2,1680,q2);
                    g2.drawLine(q1,0,q1,1600);
                }
            }
    }