Java - 创建PNG / Text徽标并将其绘制到JFrame

时间:2014-03-30 14:05:52

标签: java swing paintcomponent

我尝试打印用户可以输入到文本框的字符串到JFrame。 我的问题是永远不会调用paintComponent方法。为什么呢?

PNGCreatorWindow类:

public class PNGCreatorWindow {

private JFrame frame;
private JTextField txtText;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                PNGCreatorWindow window = new PNGCreatorWindow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public PNGCreatorWindow() {
    initialize();
}

private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 678, 502);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    txtText = new JTextField();
    txtText.setBounds(121, 13, 216, 22);
    frame.getContentPane().add(txtText);
    txtText.setColumns(10);

    JButton btnGenerate = new JButton("Generate");
    btnGenerate.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        }
    });
    btnGenerate.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent arg0) {
            GeneratePNGImage();
        }
    });
    btnGenerate.setBounds(436, 6, 183, 36);
    frame.getContentPane().add(btnGenerate);

    JPanel panel = new JPanel();
    panel.setBounds(107, 151, 338, 160);
    frame.getContentPane().add(panel);
}

protected void GeneratePNGImage() {
    PNGImage img = new PNGImage(txtText.getText());

    frame.getContentPane().add(img);        
    frame.getContentPane().validate();
    frame.getContentPane().setVisible(true);
    frame.repaint();

}
}

PNGImage类:

public class PNGImage extends JComponent {

private String text;


public PNGImage(String text){
    this.text = text;
}

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D)g;
    g2.setColor(Color.red);
    g2.drawString(this.text, 100,100);
    g2.fillRect(50, 50, 1000, 1000);
}

}

1 个答案:

答案 0 :(得分:2)

我对您的代码进行了一些更改,以便在JPanel上绘制文本。

  1. 我将JTextField和JButton放在控制面板(JPanel)中,并为控制面板设置layout manager(FlowLayout)。您应该始终使用布局管理器来布局Swing组件。

  2. 我将图像面板(PNGImage)定义为布局Swing组件的一部分。首先,将所有Swing组件放在一起。然后,你改变他们的状态。

  3. 我删除了鼠标适配器,并在JButton上使用了一个动作侦听器。动作监听器使用鼠标。

  4. 在PNGImage类中,我添加了一个setter,因此我可以在用户在JTextField中键入文本之后将文本传递给该类。

  5. 我添加了对setPreferredSize的调用,以便我可以设置绘图画布的大小。我删除了所有其他大小调整,并使用JFrame的pack方法使JFrame具有适当的大小来容纳Swing组件。

  6. 我在paintComponent中添加了一个null测试,因此只有在绘制了一些文本时才会绘制文本。

  7. 这是代码。我将所有代码放在一个模块中,以便更容易粘贴。

    package com.ggl.testing;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class PNGCreatorWindow {
    
        private JFrame      frame;
        private JTextField  txtText;
        private PNGImage    imagePanel;
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        new PNGCreatorWindow();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        public PNGCreatorWindow() {
            initialize();
        }
    
        private void initialize() {
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            JPanel controlPanel = new JPanel();
            controlPanel.setLayout(new FlowLayout());
    
            txtText = new JTextField(10);
            controlPanel.add(txtText);
    
            JButton btnGenerate = new JButton("Generate");
            btnGenerate.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    generatePNGImage();
                }
            });
            controlPanel.add(btnGenerate);
    
            imagePanel = new PNGImage();
    
            frame.getContentPane().add(controlPanel, BorderLayout.NORTH);
            frame.getContentPane().add(imagePanel, BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
    
        protected void generatePNGImage() {
            imagePanel.setText(txtText.getText());
            imagePanel.repaint();
        }
    
        public class PNGImage extends JPanel {
    
            private static final long   serialVersionUID    = 602718701626241645L;
    
            private String              text;
    
            public PNGImage() {
                setPreferredSize(new Dimension(400, 300));
            }
    
            public void setText(String text) {
                this.text = text;
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (this.text != null) {
                    Graphics2D g2 = (Graphics2D) g;
                    g2.setColor(Color.red);
                    g2.drawString(this.text, 100, 100);
                }
            }
    
        }
    
    }
    

    编辑添加动作侦听器,将JPanel的内容保存为.png文件:

    package com.ggl.crossword.controller;
    
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.awt.image.RenderedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.swing.JFileChooser;
    import javax.swing.JPanel;
    import javax.swing.filechooser.FileFilter;
    import javax.swing.filechooser.FileNameExtensionFilter;
    
    import com.ggl.crossword.view.CrosswordFrame;
    
    public class CreateImageActionListener implements ActionListener {
    
        private CrosswordFrame frame;
    
        private JPanel panel;
    
        public CreateImageActionListener(CrosswordFrame frame,
                JPanel panel) {
            this.frame = frame;
            this.panel = panel;
        }
    
        @Override
        public void actionPerformed(ActionEvent event) {
            writeImage();
        }
    
        public void writeImage() {
            FileFilter filter = 
                    new FileNameExtensionFilter("PNG file", "png");
            JFileChooser fc = new JFileChooser();
            fc.setFileFilter(filter);
            int returnValue = fc.showSaveDialog(frame.getFrame());
            if (returnValue == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                if (!file.getAbsolutePath().endsWith(".png")) {
                    file = new File(file.getAbsolutePath() + ".png");
                }
                RenderedImage image = createImage(panel);
                try {
                    ImageIO.write(image, "png", file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private BufferedImage createImage(JPanel panel) {
            int w = panel.getWidth();
            int h = panel.getHeight();
            BufferedImage bi = new BufferedImage(w, h, 
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bi.createGraphics();
            panel.paint(g);
            g.dispose();
            return bi;
        }
    
    }