混淆了我试图使用的JPanel的属性

时间:2014-11-08 06:16:13

标签: java swing jframe jpanel javax.imageio

我正在构建一个带有swing的简单GUI,但我遇到了一个我无法弄清楚原因的问题。创建缓冲图像会阻止我的其余代码执行任何操作。

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.BorderFactory;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Main extends JPanel{

    BufferedImage img;
    int number;

    public static void main(String[] args) {
        JFrame frame = new JFrame("Some practice");
        frame.setSize(200,200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        Main doStuff = new Main();

        JButton myButton = new JButton("Button");
        JPanel controls = new JPanel();
        controls.setBorder(BorderFactory.createTitledBorder(
                             "Small Panel"));
        controls.add(myButton);
        frame.add("South", controls);

        frame.add(doStuff);
    }

    public Main () {
        super.setBorder(BorderFactory.createTitledBorder("Big Panel!"));

        // This method seems to shut down my GUI
        importImage();
    }

    private void importImage() {
        try {
                img = ImageIO.read(new File("res/strawberry.jpg"));
        } catch (IOException e) {
                System.out.println("Image exception");
        }
    }
}

如果我在importImage的构造函数中有Main函数,那么GUI就不会显示。尝试注释掉doStuff();行,你会看到两个镶边的面板出现。

我想知道的是Java或Swing的特性是什么,我没有看到这导致我混淆?感谢

1 个答案:

答案 0 :(得分:2)

frame.setVisible(true);移至main()的末尾。

public static void main(String[] args) {
    JFrame frame = new JFrame("Some practice");
    frame.setSize(200, 200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // frame.setVisible(true);

    Main doStuff = new Main();

    JButton myButton = new JButton("Button");
    JPanel controls = new JPanel();
    controls.setBorder(BorderFactory.createTitledBorder("Small Panel"));
    controls.add(myButton);
    frame.add("South", controls);

    frame.add(doStuff); // <-- you are still adding things.
    frame.setVisible(true);
}

修改

但是,你似乎想要ImagePanel喜欢

/**
 * From: http://www.java2s.com/Code/Java/Swing-JFC/Panelwithbackgroundimage.htm
 */
class ImagePanel extends JPanel {
    private Image img;

    public ImagePanel(String img) {
        this(new ImageIcon(img).getImage());
    }

    public ImagePanel(Image img) {
        this.img = img;
        Dimension size = new Dimension(img.getWidth(null),
                img.getHeight(null));
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);
        setLayout(null);
    }

    public void paintComponent(Graphics g) {
        g.drawImage(img, 0, 0, null);
    }
}

然后将构造函数更改为使用add(ImagePanel),例如

String imgPath = "res/strawberry.jpg";
add(new ImagePanel(imgPath));   

最后,您应该在新的Thread上下文中执行操作,并向ActionListener添加了Main,以便您可以单击按钮。把它们放在一起

public class Main extends JPanel implements ActionListener {
    BufferedImage img;
    int number;

    public static void main(String[] args) {
        JFrame frame = new JFrame("Some practice");
        Runnable doRun = new Runnable() {
            @Override
            public void run() {
                frame.setSize(200, 200);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                Main doStuff = new Main();

                JButton myButton = new JButton("Button");
                myButton.addActionListener(doStuff);
                JPanel controls = new JPanel();
                controls.setBorder(BorderFactory
                        .createTitledBorder("Small Panel"));
                controls.add(myButton);
                frame.add("South", controls);
                frame.add(doStuff);
                frame.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(doRun);
    }

    public Main() {
        super.setBorder(BorderFactory.createTitledBorder("Big Panel!"));
        final String imgPath = "res/strawberry.jpg";
        // This method seems to shut down my GUI
        add(new ImagePanel(imgPath));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e);
    }
}