java - 我尝试使用的 JPanel 的令人困惑的属性

标签 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 的哪些属性导致了我的这种混淆?谢谢

最佳答案

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 上下文中执行操作,并且我向 Main 添加了一个 ActionListener,以便您可以单击该按钮。将所有内容放在一起

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);
    }
}

关于java - 我尝试使用的 JPanel 的令人困惑的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26814411/

相关文章:

java - 我们可以在回收 View 中调整项目高度吗?

java - java 中 JEditorPane 中的语法高亮显示

java - 将矩形保留在 JFrame 中

java - 我需要使用数据库中的值创建 XYLineChart (Java(Mysql)

java - 处理 JFrame 会导致内存泄漏吗?

javascript - 如何在 es6 版本的 javascript 中使用 java 库?

java - Hibernate可以将空字符串默认为空字符串吗

java - 如何查找 JFrame 中某个像素的颜色?

java - 如何根据 JList 中选择的内容更新 JLabel

java - 添加数组列表时Android Material Design下拉布局问题