gpt4 book ai didi

java - JTextArea 过滤器和/或时间输入 (00 :00:00) Java

转载 作者:行者123 更新时间:2023-12-01 22:45:11 26 4
gpt4 key购买 nike

我的程序中有一个部分,用户应该能够编辑时间量。已经设置了默认时间量,但用户应该能够根据需要对其进行编辑 (00:00:00)是否可以使用单行 JTextArea 来限制可以输入的字符(显然只能输入数字)和某种不允许编辑冒号的过滤器?或者有更简单的东西吗?

最佳答案

因此,处理持续时间有很大不同,因为许多正常的“验证”过程可以被丢弃(例如,您并不真正关心时间,因为用户可能需要输入 100 小时,因为示例)...

所以,基于这个time field example ,我剥离了 API 并重新构建了它(无论如何它确实需要彻底修改;))

所以我最终得到了这个持续时间字段......

Duration Field

从本质上讲,它只不过是一系列带有 DocumentFilterDocumentListener 的字段、一些键绑定(bind)和通用自动化,使其“看起来”像一个单个字段...

import java.awt.Component;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class DurationField extends AbstractTimeField {

private HourDocumentFilter hourDocumentFilter;

private JTextField secondField;
private DocumentFilter secondDocumentFilter;
private FocusListener secondFocusHandler;

public DurationField() {
setDuration(0, 0, 0);
}

public void setDuration(int hour, int minute, int seconds) {
setHour(hour);
setMinute(minute);
setSeconds(seconds);
}

public long getDuration() throws NumberFormatException {

int hour = getHour();
int minute = getMinute();
int second = getSecond();

return (hour * 60 * 60 * 1000)
+ (minute * 60 * 1000)
+ (second * 1000);

}

@Override
public void setHour(int hour) {
setFieldValue(getHourField(), hour, 3);
}

public void setSeconds(int seconds) {
setFieldValue(getSecondField(), seconds, 2);
}

public int getSecond() throws NumberFormatException {
return Integer.parseInt(getSecondField().getText());
}

@Override
protected JTextField createHourField() {
JTextField field = super.createHourField();
field.setColumns(4);
return field;
}

@Override
protected int getHourFocusForwardLength() {
return -1;
}

protected int getSecondFocusForwardLength() {
return 2;
}

protected JTextField createSecondField() {
JTextField secondField = new JTextField(2);
((AbstractDocument) secondField.getDocument()).setDocumentFilter(getSecondDocumentFilter());
secondField.addFocusListener(getSecondFocusHandler());
secondField.setHorizontalAlignment(JTextField.RIGHT);
secondField.getDocument().addDocumentListener(new MoveFocusForwardHandler(secondField, getMinuteFocusForwardLength()));
return secondField;
}

@Override
protected JComponent[] getTimeFields() {
return new JComponent[]{
getHourField(),
new JLabel(":"),
getMinuteField(),
new JLabel("."),
getSecondField()
};
}

@Override
protected List<JComponent> initFocusTransveralOrder() {
List<JComponent> order = super.initFocusTransveralOrder();
order.add(getSecondField());
return order;
}

@Override
protected void installKeyBindings() {
super.installKeyBindings();

JTextField minuteField = getMinuteField();
installKeyBinding(
minuteField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, 0),
"toSecondField",
new MoveFocusForward());

installKeyBinding(
minuteField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
"afterMinuteArrow",
new MoveFieldFocusForward(minuteField, true));
installKeyBinding(
minuteField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD6, 0),
"afterMinuteKeyPad",
new MoveFieldFocusForward(minuteField, false));

JTextField secondField = getMinuteField();
installKeyBinding(
secondField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
"beforeSecond",
new MoveFieldFocusBackward(minuteField, true));
installKeyBinding(
secondField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4, 0),
"beforeSecond",
new MoveFieldFocusBackward(secondField, false));
}

public JTextField getSecondField() {
if (secondField == null) {
secondField = createSecondField();
}
return secondField;
}

