【问题标题】:Java problems with applying transforms to 3 graphics2d images based on JButton基于 JButton 将变换应用于 3 个图形二维图像的 Java 问题
【发布时间】:2017-01-22 23:30:37
【问题描述】:

我对 Java 还是比较陌生。此外,这是一个学校项目。

目标:运行时,程序应该创建并显示 3 ea。 25x25 图像。然后,每当按下按钮时,将对每个图像应用各种变换。我的问题是没有应用任何转换。

我有 3 个类:绘图区、GUI 构建器和主运行类。 到目前为止,GUI 已经出现,初始图像已显示,按钮的侦听器已准备就绪。按下按钮时,会出现相应的消息,但我的图像没有任何变化。

这是 GUI 构建器:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.ParseException;
import javax.swing.border.Border;

//@SuppressWarnings("serial")
public class Project1 extends JFrame implements ActionListener { 
public static JButton nextTransformBtn;
public static JButton closeBtn;
//public static JLabel label;
public static JFrame window;
public static JPanel topPanel;
public static DrawArea panel;
public static Border blackLine;
private int frameNumber;  // A counter that increases by one in each frame.
private long elapsedTimeMillis;  // The time, in milliseconds, since the animation started.
private float pixelSize;  // This is the measure of a pixel in the coordinate system
                          // set up by calling the applyWindowToViewportTransformation method.  It can be used
                          // for setting line widths, for example.
public static final int CANVAS_WIDTH = 800;
public static final int CANVAS_HEIGHT = 600;
public static int count ;
int num ;
//public static final String TITLE = " Project 1";


/** constructor
 * @param args 
 */
public Project1() throws ParseException { 
    /**
     * Set properties of Project1 JFrame
     */
    super("Project 1");
    setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
    setLocationRelativeTo(null);
    setResizable(false);
    setBackground( Color.lightGray );
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    /**
     * Creates black line for border
     */        
    blackLine = BorderFactory.createLineBorder(Color.BLACK);

    /**
     * Create a JPanel to display Graphics
     */  
    panel = new DrawArea();
    panel.setBackground(Color.white);
    panel.setBorder(blackLine);

    /**
     * Create components for topPanel
     */     
    //label = new JLabel("    Project 1 ");
    nextTransformBtn = new JButton("Next transform");
    closeBtn= new JButton("Exit Program");

    /**
     * Create a topPanel for text box and
     * set its properties
     */     
    topPanel = new JPanel();
    FlowLayout layout = new FlowLayout();
    topPanel.setLayout(layout);
    topPanel.setBorder(blackLine);
    //topPanel.add(label);
    topPanel.add(nextTransformBtn);
    topPanel.add(closeBtn);

    /**
     * Add topPanel and panel to JFrame
     */ 
    add(topPanel, BorderLayout.NORTH);
    getContentPane().add(panel);

    /**
     * Create ActionListeners for buttons
     */         
    closeBtn.addActionListener(e-> System.exit(0));
    nextTransformBtn.addActionListener(e-> {
        System.out.print (count + " - ");
        panel.doTransform(count);
        panel.redrawComponent();
        count++;
        if(count == 6) count = 0;
    });

}// end constructor method

@Override
public void actionPerformed(ActionEvent e) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

这里是绘图区:

public class DrawArea extends JPanel{
BufferedImage boxImage;      
AffineTransform at = new AffineTransform();
public Graphics2D g2;
public DrawArea(){
    setBackground(Color.white);
    setSize(800,600);
}

public void doTransform(int count){
    switch(count){
        case 0:
            at.translate(-5, 0);
            System.out.println("Translate images -5 in X direction.");
            break;
        case 1:
            at.translate(0,7);
            System.out.println("Translate images 7 in Y direction.");
            break;
        case 2:
            System.out.println("Rotates images 45 degrees counter clockwise.");
            at.rotate(Math.toRadians(45));
            break;
        case 3:
            at.rotate(Math.toRadians(-90));
            System.out.println("Rotates images 90 degrees clockwise.");
            break;
        case 4:
            at.scale(2, 0);
            System.out.println("Scales images 2 times for X component.");
            break;
        case 5:
            at.scale(0, 0.5);
            System.out.println("Scales images 0.5 times for Y component.");
            break;
    }
    g2.setTransform(at);
}
public void redrawComponent(){
    repaint();
}
@Override
public void paintComponent(Graphics g) {
    g2 = (Graphics2D)g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setPaint(Color.WHITE);
    g2.fillRect(0,0,getWidth(),getHeight()); // From the old graphics API!
    setPixelSize(g2, -100, 100, -100, 100, true);
    /* 
     * Create images and store in 2d array
     */
    int blk = Color.BLACK.getRGB();
    int boxData[][]= newint[25][25];
    for(int x = 0 ; x<25 ; x++){
        for(int y = 0 ; y<25 ; y++){
            if( x==0 || y==0 || x == 24 || y == 24){
                boxData[x][y] = Color.BLACK.getRGB();
            } else if (x>y){
                boxData[x][y] = Color.red.getRGB();
            } else if (x<y){
                boxData[x][y] = Color.blue.getRGB();
            }
        }
    }
    boxImage = new BufferedImage(25, 25 ,BufferedImage.TYPE_INT_RGB);                
    //box
    for (int x = 0 ; x<25 ; x++){
        for(int y = 0 ; y<25 ; y++){
            boxImage.setRGB(x,y,boxData[x][y]);
        }
    }
    g2.drawImage(boxImage, -13, -40, this);        

    AffineTransform saveXform = g2.getTransform();
    AffineTransform toCenterAt = new AffineTransform();
    toCenterAt.concatenate(at);
    g2.transform(toCenterAt);
    g2.setTransform(saveXform);
}
private void setPixelSize(Graphics2D g2,
        double left, double right, double bottom, double top, 
        boolean preserveAspect) {
    int width = getWidth();   // The width of this drawing area, in pixels.
    int height = getHeight(); // The height of this drawing area, in pixels.
    if (preserveAspect) {
        // Adjust the limits to match the aspect ratio of the drawing area.
        double displayAspect = Math.abs((double)height / width);
        double requestedAspect = Math.abs(( bottom-top ) / ( right-left ));
        if (displayAspect > requestedAspect) {
            // Expand the viewport vertically.
            double excess = (bottom-top) * (displayAspect/requestedAspect - 1);
            bottom += excess/2;
            top -= excess/2;
        }
        else if (displayAspect < requestedAspect) {
            // Expand the viewport vertically.
            double excess = (right-left) * (requestedAspect/displayAspect - 1);
            right += excess/2;
            left -= excess/2;
        }
    }
    g2.scale( width / (right-left), height / (bottom-top) );
    g2.translate( -left, -top );
    double pixelWidth = Math.abs(( right - left ) / width);
    double pixelHeight = Math.abs(( bottom - top ) / height);
    pixelSize = (float)Math.max(pixelWidth,pixelHeight);
}// end setPixelSize method

public void actionPerformed(ActionEvent e) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

现在我的主要课程...

import java.text.ParseException;


public class runProject1 {

public static void main(String[] args) throws ParseException{

    final Project1 panel = new Project1();
    panel.setVisible(true);

}

}

【问题讨论】:

