繁体   English   中英

从另一个类java向JFrame添加图片

[英]Adding picture to JFrame from another class java

我正在尝试制作一个程序,该程序读取用户选择的文件,并且在读取文件后-将后缀“ txt”更改为“ gif”,并将文件另存为图片(与该文件位于同一目录中)文件)。 问题是,此图片变量在“ actionPerformed-method”中获取其值,此后,我想将其添加到另一个类的框架中,但它不会显示。 这是我的OptionsPane类中的代码:

public class OptionsPane extends JComponent implements ActionListener{

    private JButton buttonOne = new JButton("Alt.1");
    private JButton buttonTwo = new JButton("Alt.2");
    private JButton buttonThree = new JButton("Alt.3");
    private int option;
    private JButton buttonChoose = new JButton("Choose file"); 
    private FileHandler filehandler; 
    private String picture;
    private JLabel picLabel; 

    public OptionsPane(){

        JLabel label = new JLabel("Choose optimization method", SwingConstants.CENTER);
        JPanel subPanel = new JPanel(); 
        label.setForeground(Color.CYAN); 
        label.setFont(new Font("Tahoma", Font.BOLD, 15));   
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(label);
        buttonOne.addActionListener(this);
        buttonTwo.addActionListener(this);
        buttonThree.addActionListener(this);
        buttonChoose.addActionListener(this);

        subPanel.setBackground(Color.DARK_GRAY);
        subPanel.add(buttonOne);
        subPanel.add(buttonTwo);
        subPanel.add(buttonThree);
        subPanel.add(buttonChoose);
        this.add(subPanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == buttonOne){
            option = 1;
            System.out.println("You clicked button 1!");
        }else if(e.getSource() == buttonTwo){
            option = 2;
            System.out.println("You clicked button 2!");
        }else if(e.getSource() == buttonThree){
            option = 3;
            System.out.println("You clicked button 3!");
        }else if(e.getSource() == buttonChoose){
            System.out.println("hello");
            option = 4; 
            filehandler = new FileHandler(); 
            filehandler.read();
            picture = filehandler.getFilePath().replaceFirst("txt", "gif"); 
            picLabel = new JLabel(new ImageIcon(picture));
            this.add(picLabel); 
        }
    }
}

该框架位于“ MainFrame”类中,目前如下所示:

public class MainFrame extends JFrame{

    private JFrame frame = new JFrame(); 
    private String picture; 
    private JLabel picLabel;
    public MainFrame(){

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(1300, 800)); 
        frame.getContentPane().setBackground(Color.DARK_GRAY);
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));

        OptionsPane optionspane = new OptionsPane(); 
        frame.add(optionspane);

        frame.pack(); 
        frame.setVisible(true);
        frame.setResizable(true);
    }
}

为什么在大型机中看不到图片?

编辑现在可以使用!

https://stackoverflow.com/a/22380387/3271504

感谢您的帮助@arooaroo。 我试图记下您写的内容,但是当我想根据用户选择的文件添加图像时仍然无法正常工作(例如,如果用户选择文件text1.txt,我想要相应的图片“ text1.gif”显示)。 在您的帮助下,当我用“ /”-斜杠键入特定路径时该图片出现了,但是当我选择一个文件并尝试从文件路径中加载图片时,该图片没有显示,这是因为它带有反斜杠在通路中。 这应该是这样(这样一个令人烦恼的问题):

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == buttonOne){
        option = 1;
        System.out.println("You clicked button 1!");
    }else if(e.getSource() == buttonTwo){
        option = 2;
        System.out.println("You clicked button 2!");
    }else if(e.getSource() == buttonThree){
        option = 3;
        System.out.println("You clicked button 3!");
    }else if(e.getSource() == buttonChoose){
    filehandler = new FileHandler(); 
    filehandler.read();
    filepath = filehandler.getFilePath(); 
    picture = filepath.replaceFirst("txt", "gif");
    picture = picture.replaceAll("\\\\", "/");

    ImageIcon icon = new ImageIcon(picture);
    mainFrame.setPicture(icon);

}

