将转换应用于基于JButton的3个graphics2d图像的Java问题

时间:2022-06-01 20:50:06

I'm still relatively new to Java. Also, this is a school project.

我还是比较新的Java。此外,这是一个学校项目。

Goal: When run, the program is SUPPOSED TO create and display 3 ea. 25x25 images. Then, whenever a button is pushed, various transforms are to be applied to each of the images. My problem is that none of the transforms are being applied.

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

I have 3 classes: a drawing area, a GUI builder, and a main run class. So far the GUI is coming up,the initial images are displayed, and the listeners for buttons are good to go. When the buttons are pushed, the appropriate messages appear but nothing changes with my images.

我有3个类:绘图区域,GUI构建器和主运行类。到目前为止,GUI即将出现,初始图像显示,按钮的听众很好。按下按钮时,会显示相应的消息,但我的图像没有任何变化。

Here's the GUI builder:

这是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.
}
}

And here's the drawing area:

这是绘图区域:

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.
}

And now my main class...

而现在我的主要班级......

import java.text.ParseException;


public class runProject1 {

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

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

}

}

2 个解决方案

#1


1  

Your problems start here:

你的问题从这里开始:

public Graphics2D g2;

There is no reason to maintain a reference to the system Graphics context, let alone make it public. The Graphics is controlled by the paint system and you will be given a instance to paint to when the system needs you to update the component.

没有理由保持对系统Graphics上下文的引用,更不用说将其公开了。图形由绘图系统控制,当系统需要您更新组件时,您将获得一个绘制实例。

So, instead, update your transform as you need and call repaint on the component, apply the transform to the Graphics context passed to the paintComponent method

因此,根据需要更新转换并在组件上调用重绘,将转换应用于传递给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 code resets the transform each time, remember transformations are cumulative

此代码每次都会重置转换,请记住转换是累积的

You may also like to have a look at this example for some more ideas

您可能还想查看此示例以获取更多想法

I might also point out the overuse of static is very dangerous and could cause no end of issues if you're not careful. static is not a means for cross object communication and you should use it sparingly

我也可能会指出过度使用静电是非常危险的,如果你不小心,可能会导致问题没有结束。 static不是交叉对象通信的手段,你应该谨慎使用它

#2


0  

Here try this. It's transforming now. I changed a few things, so go back and see what I changed to see what was wrong in the first place. Also moved the repaint into the doTransform method.

试试吧。它现在正在改变。我改变了一些东西,所以回过头来看看我改变了什么,一开始就看错了。还将重绘移动到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.
}

}

#1


1  

Your problems start here:

你的问题从这里开始:

public Graphics2D g2;

There is no reason to maintain a reference to the system Graphics context, let alone make it public. The Graphics is controlled by the paint system and you will be given a instance to paint to when the system needs you to update the component.

没有理由保持对系统Graphics上下文的引用,更不用说将其公开了。图形由绘图系统控制,当系统需要您更新组件时,您将获得一个绘制实例。

So, instead, update your transform as you need and call repaint on the component, apply the transform to the Graphics context passed to the paintComponent method

因此,根据需要更新转换并在组件上调用重绘,将转换应用于传递给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 code resets the transform each time, remember transformations are cumulative

此代码每次都会重置转换,请记住转换是累积的

You may also like to have a look at this example for some more ideas

您可能还想查看此示例以获取更多想法

I might also point out the overuse of static is very dangerous and could cause no end of issues if you're not careful. static is not a means for cross object communication and you should use it sparingly

我也可能会指出过度使用静电是非常危险的,如果你不小心,可能会导致问题没有结束。 static不是交叉对象通信的手段,你应该谨慎使用它

#2


0  

Here try this. It's transforming now. I changed a few things, so go back and see what I changed to see what was wrong in the first place. Also moved the repaint into the doTransform method.

试试吧。它现在正在改变。我改变了一些东西,所以回过头来看看我改变了什么,一开始就看错了。还将重绘移动到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.
}

}