  • 欢迎来到 Stack Overflow!看起来你正在寻求家庭作业帮助。虽然我们对此本身没有任何问题,但请注意这些dos and don'ts,并相应地编辑您的问题。
  • 欢迎您!你的主要方法在哪里?它看起来怎么样?
  • 专业提示:一旦您将块格式应用于此处发布的代码,您就不需要反引号 - 它们仅用于小段内联代码。
  • 编辑您的原始帖子并添加第 3 类...包含您的主要方法的类。
  • 不要保存对Graphics 的引用,这是一个非常糟糕的主意,问题无穷无尽。相反,根据需要更新您的转换,调用repaint 并更新提供的Graphics 上下文的转换。确保您也先致电super.paintComponent。最好还是先使用Graphics 上下文中的createdispose,因为它是共享资源,如果您更改转换并且不撤消它会发生奇怪的事情

标签: java swing affinetransform


【解决方案1】:

你的问题从这里开始:

public Graphics2D g2;

没有理由维护对系统Graphics 上下文的引用,更不用说使其成为publicGraphics 由绘制系统控制,当系统需要您更新组件时,您将获得一个实例来绘制。

因此,请根据需要更新您的转换并在组件上调用repaint,将转换应用于传递给paintComponent 方法的Graphics 上下文

public class DrawArea extends JPanel {

    BufferedImage boxImage;
    AffineTransform at = new AffineTransform();

    public DrawArea() {
        setBackground(Color.white);
        setSize(800, 600);
    }

    public void doTransform(int count) {
        at = new AffineTransform();
        switch (count) {
            case 0:
                at.translate(-5, 0);
                System.out.println("Translate images -5 in X direction.");
                break;
            case 1:
                at.translate(0, 7);
                System.out.println("Translate images 7 in Y direction.");
                break;
            case 2:
                System.out.println("Rotates images 45 degrees counter clockwise.");
                at.rotate(Math.toRadians(45));
                break;
            case 3:
                at.rotate(Math.toRadians(-90));
                System.out.println("Rotates images 90 degrees clockwise.");
                break;
            case 4:
                at.scale(2, 0);
                System.out.println("Scales images 2 times for X component.");
                break;
            case 5:
                at.scale(0, 0.5);
                System.out.println("Scales images 0.5 times for Y component.");
                break;
        }
        repaint();
    }

    public void redrawComponent() {
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(800, 600);
    }

