我正在尝试创建一个程序来读取用户选择的文件,并在读取文件后 - 将后缀“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);
}
感谢您的帮助!
答案 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
。