Jbutton acction listener

左心房为你撑大大i 提交于 2019-12-11 08:48:50

问题


I am trying to create a form. there is a button that when clicking the button, a photo which is specified would appear. my problem is, when I click the button, the picture pops up and if the cursor passes the form boundary, the image disappears. here is my code:

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;

public class SeamCarving extends JFrame
{     
public static void main(String[] args) throws IOException {
    final BufferedImage input = ImageIO.read(new File("path"));

    final BufferedImage[] toPaint = new BufferedImage[]{input};
    final Frame frame = new Frame("Seams") {

        @Override
        public void update(Graphics g) {
            final BufferedImage im = toPaint[0];
            if (im != null) {
                g.clearRect(0, 0, getWidth(), getHeight());
                g.drawImage(im, 0, 0, this);
            }
        }
    };
    frame.setSize(input.getWidth(), input.getHeight());
    frame.setVisible(true);
    frame.add(startButton);

    startButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            BufferedImage out = input;
            out = deleteVerticalSeam(out);
            toPaint[0] = out;
            frame.repaint();
            System.out.println("Do Something Clicked");
        }
    });
 }
}

回答1:


Don't override update, this isn't how painting is achieved in Swing. Attempting to paint directly to a top level container like JFrame is problematic at best.

Instead, start with a JPanel and use it's paintComponent method instead. Make sure you call super.paintComponent as well.

In fact, you could probably just use a JLabel to display the image instead.

Take a look at;

  • Performing Custom Painting
  • How to use labels

For more details

Updated with example

I still think a JLabel would be simpler solution, but what do I know.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SeamCarving {

    public static void main(String[] args) {
        new SeamCarving();
    }

    public SeamCarving() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage input;
        private BufferedImage[] toPaint;

        public TestPane() {
            try {
                input = ImageIO.read(new File("C:\\hold\\thumbnails\\2005-09-29-3957.jpeg"));
                toPaint = new BufferedImage[1];
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setLayout(new GridBagLayout());
            JButton startButton = new JButton("Start");
            startButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    BufferedImage out = input;
                    out = input; //deleteVerticalSeam(out);
                    toPaint[0] = out;
                    repaint();
                    System.out.println("Do Something Clicked");
                }
            });
            add(startButton);
        }

        @Override
        public Dimension getPreferredSize() {
            return input == null ? new Dimension(400, 400) : new Dimension(input.getWidth(), input.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (toPaint[0] != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(input, 0, 0, this);
                g2d.dispose();
            }
        }
    }

}

The problem with overriding update is the paint subsystem can choose to avoid calling and end up calling paint directly, circumventing your painting.

Painting also involves painting child components (like your button) and borders, which you've conveniently discarded by not calling super.update.



来源:https://stackoverflow.com/questions/21036624/jbutton-acction-listener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!