    @Override
    protected void paintComponent(Graphics g) {
        // Let the API fill the background       
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();

        AffineTransform toCenterAt = new AffineTransform();
        // This centers the transform in the available space
        toCenterAt.translate(getWidth() / 2, getHeight() / 2);
        toCenterAt.concatenate(at);
        g2.transform(toCenterAt);

        /*
        Create images and store in 2d array
         */
        int blk = Color.BLACK.getRGB();
        int boxData[][] = new int[25][25];
        for (int x = 0; x < 25; x++) {
            for (int y = 0; y < 25; y++) {
                if (x == 0 || y == 0 || x == 24 || y == 24) {
                    boxData[x][y] = Color.BLACK.getRGB();
                } else if (x > y) {
                    boxData[x][y] = Color.red.getRGB();
                } else if (x < y) {
                    boxData[x][y] = Color.blue.getRGB();
                }
            }
        }
        boxImage = new BufferedImage(25, 25, BufferedImage.TYPE_INT_RGB);
        //box
        for (int x = 0; x < 25; x++) {
            for (int y = 0; y < 25; y++) {
                boxImage.setRGB(x, y, boxData[x][y]);
            }
        }
        g2.drawImage(boxImage, -13, -40, this);
        g2.dispose();
    }
}

这段代码每次都会重置变换,记住变换是累积的

您可能还想看看this example 以获得更多想法

我还可能指出过度使用static 是非常危险的,如果您不小心,可能会导致无穷无尽的问题。 static 不是跨对象通信的手段,您应该谨慎使用它

【讨论】:

    【解决方案2】:

    来试试这个。现在正在转变。我改变了一些东西,所以回去看看我改变了什么,看看有什么问题。还将重绘移到 doTransform 方法中。

    public class DrawArea extends JPanel{
        float pixelSize;
        BufferedImage boxImage;      
        AffineTransform at = new AffineTransform();
        public DrawArea(){
            setBackground(Color.white);
            setSize(800,600);
        }
    
    public void doTransform(int count){
        switch(count){
        case 0:
            at.translate(-5, 0);
            System.out.println("Translate images -5 in X direction.");
            break;
        case 1:
            at.translate(0,7);
            System.out.println("Translate images 7 in Y direction.");
            break;
        case 2:
            System.out.println("Rotates images 45 degrees counter clockwise.");
            at.rotate(Math.toRadians(45));
            break;
        case 3:
            at.rotate(Math.toRadians(-90));
            System.out.println("Rotates images 90 degrees clockwise.");
            break;
        case 4:
            at.scale(2, 0);
            System.out.println("Scales images 2 times for X component.");
            break;
        case 5:
            at.scale(0, 0.5);
            System.out.println("Scales images 0.5 times for Y component.");
            break;
        }
        repaint();
    
    }
    public void redrawComponent(){
        repaint();
    }
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.WHITE);
        g2.fillRect(0,0,getWidth(),getHeight()); // From the old graphics API!
        setPixelSize(g2, -100, 100, -100, 100, true);
        /* 
         * Create images and store in 2d array
         */
        int blk = Color.BLACK.getRGB();
        int boxData[][]= new int[25][25];
        for(int x = 0 ; x<25 ; x++){
            for(int y = 0 ; y<25 ; y++){
                if( x==0 || y==0 || x == 24 || y == 24){
                    boxData[x][y] = Color.BLACK.getRGB();
                } else if (x>y){
                    boxData[x][y] = Color.red.getRGB();
                } else if (x<y){
                    boxData[x][y] = Color.blue.getRGB();
                }
            }
        }
        boxImage = new BufferedImage(25, 25 ,BufferedImage.TYPE_INT_RGB);                
        //box
        for (int x = 0 ; x<25 ; x++){
            for(int y = 0 ; y<25 ; y++){
                boxImage.setRGB(x,y,boxData[x][y]);
            }
        }
    
    
        AffineTransform saveXform = g2.getTransform();
        AffineTransform toCenterAt = new AffineTransform();
        toCenterAt.concatenate(at);
        g2.transform(toCenterAt);
        g2.setTransform(saveXform);
    
        g2.setTransform(at);
        g2.drawImage(boxImage, 100, 100, this);
    
    }
    private void setPixelSize(Graphics2D g2,
            double left, double right, double bottom, double top, 
            boolean preserveAspect) {
        int width = getWidth();   // The width of this drawing area, in pixels.
        int height = getHeight(); // The height of this drawing area, in pixels.
        if (preserveAspect) {
            // Adjust the limits to match the aspect ratio of the drawing area.
            double displayAspect = Math.abs((double)height / width);
            double requestedAspect = Math.abs(( bottom-top ) / ( right-left ));
            if (displayAspect > requestedAspect) {
                // Expand the viewport vertically.
                double excess = (bottom-top) * (displayAspect/requestedAspect - 1);
                bottom += excess/2;
                top -= excess/2;
            }
            else if (displayAspect < requestedAspect) {
                // Expand the viewport vertically.
                double excess = (right-left) * (requestedAspect/displayAspect - 1);
                right += excess/2;
                left -= excess/2;
            }
        }
        g2.scale( width / (right-left), height / (bottom-top) );
        g2.translate( -left, -top );
        double pixelWidth = Math.abs(( right - left ) / width);
        double pixelHeight = Math.abs(( bottom - top ) / height);
        pixelSize = (float)Math.max(pixelWidth,pixelHeight);
    }// end setPixelSize method
    
    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    

    }

    【讨论】:

      猜你喜欢
      • 2020-03-06
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2017-08-05
      相关资源
      最近更新 更多