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

时间:2014-03-13 13:07:24

标签: java swing jframe imageicon

我正在尝试创建一个程序来读取用户选择的文件,并在读取文件后 - 将后缀“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);

}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

一旦你将你的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