【问题标题】:Unable to type or delete text in JTextfield无法在 JTextfield 中键入或删除文本
【发布时间】:2013-05-06 04:59:25
【问题描述】:

我正在使用 Java 的艺术和科学(使用 Java SE 6u45)学习 Java。尝试通过在 JTextField 中输入新的字体类型来更改文本的字体。但问题是我无法在 JTextField 中输入任何文本。这个问题对于我使用过的其他摆动组件(如 JButton、JCheckBox)很常见。但是在后面的组件中,我可以看到选择的效果,即使视觉选择保持不变,这意味着即使单击后复选框仍保持选中状态,但代码显示未选中框的结果。

但是在 JTextField 的情况下,甚至没有显示效果。我也不能删除我放在 JTextField 中的测试文本。尝试使用isEditable()grabFocus()isFocusable()。会不会是 Java 错误?

/**
* Example 10.9
 * 
 * This program prints the given text in the font inputted by the user in JTextField
 */
package ASJ_Examples;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JLabel;
import javax.swing.JTextField;

import acm.graphics.GLabel;
import acm.program.GraphicsProgram;

public class FontSampler extends GraphicsProgram implements ActionListener{
/**
 * Eclispe Generated
 */
private static final long serialVersionUID = -5734136235409079420L;
private static final String TEST_STRING = "This is a test";
private static final double LEFT_MARGIN = 3;
private static final int MAX_FONT_NAME = 10;

public void init(){
    addJFontLabel();
    addJFontTextField();
    lastY = 0;
    addGLabel(); 
}
/**
 * Adds a text field to enter the required font
 */
private void addJFontTextField() {
    String test = "new";
    fontField = new JTextField(test, MAX_FONT_NAME);    //added to see if Jtextfiled is responding 
//      fontField.setEnabled(true);
//      fontField.setEditable(true);
    fontField.addActionListener(this);
    //added these to give focus to jtextfield but no effect
    fontField.isEditable();
    fontField.grabFocus();
    fontField.isFocusable();
    //add to window
    add(fontField, SOUTH);

}
/**
 * Adds JFontLAbel to denote the text input field
 */
private void addJFontLabel() {
    add(new JLabel("Font"), SOUTH);

}

/**
 * Adds the test label to canvas
 */
private void addGLabel() {
    lastLabel = new GLabel(TEST_STRING);
    add(lastLabel, 20, 20);

}

public void ActionPerformed(ActionEvent e){
    if(e.getSource() == fontField){
        GLabel label = new GLabel(TEST_STRING);
        label.setFont(lastLabel.getFont()); //to display the text even if the suer entered a non-allowed font
        label.setFont(fontField.getText()); //change the font to u4ser demanded font
        addGlabel(label);
        lastLabel = label;
    }
}
/**
 *adds a Glabel on the next line adjusting for heights
 * @param label
 */
private void addGlabel(GLabel label) {
    lastY += label.getHeight();
    lastY += lastLabel.getDescent() - label.getDescent();
    add(label, LEFT_MARGIN, lastY);

}
/**
 * JTextField to enter font
 */
private JTextField fontField;
/**
 * GLabel which is being worked on
 */
private GLabel lastLabel;
/**
 * 
 */
private double lastY;
}

【问题讨论】:

  • ACM API 是纯 AWT,但“J”组件是 Swing。您可能需要调用该功能以允许mix of AWT & Swing
  • 我猜是这样,但这需要我时间来理解。尝试了教程中的示例,您指出了效果组件层次结构,但没有效果。我想稍后会回到这个问题。
  • 为了更好的帮助,请尽快发布SSCCE,简短,可运行,可编译,(射击到黑暗中)顺便说一句,使用未修饰的 JDialog 而不是 J/Window
  • 尝试改用java.awt.TextField,看看是否有效果

标签: java swing actionlistener jtextfield acm-java-libraries


【解决方案1】:

尝试使用fontField.requestFocus(); 而不是fontField.grabFocus();fontField.setEditable(true); 而不是fontField.isEditable(); fontField.setFocusable(true); 而不是 fontField.isFocusable();

顺便说一句,fontField.setEditable(true);fontField.setFocusable(true); 不是必需的,默认情况下它们设置为 true。

【讨论】:

  • fontField.requestFocusInWindow() 而不是 fontField.requestFocus()
  • 试过了,但没有效果。它的响应好像 JTextField 是一个标签。光标变为 textinput 但 JTextField 仍然不可编辑。
【解决方案2】:

正如@andrew-thompson 指出的那样,问题是mix of awt and swing。我想 GComponent 不知何故覆盖了 Swing 组件 JTextField ,这使得它无法访问。因此,解决方法是为 JTextField 创建 JPanel 和 KeyListener,如 @marco 所述。 这是有效的代码: SSCCE 代码

 /**
 * 
 * This program prints the given text in the font inputted by the user in JTextField
 */

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;
import javax.swing.JTextField;