@Override
protected DocumentFilter getHourDocumentFilter() {
if (hourDocumentFilter == null) {
hourDocumentFilter = new HourDocumentFilter();
}
return hourDocumentFilter;
}

protected DocumentFilter getSecondDocumentFilter() {
if (secondDocumentFilter == null) {
secondDocumentFilter = new SecondDocumentFilter();
}
return secondDocumentFilter;
}

/**
* Returns the focus listener used to monitor the hour field
*
* @return
*/
protected FocusListener getSecondFocusHandler() {
if (secondFocusHandler == null) {
secondFocusHandler = new SecondFocusHandler();
}
return secondFocusHandler;
}

protected void secondFieldLostFocus(FocusEvent evt) {
String text = getSecondField().getText();
if (text.length() < 2) {
text = pad(text, 2);
getSecondField().setText(text);
}
}

/**
* Hour field focus handler. This watches for focus lost events a automatically pads the field with a leading "0" if the field is only 1 character in length
*/
protected class SecondFocusHandler extends AbstractFocusHandler {

@Override
public void focusLost(FocusEvent e) {
secondFieldLostFocus(e);
}
}

protected class HourDocumentFilter extends DocumentFilter {

@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
System.out.println("insert: offset = " + offset + "; text = " + text);
super.insertString(fb, offset, text, attr);
}

@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

try {
// We convert the value here to make sure it's a number...
int value = Integer.parseInt(text);
super.replace(fb, offset, length, text, attrs);
} catch (NumberFormatException exp) {
}
}
}

protected class SecondDocumentFilter extends DocumentFilter {

@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
super.insertString(fb, offset, text, attr);
}

@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

try {
boolean isAcceptable = false;

// How long is the text been added
int strLength = text.length();
// Convert the value to an integer now and save us the hassel
int value = Integer.parseInt(text);

// If the length is only 1, probably a new character has been added
if (strLength == 1) {
// The valid range of values we can accept
int upperRange = 9;
int lowerRange = 0;

// Is the value acceptable..
if (value >= lowerRange && value <= upperRange) {
isAcceptable = true;
}
} else {
// Basically, we are going to trim the value down to at max 2 characters

// Need to know at what offest...
// 2 - offset..
// offset == 0, length = 2 - offset = 2
// offset == 1, length = 2 - offset = 1
strLength = 2 - offset;
String timeText = text.substring(offset, strLength);
value = Integer.parseInt(timeText);
if (value >= 0 && value <= 59) {
// Pad out the value as required
text = pad(value, 2);
isAcceptable = true;
}
}

if (isAcceptable) {
super.replace(fb, offset, length, text, attrs);
}

} catch (NumberFormatException exp) {
}
}
}

}

还有抽象父类...

import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.JTextComponent;

public abstract class AbstractTimeField extends JPanel {

private DocumentFilter minDocumentFilter;
private FocusListener hourFocusHandler;
private FocusListener minuteFocusHandler;

private JTextField hourField;
private JTextField minuteField;

private JPanel pnlFields;

private List<JComponent> focusOrder;

public AbstractTimeField() {

initUI();
installKeyBindings();

}

protected void initUI() {

setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(getTimeFieldsPanel(), gbc);

}

protected void installKeyBindings() {

JTextField hourField = getHourField();
installKeyBinding(
hourField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_SEMICOLON, KeyEvent.SHIFT_DOWN_MASK),
"toMinuteField",
new MoveFocusForward());
installKeyBinding(
hourField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
"afterHourArrow",
new MoveFieldFocusForward(hourField, true));
installKeyBinding(
hourField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD6, 0),
"afterHourKeyPad",
new MoveFieldFocusForward(hourField, false));

JTextField minuteField = getMinuteField();
installKeyBinding(
minuteField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
"beforeMinuteArrow",
new MoveFieldFocusBackward(minuteField, true));
installKeyBinding(
minuteField,
JComponent.WHEN_FOCUSED,
KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4, 0),
"beforeMinuteKeyPad",
new MoveFieldFocusBackward(minuteField, false));

}

protected JPanel getTimeFieldsPanel() {

if (pnlFields == null) {

pnlFields = new JPanel(new GridBagLayout());
pnlFields.setBorder(new CompoundBorder(UIManager.getBorder("TextField.border"), new EmptyBorder(0, 2, 0, 2)));
pnlFields.setBackground(UIManager.getColor("TextField.background"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (JComponent field : getTimeFields()) {
field.setBorder(null);
pnlFields.add(field, gbc);
gbc.gridx++;
}

}

return pnlFields;

}

protected JComponent[] getTimeFields() {
return new JComponent[]{
getHourField(),
new JLabel(":"),
getMinuteField()
};
}

protected List<JComponent> initFocusTransveralOrder() {
List<JComponent> focusOrder = new ArrayList<>(3);
focusOrder.add(getHourField());
focusOrder.add(getMinuteField());
return focusOrder;
}

protected List<JComponent> getFocusTraversalOrder() {
if (focusOrder == null) {
focusOrder = initFocusTransveralOrder();
}
return focusOrder;
}

protected int getHourFocusForwardLength() {
return 2;
}

protected int getMinuteFocusForwardLength() {
return 2;
}

protected JTextField createHourField() {
JTextField hourField = new JTextField(2);
((AbstractDocument) hourField.getDocument()).setDocumentFilter(getHourDocumentFilter());
hourField.addFocusListener(getHourFocusHandler());
hourField.setHorizontalAlignment(JTextField.RIGHT);
hourField.getDocument().addDocumentListener(new MoveFocusForwardHandler(hourField, getHourFocusForwardLength()));
return hourField;
}

public JTextField getHourField() {
if (hourField == null) {
hourField = createHourField();
}
return hourField;
}

protected JTextField createMinuteField() {
JTextField minuteField = new JTextField(2);
((AbstractDocument) minuteField.getDocument()).setDocumentFilter(getMinuteDocumentFilter());
minuteField.addFocusListener(getMinuteFocusHandler());
minuteField.setHorizontalAlignment(JTextField.RIGHT);
minuteField.getDocument().addDocumentListener(new MoveFocusForwardHandler(hourField, getMinuteFocusForwardLength()));
return minuteField;
}

public int getHour() throws NumberFormatException {
return getFieldValue(getHourField());
}

public int getMinute() throws NumberFormatException {
return getFieldValue(getMinuteField());
}

protected int getFieldValue(JTextComponent field) throws NumberFormatException {
return Integer.parseInt(field.getText());
}

public void setHour(int hour) {
setFieldValue(getHourField(), hour, 2);
}

public void setMinute(int minute) {
setFieldValue(getMinuteField(), minute, 2);
}

protected void setFieldValue(JTextComponent field, int value, int padding) {
String text = pad(value, padding);
field.setText(text);
}

public JTextField getMinuteField() {
if (minuteField == null) {
minuteField = createMinuteField();
}
return minuteField;
}

/**
* Returns the document filter used to filter the hour field
*
* @return
*/
protected abstract DocumentFilter getHourDocumentFilter();

/**
* Returns the document filter user to filter the minute field
*
* @return
*/
protected DocumentFilter getMinuteDocumentFilter() {
if (minDocumentFilter == null) {
minDocumentFilter = new MinuteDocumentFilter();
}
return minDocumentFilter;
}

/**
* Returns the focus listener used to monitor the hour field
*
* @return
*/
protected FocusListener getHourFocusHandler() {
if (hourFocusHandler == null) {
hourFocusHandler = new HourFocusHandler();
}
return hourFocusHandler;
}

/**
* Used the focus listener used to monitor the minute field
*
* @return
*/
protected FocusListener getMinuteFocusHandler() {
if (minuteFocusHandler == null) {
minuteFocusHandler = new MinuteFocusHandler();
}
return minuteFocusHandler;
}

public static String pad(long lValue, int iMinLength) {
return pad(Long.toString(lValue), 2);
}

public static String pad(int iValue, int iMinLength) {
return pad(Integer.toString(iValue), iMinLength);
}

public static String pad(String sValue, int iMinLength) {
StringBuilder sb = new StringBuilder(iMinLength);
sb.append(sValue);
while (sb.length() < iMinLength) {
sb.insert(0, "0");
}
return sb.toString();
}

protected void hourFieldLostFocus(FocusEvent evt) {
if (!evt.isTemporary()) {
String text = getHourField().getText();
if (text.length() < 2) {
text = pad(text, 2);
getHourField().setText(text);
}
}
}

protected void minuteFieldLostFocus(FocusEvent evt) {
if (!evt.isTemporary()) {
String text = getMinuteField().getText();
if (text.length() < 2) {
getMinuteField().setText(text + "0");
}
}
}

protected void installKeyBinding(JComponent field, int condition, KeyStroke keyStroke, String name, Action action) {
InputMap im = field.getInputMap(condition);
im.put(keyStroke, name);

ActionMap am = field.getActionMap();
am.put(name, action);
}

protected void moveFocusToNextField(JComponent parent) {
List<JComponent> order = getFocusTraversalOrder();
Component current = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (current == parent) {
int index = order.indexOf(current);
if (index != -1) {
if (index == order.size() - 1) {
transferFocus();
} else {
JComponent next = order.get(index + 1);
next.requestFocusInWindow();
}
} else {
transferFocus();
}
}
}

protected void moveFocusToPreviousField(JComponent parent) {
List<JComponent> order = getFocusTraversalOrder();
Component current = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (current == parent) {
int index = order.indexOf(current);
if (index != -1) {
if (index == 0) {
transferFocusBackward();
} else {
JComponent previous = order.get(index - 1);
previous.requestFocusInWindow();
}
} else {
transferFocusBackward();
}
}
}

protected abstract class AbstractFocusHandler extends FocusAdapter {

@Override
public void focusGained(FocusEvent e) {
if (e.getComponent() instanceof JTextComponent) {
JTextComponent field = (JTextComponent) e.getComponent();
field.selectAll();
}
}

}

/**
* Hour field focus handler. This watches for focus lost events a automatically pads the field with a leading "0" if the field is only 1 character in length
*/
protected class HourFocusHandler extends AbstractFocusHandler {

@Override
public void focusLost(FocusEvent e) {
hourFieldLostFocus(e);
}
}

/**
* Minute field focus handler, watches for focus lost events and automatically adds a "0" to the end of the field if it is only 1 character in length
*/
protected class MinuteFocusHandler extends AbstractFocusHandler {

@Override
public void focusLost(FocusEvent e) {
minuteFieldLostFocus(e);
}

}

protected class MoveFocusForwardHandler implements DocumentListener {

private JTextComponent parent;
private int maxLength;

public MoveFocusForwardHandler(JTextComponent parent, int maxLength) {
this.parent = parent;
this.maxLength = maxLength;
}

public int getMaxLength() {
return maxLength;
}

public JTextComponent getParent() {
return parent;
}

@Override
public void insertUpdate(DocumentEvent e) {
documentChanged(e);
}

@Override
public void changedUpdate(DocumentEvent e) {
documentChanged(e);
}

@Override
public void removeUpdate(DocumentEvent e) {
documentChanged(e);
}

protected void documentChanged(DocumentEvent e) {
if (getMaxLength() > 0) {
if (e.getDocument().getLength() >= getMaxLength()) {
moveFocusToNextField(getParent());
}
}
}

}

/**
* The document filter used to filter the minute field.
*/
protected class MinuteDocumentFilter extends DocumentFilter {

@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
super.insertString(fb, offset, text, attr);
}

@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

try {
boolean isAcceptable = false;

// How long is the text been added
int strLength = text.length();
// Convert the value to an integer now and save us the hassel
int value = Integer.parseInt(text);

// If the length is only 1, probably a new character has been added
if (strLength == 1) {
// The valid range of values we can accept
int upperRange = 9;
int lowerRange = 0;
if (offset == 0) {
// If we are at the first edit position, we can only accept values
// from 0-5 (50 minutes that is)
upperRange = 5;
}

// Is the value acceptable..
if (value >= lowerRange && value <= upperRange) {
isAcceptable = true;
}
} else {
// Basically, we are going to trim the value down to at max 2 characters

// Need to know at what offest...
// 2 - offset..
// offset == 0, length = 2 - offset = 2
// offset == 1, length = 2 - offset = 1
strLength = 2 - offset;
String timeText = text.substring(offset, strLength);
value = Integer.parseInt(timeText);
if (value >= 0 && value <= 59) {
// Pad out the value as required
text = pad(value, 2);
isAcceptable = true;
}
}

if (isAcceptable) {
super.replace(fb, offset, length, text, attrs);
if (fb.getDocument().getLength() == 2) {
moveFocusToNextField(getMinuteField());
}
}

} catch (NumberFormatException exp) {
}
}
}

