java 如何实现Graphics2D画的图形进行缩放?

时间:2021-08-15 21:41:51
在java的面板(Jpanel)中用Graphics2D画的图形,如矩形,直线等,该如何实现放大 或 缩小功能呢?

9 个解决方案

#1


csdn里高手哪里去了,难倒没人会吗?
小弟急等............

#2


放大缩小实际是重新画的吧.

#3


 没有尝试过缩放 但个人认为可以通过改变坐标和长度等属性实现 这就是你编码能力的问题了 貌似java没有现成的方法实现缩放

#4


java.awt.Graphics2D
java.awt.geom.AffineTransform
提供的scale变换。

#5


AffineTransform 仿射变换。
可以用于平移,旋转,缩放等功能。
多看下文档吧,虽然文档上是以矩阵为例说的。但是理解了原理是一样的。
需要注意,确定变换时候的的中心点,就是逻辑上的坐标原点。

#6


我发过一个写好的类 在csdn的下载中搜索下吧

#7


缩放原理我大概能明白了。
现在我们的需求有变化,要求是这样的:
假如我的Panel上画了5个小菱形,现在有两个按钮对进行放大和缩小,要求如下:
(1)按固定比例值进行缩放。
(2)缩放必须横向缩放,纵向不动,缩放过程中菱形的大小不改变,改变的只是坐标位置(其实也就是横向坐标)。
(3)缩放必须以panle的中心进行两边缩放。

我是如下实现的,在一个NewSubKFEditorPanel上进行画图操作,在NewJFrame上拖动了JScrollPane,然后把NewSubKFEditorPanel放到JScrollPane上,通过比例值来改变NewSubKFEditorPanel上面的菱形坐标,同时
根据这个比例值变更NewSubKFEditorPanel的大小,以使JScrollPane滚动条出来。
但是存在两个问题:
(1)根据比例值放大并改变NewSubKFEditorPanel大小时,会导致最后找不到菱形。
(2)没有以中心点进行缩放。

一会把代码提交,请高手帮忙,再次多谢了。

#8


由于不能上传附件我大概把代码贴下来把
(1)NewJFrame.java(控件两个按钮、一个JScrollPane、和NewSubKFEditorPanel)大概如下:
public class NewJFrame extends javax.swing.JFrame {
   private double scale[] = {1.0, 1.4, 1.7, 2.0, 2.2, 2.5, 2.7, 2.8, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
   int i = 0;
       private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        if ((i > -1) && (i < scale.length)) {
            System.out.println("i = " + i);
            newSubKFEditorPanel1.increaseZoomScale(scale[i++]);
            
        }
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)     {                                         
        if ((i > 0) && (i <= scale.length)) {
            System.out.println("i = " + --i);
            newSubKFEditorPanel1.decreaseZoomScale(scale[i]);
        }
    }
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JScrollPane jScrollPane1;
    private com.sony.threedee.gui.NewSubKFEditorPanel newSubKFEditorPanel1;
    // End of variables declaration

}

(2)NewSubKFEditorPanel.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewSubKFEditorPanel.java
 *
 * Created on 2010年7月27日, 上午10:21:44
 */

package com.sony.threedee.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;

/**
 *
 * @author lichuanfeng
 */
public class NewSubKFEditorPanel extends javax.swing.JPanel {
    //for test code
    private static final float dash1[] = {10.0f};
    private NewKFPoint[] kfPoints = new NewKFPoint[5];
    private boolean bzoomScale = true;
//    private double sx = 1.0;
//    private double sy = 1.0;
    private int panel_Width = 0;
//    private int panel_Height = 0;
    private int offset = 3;

    private int fact_panelWidth = 0;
//    private int fact_panelHeight = 0;
    private AffineTransform at = new AffineTransform();         //AffineTransform 

