简体   繁体   English

JFrame在重绘时不刷新

[英]JFrame not refreshing on repaint

I have written a small code for simple resizing of any image on my system in java using SWING. 我编写了一个小代码,用于使用SWING在Java中简单调整系统中任何图像的大小。

http://ideone.com/9vii2E http://ideone.com/9vii2E

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

class T extends JPanel implements ActionListener {
    /**
     * 
     */
    private static final long serialVersionUID = -2900955352094956729L;
    int x = 0;
    int flag = 0;
    BufferedImage b;
    Image z;
    JButton j, a, cl;
    JTextField ht, wdth;

    T() {
        j = new JButton("Hi");
        a = new JButton("Resizze");
        a.addActionListener(this);
        add(a);
        j.addActionListener(this);
        add(j);
        setBackground(Color.WHITE);

    }

    class tobi implements ActionListener {// for close button of second window
        public void actionPerformed(ActionEvent asd) {
            // if(x==1)
            {
                int gadda = 100, w = 100;
                gadda = Integer.parseInt(ht.getText());
                w = Integer.parseInt(wdth.getText());
                z = z.getScaledInstance(gadda, w, Image.SCALE_SMOOTH);
                setBackground(Color.BLACK);
                j.repaint();
                JButton ttr = (JButton) asd.getSource();
                Window qwe = SwingUtilities.windowForComponent(ttr);
                qwe.setVisible(false);
            }
        }

    }

    public void meth()// method to create second window
    {
        JFrame win = new JFrame();
        win.setTitle("resizze!!");
        win.setLayout(new FlowLayout());
        JLabel height = new JLabel("Height:");
        ht = new JTextField(20);

        JLabel width = new JLabel("Width:");
        wdth = new JTextField(20);
        JButton cl = new JButton("close");

        cl.addActionListener(new tobi());
        win.add(height);
        win.add(ht);
        win.add(width);
        win.add(wdth);
        win.add(cl);
        win.pack();
        win.setVisible(true);
    }

    public void paintComponent(Graphics g) {

        Graphics2D gt = (Graphics2D) g;
        super.paintComponent(g);
        if (x == 1)
            g.drawImage(z, 0, 0, null);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == j) {
            JFileChooser q = new JFileChooser();
            // q.setFileFilter(new
            // FileNameExtensionFilter("Image Files",ImageIO.getReaderFileSuffixes()));
            q.addChoosableFileFilter(new FileNameExtensionFilter("Image Files",
                    "jpg", "jpeg", "png"));
            int option = q.showOpenDialog(null);
            if (option == JFileChooser.APPROVE_OPTION) {
                File f = q.getSelectedFile();
                try {
                    b = ImageIO.read(f);
                    z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
                } catch (IOException ae) {
                }
            }
            x = 1;
            repaint();
        }

        else if (e.getSource() == a) {
            meth();
        }

    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable(){
    public void run(){
    JFrame j = new JFrame();
        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        j.setSize(500, 500);
        j.add(new T());
        j.setVisible(true);
    j.revalidate();
    j.repaint();

}
});
    }
}

I am asking user to upload the image file and then taking parameters height and width for resizing. 我要求用户上传图像文件,然后使用参数height和width进行大小调整。 After clicking on close button in second window,nothing happens(except for first few times),while the image on first window should be repainted. 单击第二个窗口中的关闭按钮后,没有任何反应(除了前几次),而第一个窗口中的图像应重新绘制。 (Sorry for bad variable names and formatting) (对不起,错误的变量名和格式)

You have a whole bunch of issues, variable naming only been one of them... 您遇到了一堆问题,变量命名只是其中之一...

g.drawImage(z, 0, 0, null); should be g.drawImage(z, 0, 0, this); 应该是g.drawImage(z, 0, 0, this); , this ensures that if the image is still be processed for some reason, the component can respond to any of it's changes and update schedule new repaints of it's own accord ,这可以确保如果由于某些原因仍在处理图像,则组件可以响应其任何更改并自行计划更新时间表

Don't ignore exceptions 不要忽略异常

try {
    b = ImageIO.read(f);
    z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
} catch (IOException ae) {

}

should be (at the very least) 应该(至少)

try {
    b = ImageIO.read(f);
    z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
} catch (IOException ae) {
    ae.printStackTrace();
}

This will help you solve probable issues in your code. 这将帮助您解决代码中的可能问题。

I'd also change the above to 我也将以上内容更改为

try {
    b = ImageIO.read(f);
    z = b;
} catch (IOException ae) {
    ae.printStackTrace();
}

so you are presented with the original image first (this is just my opinion), but since you don't have any real scaling properties at this point, it makes sense to me. 因此,您首先会看到原始图像(这只是我的观点),但是由于此时您还没有任何实际的缩放属性,因此对我来说很有意义。

You're shadowing the cl variable, declaring it as a instance field, but re-declaring it again as a local variable in meth . 您正在隐藏cl变量,将其声明为实例字段,但是再次将其重新声明为meth的局部变量。 I don't if this will be an issue, but you need to be aware of it. 我不是这个问题,但是您需要意识到这一点。

z = z.getScaledInstance(gadda, w, Image.SCALE_SMOOTH); should be z = b.getScaledInstance(gadda, w, Image.SCALE_SMOOTH); 应该是z = b.getScaledInstance(gadda, w, Image.SCALE_SMOOTH); . You want to scale from the source, otherwise you are going to have a lot of pixelation issues. 您想从源头进行扩展,否则将会有很多像素化问题。

You also calling j.repaint(); 您还调用了j.repaint(); which is just repainting the button, which is clearly not what you want to do, instead you should just be calling repaint() on the panel itself 这只是重新绘制按钮,这显然不是您想要执行的操作,相反,您应该只在面板本身上调用repaint()

You should also have a look at The Perils of Image.getScaledInstance() and this example and this example for examples of how you might produce better scaling operations 您还应该查看Image.getScaledInstance()的危险以及该示例此示例,以获取有关如何产生更好的缩放操作的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM