是否可以像这样在JTextField中分发字符串:(" bruno"在蓝色文本字段中)。
JTextField自动划分为许多等间距位置作为最大列值
我编写此代码来解释为什么字体跟踪对我不起作用:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.font.TextAttribute;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class SpacedFieldTest extends JFrame{
Map<TextAttribute, Object> fontAttributes = new HashMap<TextAttribute, Object>();
int maxColumn;
String text;
public SpacedFieldTest(String text, int maxColumn) {
this.text = text;
this.maxColumn = maxColumn;
addContent();
pack();
}
private void addContent() {
setLayout(new FlowLayout());
final SpacedField field = new SpacedField();
configureField(field, "Arial", 20f);
getContentPane().add(field);
JSpinner spinner = createSpinner(field);
getContentPane().add(spinner);
JLabel tracking = new JLabel("Tracking");
getContentPane().add(tracking);
}
private JSpinner createSpinner(final SpacedField field) {
float min = 0.0f;
float value = 0.1f;
float max = 3.0f;
float stepSize = 0.1f;
SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, stepSize);
JSpinner spinner = new JSpinner(model){
@Override
public Object getValue() {
fontAttributes.put(TextAttribute.TRACKING, super.getValue());
field.setFont(field.getFont().deriveFont(fontAttributes));
return super.getValue();
}
};
spinner.setPreferredSize(new Dimension(50,25));
JSpinner.NumberEditor editor = (JSpinner.NumberEditor)spinner.getEditor();
DecimalFormat format = editor.getFormat();
format.setMinimumFractionDigits(1);
return spinner;
}
private void configureField(JTextField field, String family, float fontSize) {
fontAttributes.put(TextAttribute.SIZE, fontSize);
fontAttributes.put(TextAttribute.FAMILY, family);
Font font = Font.getFont(fontAttributes);
field.setFont(font);
field.setText(text);
}
class SpacedField extends JTextField{
final int WIDTH = 300;
final int HEIGHT = 25;
int gridWidth;
public SpacedField() {
gridWidth = WIDTH/maxColumn;
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setDocument(new SpacedFieldDocument());
}
public void paintComponent(Graphics g){
super.paintComponent(g);
paintGrid(g);
}
private void paintGrid(Graphics g) {
for(int i=1; i<=maxColumn; i++){
g.drawLine(i*gridWidth, HEIGHT/2, i*gridWidth, HEIGHT);
}
}
}
class SpacedFieldDocument extends PlainDocument{
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if(getLength()>maxColumn)
return;
super.insertString(offs, str, a);
}
}
public static void main(String args[]){
final SpacedFieldTest sf = new SpacedFieldTest("abcde", 5);
sf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
sf.setVisible(true);
}
});
}
}
答案 0 :(得分:0)
可能的肥胖型。
您要做的是为每个可用字符设置单独的JTextField。这最好作为一个独立的类实现,扩展JComponent,但这取决于你。
我建议在初始化程序中抛出这些:
private final LinkedList<JTextField> fields = new LinkedList<>();
private KeyListener fieldKeyListener = new KeyListener(){
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() != KeyEvent.VK_BACK_SPACE && e.getKeyCode() != KeyEvent.VK_DELETE) {
System.out.println("Key code: " + e.getKeyCode());
int index = fields.indexOf(e.getSource());
int newIndex = index + 1;
if(newIndex < fields.size()) fields.get(newIndex).requestFocus();
else
System.out.println(gatherString());
//or use whichever action should retrieve the string
}
}
@Override
public void keyReleased(KeyEvent e) {
}
};
对于它的肉,你会想要这样做。我继续在JFrame的中间即时构建它,但如果你可以想象不止一次这样做,你会想要将它改编为构造函数的初始化器。
private JComponent getDistField() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, charCount));
for(int i = 0; i < charCount; i++) {
fields.add(new JTextField(1));
/* All customizations to look and feel, for each component, go here */
//document must be unique for each field, or text will duplicate.
fields.getLast().setDocument(new PlainDocument(){
@Override
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if(getLength() + str.length() <= 1)
super.insertString(offs, str, a);
}
});
fields.getLast().addKeyListener(fieldKeyListener);
panel.add(fields.getLast());
}
return panel;
}
我假设&#34; charCount&#34;为字段接受的字符数提前设置(或甚至作为参数传入)。迭代器创建一系列子文本字段;每个都将处理一个字符并立即更新插入符号的位置。请注意,文档需要对每个字段都是唯一的,否则文本将在整个过程中自行复制!
理论上,您也可以使用插入符号侦听器而不是键侦听器来执行此操作;然而,它们与按键相切并且完全不知道哪个键刚刚关闭。并不意味着它无法弄清楚,但我找不到一个干净的方法去做。
当您准备好输入所输入字符串的完整内容时,请调用以下内容:
public String gatherString() {
StringBuilder builder = new StringBuilder();
for(JTextField field : fields) {
builder.append(field.getText());
}
return builder.toString();
}
它从每个字段的内容汇集字符串。值得庆幸的是,空字段没有贡献;如果你想要它们也是不可编辑的,你可以尝试将它们设置为禁用并触发它们在它们之前的字段的填充;甚至添加一个鼠标监听器,找到最后一个未编辑的字段,并在任何点击时突出显示它。这完全是关于听众(/观察者)的。
希望这会为你做到,我相信你可以明白为什么你可能希望这是它自己的模块。祝你好运!
此外,如果您将来查看问题的正确格式,它将非常有用。我无法在当前条件下对其进行投票,社区将更好地收到它。它可以帮助您研究"How do I ask a good question?"。