2013-05-06 37 views
1

我正在使用Java和Art of Science(使用Java SE 6u45)學習Java。試圖通過在JTextField中輸入新的字體類型來更改文本的字體。但問題是我無法在JTextField中輸入任何文本。這個問題對於我用過的JButton,JCheckBox等其他swing組件來說很常見。但在後面的組件中,我可以看到選擇的效果,即使視覺選擇保持不變,這意味着即使在單擊之後該複選框仍保持選中狀態,但代碼顯示未選中框的結果。無法在JTextfield中鍵入或刪除文本

但是在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; 
} 
+1

的ACM API是純粹的AWT,但 'J' 組件是搖擺。您可能需要調用該功能以允許[AWT和Swing混合](http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html)。 – 2013-05-06 05:18:58

+0

我想是這樣,但這需要我時間來理解。嘗試了教程中的示例,指向效果組件層次結構,但沒有效果。我想稍後會回到這個問題。 – 2013-05-06 06:59:20

+1

爲更好地幫助發佈[SSCCE](http://sscce.org/),簡短,可運行,可編譯,(拍攝到黑暗)BTW使用未裝飾的JDialog代替J/Window – mKorbel 2013-05-06 07:15:01

回答

0

正如@安德魯 - 湯普森指出,問題是mix of awt and swing。我猜想GComponent重疊了Swing組件JTextField,導致它無法訪問。所以解決方法是創建JPanel和KeyListener到JTextField,如@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; 

} 

謝謝:)

+0

[sscce](http://sscce.org/)應該是完整的並且是獨立的。 – trashgod 2013-05-06 11:24:27

+0

請勿使用KeyListener。將ActionListener添加到文本字段。 – camickr 2013-05-06 15:13:28

+0

@camickr都不是。使用DocumentListener。當用戶按Enter時,ActionListener只會在JTextField中觸發。 – Marco 2013-05-06 15:29:32

0

嘗試使用的fontField.requestFocus();代替fontField.grabFocus();fontField.setEditable(true);,而不是fontField.isEditable(); fontField.setFocusable(true);,而不是fontField.isFocusable();

BTW fontField.setEditable(true);fontField.setFocusable(true);是沒有必要的默認情況下它們都設置爲true。

+1

'fontField.requestFocusInWindow()'而不是'fontField.requestFocus()' – MadProgrammer 2013-05-06 06:03:35

+0

嘗試過它們,但沒有效果。它正在響應,就好像JTextField是一個標籤。遊標變爲textinput,但JTextField仍然是不可編輯的。 – 2013-05-06 06:43:52

0

但是在後面的組件中,我可以看到選擇的效果,即使可視化選擇保持不變,這意味着即使點擊後複選框仍保持選中狀態,但代碼顯示未選中框的結果。

這聽起來很奇怪。也許GraphicsProgram班正在做一些調皮的事。雖然不能告訴它的代碼。

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 
    } 
}); 
+2

開發者死緩慢而可怕的死亡每一些附加一個'KeyListener'到文本字段時:P – MadProgrammer 2013-05-06 06:04:28

+0

使用'DocumentListener'到JTextField的而不是使用'KeyListener' – Amarnath 2013-05-06 06:16:34

+0

試了一下'fontField.addKeyListener(新KeyAdapter(){ \t \t \t @Override \t \t \t公共無效的keyTyped(KeyEvent的發送){ \t \t \t \t如果(e.getKeyCode()== KeyEvent.VK_ENTER){ \t \t \t \t \t的println( 「測試」); \t \t \t \t} \t \t \t} \t \t});',但沒有效果依然。猜猜這是一些[AWT搖擺組合](http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html),正如@ andrew-thompson所指出的。必須閱讀它。目前這個問題尚未解決。我同意將ActionListener添加到JTextField是我的錯。謝謝你:) – 2013-05-06 06:56:21