    private Color color = new Color(255, 255, 255);
    private static final float panelWidth = 499.0f; 
    private static final float panelHeight = 100.0f;
    private static final float halfPanelWidth = 249.5f;
    private static final float halfPanelHeight = 50.0f;
//    private static float centerX = 250.0f;
//    private static float centerY = 50.0f;
    private Line2D centerLine = new Line2D.Float(0.0f, halfPanelHeight, panelWidth, halfPanelHeight);
    public NewSubKFEditorPanel() {
        initComponents();
        Dimension dimension = this.getPreferredSize();
        fact_panelWidth = dimension.width;
//        fact_panelHeight = dimension.height;


        int x = 10;
        for (int i = 0; i < 5; i++) {
            kfPoints[i] = new NewKFPoint(x, 10);
            x += 10;
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setAutoscrolls(true);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 508, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 143, Short.MAX_VALUE)
        );
    }// </editor-fold>                        


    // Variables declaration - do not modify                     
    // End of variables declaration                   

    public void setBackGroundColor(Color col) {
        color = col;
    }

    public void setZoomScale() {
        bzoomScale = false;
        repaint();
    }

    public void setScale(boolean b, double scale) {
        for (int i = 0; i < 5; i++) {
            kfPoints[i].setScale(b, scale);
        }
    }

    public void increaseZoomScale(double scale) {
        if (at != null) {
//            sx = scale;
//            sy = scale;
            setScale(true, scale);
        }

        panel_Width = (int)(fact_panelWidth*scale);
        setPreferredSize(new Dimension(panel_Width, this.getHeight()));

        updateUI();
    }

    public void decreaseZoomScale(double scale) {

        if (at != null) {
//            sx = scale;
//            sy = scale;
            setScale(false, scale);
        }

        panel_Width = (int)(panel_Width/scale);
        setPreferredSize(new Dimension(panel_Width, this.getHeight()));
        updateUI();
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
//        panel_Width = this.getWidth();
//        panel_Height = this.getHeight();
//        at = g2.getTransform();
//        at.scale(sx, sy);
//        g2.setTransform(at);

        g2.setBackground(color);
        g2.clearRect(0, 0, getWidth(), getHeight());
        g2.setPaint(Color.black);
        g2.draw(centerLine);


        //for test code
//        g2.draw(new Rectangle2D.Double(2, 2, panel_Width-20, panel_Height-20));

        GeneralPath polyline = new GeneralPath();

        for (int j = 0; j < 5; j++) {
            polyline.moveTo (kfPoints[j].getX(), kfPoints[j].getY()-offset);
            polyline.lineTo(kfPoints[j].getX()-offset, kfPoints[j].getY());
            polyline.lineTo(kfPoints[j].getX(), kfPoints[j].getY()+offset);
            polyline.lineTo(kfPoints[j].getX()+offset, kfPoints[j].getY());
            polyline.lineTo(kfPoints[j].getX(), kfPoints[j].getY()-offset);

        }
        polyline.closePath();
        g2.setPaint(Color.red);
        g2.fill(polyline);
        g2.draw(polyline);
        g2.dispose();
    }
}

#9


(3)NewKFPoint.java这是我自定义的一个结构类
public class NewKFPoint {
    private float x;
    private float y;
    private boolean isRemove;

    public NewKFPoint() {
        x = 0.0f;
        y = 0.0f;
        isRemove = false;
    }
    
    public NewKFPoint(float x_, float y_) {
        this.x = x_;
        this.y = y_;
        isRemove = false;
    }

    public void setX(float x_) {
        this.x = x_;
    }

    public void setY(float y_) {
        this.y = y_;
    }

    public float getX() {
        return this.x;
    }

    public float getY() {
        return this.y;
    }

    public void setScale(boolean increase, double scale) {
        if (increase) {
            this.x *= (float)scale;
//            this.y *= (float)scale;
        } else {
            this.x /= (float)scale;
//            this.y /= (float)scale;
        }
    }
}

#1


csdn里高手哪里去了,难倒没人会吗?
小弟急等............

#2


放大缩小实际是重新画的吧.

#3


 没有尝试过缩放 但个人认为可以通过改变坐标和长度等属性实现 这就是你编码能力的问题了 貌似java没有现成的方法实现缩放

#4


java.awt.Graphics2D
java.awt.geom.AffineTransform
提供的scale变换。

#5


AffineTransform 仿射变换。
可以用于平移,旋转,缩放等功能。
多看下文档吧,虽然文档上是以矩阵为例说的。但是理解了原理是一样的。
需要注意,确定变换时候的的中心点,就是逻辑上的坐标原点。

#6


我发过一个写好的类 在csdn的下载中搜索下吧

#7


缩放原理我大概能明白了。
现在我们的需求有变化,要求是这样的:
假如我的Panel上画了5个小菱形,现在有两个按钮对进行放大和缩小,要求如下:
(1)按固定比例值进行缩放。
(2)缩放必须横向缩放,纵向不动,缩放过程中菱形的大小不改变,改变的只是坐标位置(其实也就是横向坐标)。
(3)缩放必须以panle的中心进行两边缩放。

我是如下实现的,在一个NewSubKFEditorPanel上进行画图操作,在NewJFrame上拖动了JScrollPane,然后把NewSubKFEditorPanel放到JScrollPane上,通过比例值来改变NewSubKFEditorPanel上面的菱形坐标,同时
根据这个比例值变更NewSubKFEditorPanel的大小,以使JScrollPane滚动条出来。
但是存在两个问题:
(1)根据比例值放大并改变NewSubKFEditorPanel大小时,会导致最后找不到菱形。
(2)没有以中心点进行缩放。

一会把代码提交,请高手帮忙,再次多谢了。

#8


由于不能上传附件我大概把代码贴下来把
(1)NewJFrame.java(控件两个按钮、一个JScrollPane、和NewSubKFEditorPanel)大概如下:
public class NewJFrame extends javax.swing.JFrame {
   private double scale[] = {1.0, 1.4, 1.7, 2.0, 2.2, 2.5, 2.7, 2.8, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
   int i = 0;
       private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        if ((i > -1) && (i < scale.length)) {
            System.out.println("i = " + i);
            newSubKFEditorPanel1.increaseZoomScale(scale[i++]);
            
        }
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)     {                                         
        if ((i > 0) && (i <= scale.length)) {
            System.out.println("i = " + --i);
            newSubKFEditorPanel1.decreaseZoomScale(scale[i]);
        }
    }
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JScrollPane jScrollPane1;
    private com.sony.threedee.gui.NewSubKFEditorPanel newSubKFEditorPanel1;
    // End of variables declaration

}