import acm.graphics.GLabel;
import acm.program.GraphicsProgram;

public class FontSampler extends GraphicsProgram implements KeyListener{
private static final String TEST_STRING = "This is a test";
private static final double LEFT_MARGIN = 3;
private static final int MAX_FONT_NAME = 10;

public void init(){
    initPanel();    //init panel
    addJFontTextField();    //adds fontField to enter the font type
    addGLabel();    //adds default label to GCanvas
    lastY = 0;  //default y offset for post-processed label
    add(panel); //adds panel to canvas
}

/**
 * initialises panel 
 */
private void initPanel() {
    panel = new JPanel();
    panel.setLayout(new BorderLayout());

}

/**
 * Adds a text field to enter the required font
 */
private void addJFontTextField() {
    fontField = new JTextField( MAX_FONT_NAME);//added to see if Jtextfiled is responding
    panel.add(fontField, BorderLayout.SOUTH);
    fontField.addKeyListener(this); //adds key listener
}

/**
 * Adds the test label to canvas
 */
private void addGLabel() {
    lastLabel = new GLabel(TEST_STRING);
    add(lastLabel, 20, 20);

}

    /**
     * Called when any key is pressed
     */
public void keyPressed(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_ENTER){//check for enter key pressed
        GLabel label = new GLabel(TEST_STRING);
        label.setFont(lastLabel.getFont()); 
        label.setFont(fontField.getText());
        addGlabel(label);
        lastLabel = label;
    }
}

/**
 *adds a Glabel on the next line adjusting for heights
 * @param label
 */
private void addGlabel(GLabel label) {
    lastY += label.getHeight();
    lastY += lastLabel.getDescent() - label.getDescent();
    add(label, LEFT_MARGIN, lastY);
}

/**
 * JTextField to enter font
 */
private JTextField fontField;
/**
 * GLabel which is being worked on
 */
private GLabel lastLabel;
/**
 * 
 */
private double lastY;

private JPanel panel;

}

谢谢:)

【讨论】:

  • 不要使用 KeyListener。将 ActionListener 添加到文本字段。
  • @camickr 两者都没有。使用 DocumentListener。 ActionListener 仅在用户按下 Enter 时在 JTextField 中触发。
  • @Marco,KeyListener(在上面发布的代码中)只是在寻找 Enter 键,这就是为什么 ActionListener 应该在这个答案的上下文中使用。
  • @camickr 哦,我没看到。那么在这种情况下你是对的;)仍然不建议这样做,当用户复制和粘贴某些内容然后只是切换到另一个组件而不按 Enter 时会发生什么?
  • @marco 是的。在这种情况下,ActionListener 会好得多。
【解决方案3】:

但在后面的组件中,我可以看到选择的效果,即使视觉选择保持不变,这意味着即使单击后复选框仍保持选中状态,但代码显示未选中框的结果。

这听起来很奇怪。也许GraphicsProgram 班级正在做一些顽皮的事情。虽然不能告诉 w/o 它的代码。

fontField.isEditable();
fontField.grabFocus();
fontField.isFocusable();

如果字段可编辑(默认情况下),则第一个返回布尔值。 第二个不应该被客户端程序使用,而是使用fontField.requestFocusInWindow()。如果字段可聚焦(默认情况下),则第三个返回布尔值。

fontField.addActionListener(this);

JTextField 上的 ActionListener 什么都不做。尝试这样做:

fontfield.getDocument().addDocumentListener(new DocumentListener() {

    @Override
    public void removeUpdate(DocumentEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        // TODO Auto-generated method stub  
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        // TODO Auto-generated method stub
    }
});

【讨论】:

  • 每当有人将KeyListener 附加到文本字段时,开发人员就会缓慢而可怕地死亡:P
  • 对 JTextField 使用 DocumentListener 而不是使用 KeyListener
  • 试过fontField.addKeyListener(new KeyAdapter(){ @Override public void keyTyped(KeyEvent e){ if(e.getKeyCode() == KeyEvent.VK_ENTER){ println("test"); } } });,但仍然没有效果。猜猜这是@andrew-thompson 指出的一些AWT- Swing mix 的东西。必须阅读它。目前这个问题还没有解决。我同意将 ActionListener 添加到 JTextField 是我的错误。谢谢你:)
  • 它是否命中您的 KeyListener() 的 keyTyped(){}?如果不是,则可能是由于布局组件之类的原因。我猜
  • @MadProgrammer 哦,天哪,我最好在喝第一杯咖啡之前停止回答问题;)显然它是 DocumentListener .. 感谢您指出。已编辑。
猜你喜欢
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2016-05-13
  • 1970-01-01
  • 2013-06-05
  • 1970-01-01
相关资源
最近更新 更多