public class TimeFocusTraversalPolicy
extends FocusTraversalPolicy {

private List<Component> order;

public TimeFocusTraversalPolicy(List<Component> order) {
this.order = new ArrayList<>(order.size());
this.order.addAll(order);
}

@Override
public Component getComponentAfter(Container focusCycleRoot,
Component aComponent) {
int idx = (order.indexOf(aComponent) + 1) % order.size();
return order.get(idx);
}

@Override
public Component getComponentBefore(Container focusCycleRoot,
Component aComponent) {
int idx = order.indexOf(aComponent) - 1;
if (idx < 0) {
idx = order.size() - 1;
}
return order.get(idx);
}

@Override
public Component getDefaultComponent(Container focusCycleRoot) {
return order.get(0);
}

@Override
public Component getLastComponent(Container focusCycleRoot) {
return order.get(order.size() - 1);
}

@Override
public Component getFirstComponent(Container focusCycleRoot) {
return order.get(0);
}
}

public class MoveFocusForward extends AbstractAction {

@Override
public void actionPerformed(ActionEvent e) {
moveFocusToNextField((JComponent) e.getSource());
}

}

public class MoveFocusBackward extends AbstractAction {

@Override
public void actionPerformed(ActionEvent e) {
moveFocusToPreviousField((JComponent) e.getSource());
}

}

