【问题标题】:Jtextfield setText() would not work at allJtextfield setText() 根本不起作用
【发布时间】:2021-12-27 04:09:27
【问题描述】:

所以这就是我想要做的就是将 absolutePath 放入 jtextfield,我做了系统打印,它显示了路径,但不会在 jtextfield 中设置文本。

向导类中的动作事件(按钮):

  //buttons
  JButton openMapButton = new JButton("Load Map");
  ImageLoader imgload = new ImageLoader();
  openMapButton.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent e){
        imgload.fileChooser();
     }
 });

Wizard 类中的 Jtextfield:

      JTextField mapURLField = new JTextField(20);

ImageLoader 类:

public class ImageLoader extends Wizard{

private JLabel label; 
JFileChooser chooser;
File file; 
private BufferedImage img;
Wizard wiz = new Wizard();
JTextField mapURLField;   


public void loadImg(){
}


public void fileChooser(){
 wiz.mapURLField = new JTextField();
      
  if(chooser == null){
  chooser = new JFileChooser(".");
}

int returnVal = chooser.showOpenDialog(null);

if(returnVal == JFileChooser.APPROVE_OPTION){
  wiz.mapURLField.setText(chooser.getSelectedFile().getAbsolutePath());
  System.out.println(chooser.getSelectedFile().getAbsolutePath());
  }else{
     wiz.mapURLField.setText("");
  }
  
  chooser.setSelectedFile(null);


 } 
}

【问题讨论】:

  • 所以你是说System.out.println(chooser.getSelectedFile().getAbsolutePath()); 有效但wiz.mapURLField.setText(chooser.getSelectedFile().getAbsolutePath()); 无效?如果是这种情况,使用任何值设置文本字段是否有效?
  • 这个,Wizard wiz = new Wizard(); 可能是你的问题。您正在创建一个 new 向导对象,但它与显示的对象相同吗?没有像样的minimal reproducible example,真的很难说。我还想知道您是否正确使用了继承,ImageLoader extends Wizard
  • 如果ImageLoader extends Wizard 那么你为什么要实例化new Wizard() - 哎呀重复@HovercraftFullOfEels 评论
  • 然后是wiz.mapURLField = new JTextField(); - 这肯定是不是显示的JTextField。恐怕您在整个这段代码中都在滥用引用。

标签: java swing jtextfield jfilechooser


【解决方案1】:

您在错误 Wizard 对象内设置了错误 JTextField 的状态。应该更改的文本字段是 displayed Wizard 类中显示的文本字段,而不是您在某个其他类中当场创建的 JTextField您也在 ImageLoader 中创建的新创建的非显示向导类。

这个:

public class ImageLoader extends Wizard{
    private JLabel label; 

    // ....        

    Wizard wiz = new Wizard();
    JTextField mapURLField; 

创建一个new Wizard 对象,但它肯定不是当前正在显示的 Wizard 对象,因此改变了这个新创建且未显示的对象对您没有帮助。

改为:

ImageLoader imgload = new ImageLoader();

到:

ImageLoader imgload = new ImageLoader(this);     

如果没有在 ActionListener 或其他匿名类中调用,因为这应该将显示的 Wizard 对象加载到 ImageLoader 类中。

在 ImageLoader 中做:

private Wizard wiz; // a field to hold the displayed Wizard

public ImageLoader(Wizard wiz) {
    this.wiz = wiz; // set the field with the parameter passed in
    ....
}

然后在你的 ImageLoader 类中调用 *true Wizard 对象的方法,现在由 wiz 持有。

另外,摆脱

wiz.mapURLField = new JTextField();

创建一个 JTextField 是没有意义的,它肯定不会显示在原始Wizard 对象中。您想要更改显示的 JTextField 的状态。最好的方法是为 Wizard 提供一个公共方法,让您可以这样做:

// in the Wizard class:

public void setMapUrlField(String text) {
    mapURLField.setText(text);
}

最后,ImageLoader 扩展了 Wizard 类:

public class ImageLoader extends Wizard {

可能没有做你认为它正在做的事情,也可能不是你想做的事情。


概念证明代码:

import java.io.File;
import javax.swing.*;

public class Wizard extends JPanel {
    private ImageLoader imgload = new ImageLoader(this);
    private JTextField mapURLField = new JTextField(30);
    private JButton openMapButton = new JButton("Load Map");
    private File file;
    
    public Wizard() {
        openMapButton.addActionListener(e -> {
            file = imgload.fileChooser();
        });
        
        mapURLField.setFocusable(false);
        add(mapURLField);
        add(openMapButton);
    }
    
    public void setMapUrlField(String text) {
        mapURLField.setText(text);
    } 
    
    public File getFile() {
        return file;
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Wizard wiz = new Wizard();
            
            JFrame frame = new JFrame("Wizard");
            frame.add(wiz);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
class ImageLoader {

    private Wizard wiz;

    public ImageLoader(Wizard wizard) {
        this.wiz = wizard;
    }

    public File fileChooser() {
        File file = null;
        JFileChooser fileChooser = new JFileChooser();
        int retValue = fileChooser.showOpenDialog(wiz);
        if (retValue == JFileChooser.APPROVE_OPTION) {
            file = fileChooser.getSelectedFile();
            wiz.setMapUrlField(file.getAbsolutePath());
        } else {
            wiz.setMapUrlField("");
        }
        
        return file;
    }
    
}

【讨论】:

  • 感谢您的清晰解释,它帮助我更清楚地理解。它有效,但有一个小问题,我得到java.lang.NullPointerException: Cannot invoke "javax.swing.JTextField.setText(String)" because "this.mapURLField" 为空,但是当我调试它时,它显然不是空的,因为它显示了 url?我认为扩展会给类访问方法等等,但我错了。
  • 没关系,显然这是因为我有 2 个“新 jtextfield”,一个用于命名,一个用于创建。这样做的正确方法是什么? (比如private JTextField siteNameField, aisleNumField, laneNumField;JTextField siteNameField = new JTextField(5); .....)
  • @Zyaan:您将需要与外部对象交互的 Swing 组件声明为类的私有字段,并使用公共方法来允许受控交互,正如我在此处的代码中所示。如果这不能回答您在上面提出的问题,那么我不确定您在问什么。
  • 很抱歉,我没有问对,但我的意思是,无需为每个 jtextfield 变量执行 "JTextfields jt = new JTextField(20); 即可声明多个 jtextfields 的最简单方法是什么,而不是一个声明和另一个一个像我一样在体内创建它?我还想再次感谢您帮助我解决我的问题:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多