谢谢您的帮助!

一旦将您的GUI代码分成不同的类(这是一件好事),您将发现GUI编程的永恒挑战是允许它们之间存在相互依赖关系时进行干净的通信。

在这种情况下,也许最简单的方法是将MainFrame的引用传递到OptionsPane

假设您在MainFrame创建了用于设置图片的其他方法:

public class MainFrame extends JFrame{

  // all instance vars as before

  public MainFrame() {
     // same as before except for this line...
     OptionsPane optionspane = new OptionsPane(this); 
  }

  public void setPicture(JLabel pictureLabel) {
     // add code here for adding the picture...
     // That's an exercise for yourself, or another question ;)
  }

}

然后在您的OptionsPane类中:

....
private MainFrame mainFrame;  // add a new instance var

public OptionsPane(MainFrame mainFrame) {
  this.mainFrame = mainFrame;
  // ... rest of the code same as before
}

@Override
public void actionPerformed(ActionEvent e) {
    //...
        picture = filehandler.getFilePath().replaceFirst("txt", "gif"); 
        picLabel = new JLabel(new ImageIcon(picture));
        mainFrame.setPicture(picLabel); // <-- This is where you communicate with the mainFrame instance 
    //...
}

编辑

尽管我的原始答案提供了有效且正确的解决方案,但很明显,OP需要一个完全有效的示例,包括加载显示结果图像的代码。 这是一个示例程序。

public class OptionsPane extends JComponent implements ActionListener {

    private JButton buttonOne = new JButton("Alt.1");
    private JButton buttonTwo = new JButton("Alt.2");
    private JButton buttonThree = new JButton("Alt.3");
    private int option;
    private JButton buttonChoose = new JButton("Choose file");
    private String picture;
    private JLabel picLabel;
    private MainFrame mainFrame;

    public OptionsPane(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
        JLabel label = new JLabel("Choose optimization method", SwingConstants.CENTER);
        JPanel subPanel = new JPanel();
        label.setForeground(Color.CYAN);
        label.setFont(new Font("Tahoma", Font.BOLD, 15));
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(label);
        buttonOne.addActionListener(this);
        buttonTwo.addActionListener(this);
        buttonThree.addActionListener(this);
        buttonChoose.addActionListener(this);

        subPanel.setBackground(Color.DARK_GRAY);
        subPanel.add(buttonOne);
        subPanel.add(buttonTwo);
        subPanel.add(buttonThree);
        subPanel.add(buttonChoose);
        this.add(subPanel);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        // For sake of simplicity I'm ignoring the original button logic here
        // and focussing on just getting an icon loaded in the parent frame...

        ImageIcon icon = new ImageIcon("/path/to/test/image.png");
        // Just pass the icon itself rather than a new label.
        mainFrame.setPicture(icon);

    }
}


public class MainFrame {
    // No need to extend JFrame if you're using a JFrame instance variable
    private JFrame frame = new JFrame();
    private JLabel picLabel;

    private JPanel mainPanel;
    public MainFrame() {
        mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBackground(Color.DARK_GRAY);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(1300, 800));

        OptionsPane optionspane = new OptionsPane(this);
        mainPanel.add(optionspane, BorderLayout.NORTH);
        picLabel = new JLabel();
        picLabel.setHorizontalAlignment(JLabel.CENTER);
        mainPanel.add(picLabel, BorderLayout.CENTER);

        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(true);
        frame.setResizable(true);
    }

    public void setPicture(ImageIcon icon) {
        picLabel.setIcon(icon);
    }

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

请注意,我做了几件不同的事情。 我个人总是创建一个JPanel并将其设置为主层,然后直接将其添加到框架中,而不是与rootPane搞混。 在此示例中,我使用了BorderLayout ,因为它要简单得多。

另一件事是在初始设置中添加JLabel ,以将图片保存到GUI。 然后您将看到我仅在setPicture()方法中更改其图标,而不是在每个实例上添加新的JLabel

暂无
暂无

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

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