public class MoveFieldFocusForward extends AbstractAction {

private JTextComponent field;
private final boolean ignoreNumLock;

public MoveFieldFocusForward(JTextComponent field, boolean ignoreNumLock) {
this.field = field;
this.ignoreNumLock = ignoreNumLock;
}

@Override
public void actionPerformed(ActionEvent e) {
boolean numLockOff = false;
try {
// Get the state of the nums lock
numLockOff = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK);
} catch (Exception exp) {
}
if (ignoreNumLock || !numLockOff) {
if (field.getCaretPosition() >= field.getDocument().getLength()) {
moveFocusToNextField((JComponent) e.getSource());
}
}
}

}

public class MoveFieldFocusBackward extends AbstractAction {

private JTextComponent field;
private final boolean ignoreNumLock;

public MoveFieldFocusBackward(JTextComponent field, boolean ignoreNumLock) {
this.field = field;
this.ignoreNumLock = ignoreNumLock;
}

@Override
public void actionPerformed(ActionEvent e) {
boolean numLockOff = false;
try {
// Get the state of the nums lock
numLockOff = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK);
} catch (Exception exp) {
}
if ((ignoreNumLock || !numLockOff) && field.getCaretPosition() <= 1) {
moveFocusToPreviousField((JComponent) e.getSource());
}
}

}
}

抽象是为了我的利益,从这里我也可以构建一个 TimeField :)

关于java - JTextArea 过滤器和/或时间输入 (00 :00:00) Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25477999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com