(2)NewSubKFEditorPanel.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewSubKFEditorPanel.java
 *
 * Created on 2010年7月27日, 上午10:21:44
 */

package com.sony.threedee.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;

/**
 *
 * @author lichuanfeng
 */
public class NewSubKFEditorPanel extends javax.swing.JPanel {
    //for test code
    private static final float dash1[] = {10.0f};
    private NewKFPoint[] kfPoints = new NewKFPoint[5];
    private boolean bzoomScale = true;
//    private double sx = 1.0;
//    private double sy = 1.0;
    private int panel_Width = 0;
//    private int panel_Height = 0;
    private int offset = 3;

    private int fact_panelWidth = 0;
//    private int fact_panelHeight = 0;
    private AffineTransform at = new AffineTransform();         //AffineTransform 

    private Color color = new Color(255, 255, 255);
    private static final float panelWidth = 499.0f; 
    private static final float panelHeight = 100.0f;
    private static final float halfPanelWidth = 249.5f;
    private static final float halfPanelHeight = 50.0f;
//    private static float centerX = 250.0f;
//    private static float centerY = 50.0f;
    private Line2D centerLine = new Line2D.Float(0.0f, halfPanelHeight, panelWidth, halfPanelHeight);
    public NewSubKFEditorPanel() {
        initComponents();
        Dimension dimension = this.getPreferredSize();
        fact_panelWidth = dimension.width;
//        fact_panelHeight = dimension.height;


        int x = 10;
        for (int i = 0; i < 5; i++) {
            kfPoints[i] = new NewKFPoint(x, 10);
            x += 10;
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setAutoscrolls(true);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 508, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 143, Short.MAX_VALUE)
        );
    }// </editor-fold>                        


    // Variables declaration - do not modify                     
    // End of variables declaration                   

    public void setBackGroundColor(Color col) {
        color = col;
    }

    public void setZoomScale() {
        bzoomScale = false;
        repaint();
    }

    public void setScale(boolean b, double scale) {
        for (int i = 0; i < 5; i++) {
            kfPoints[i].setScale(b, scale);
        }
    }

    public void increaseZoomScale(double scale) {
        if (at != null) {
//            sx = scale;
//            sy = scale;
            setScale(true, scale);
        }

        panel_Width = (int)(fact_panelWidth*scale);
        setPreferredSize(new Dimension(panel_Width, this.getHeight()));

        updateUI();
    }

    public void decreaseZoomScale(double scale) {

        if (at != null) {
//            sx = scale;
//            sy = scale;
            setScale(false, scale);
        }

        panel_Width = (int)(panel_Width/scale);
        setPreferredSize(new Dimension(panel_Width, this.getHeight()));
        updateUI();
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
//        panel_Width = this.getWidth();
//        panel_Height = this.getHeight();
//        at = g2.getTransform();
//        at.scale(sx, sy);
//        g2.setTransform(at);

        g2.setBackground(color);
        g2.clearRect(0, 0, getWidth(), getHeight());
        g2.setPaint(Color.black);
        g2.draw(centerLine);


        //for test code
//        g2.draw(new Rectangle2D.Double(2, 2, panel_Width-20, panel_Height-20));

        GeneralPath polyline = new GeneralPath();

        for (int j = 0; j < 5; j++) {
            polyline.moveTo (kfPoints[j].getX(), kfPoints[j].getY()-offset);
            polyline.lineTo(kfPoints[j].getX()-offset, kfPoints[j].getY());
            polyline.lineTo(kfPoints[j].getX(), kfPoints[j].getY()+offset);
            polyline.lineTo(kfPoints[j].getX()+offset, kfPoints[j].getY());
            polyline.lineTo(kfPoints[j].getX(), kfPoints[j].getY()-offset);

        }
        polyline.closePath();
        g2.setPaint(Color.red);
        g2.fill(polyline);
        g2.draw(polyline);
        g2.dispose();
    }
}

#9


(3)NewKFPoint.java这是我自定义的一个结构类
public class NewKFPoint {
    private float x;
    private float y;
    private boolean isRemove;

    public NewKFPoint() {
        x = 0.0f;
        y = 0.0f;
        isRemove = false;
    }
    
    public NewKFPoint(float x_, float y_) {
        this.x = x_;
        this.y = y_;
        isRemove = false;
    }

    public void setX(float x_) {
        this.x = x_;
    }

    public void setY(float y_) {
        this.y = y_;
    }

    public float getX() {
        return this.x;
    }

    public float getY() {
        return this.y;
    }

    public void setScale(boolean increase, double scale) {
        if (increase) {
            this.x *= (float)scale;
//            this.y *= (float)scale;
        } else {
            this.x /= (float)scale;
//            this.y /= (float)scale;
        }
    }
}