我有一个GUI窗口,询问休息时间。我想得到的结果是,例如,1:15 - int hours = 1和int mins = 15 - 单击继续按钮后。我得到的结果要么是小时,要么是分钟,因为我不能让JComboBox和JButton一起工作(我想)。另外,我不太清楚如何检查用户是输入了数字还是输入了无效的输入。这是代码:
@SuppressWarnings("serial")
public class FormattedTextFields extends JPanel implements ActionListener {
private int hours;
private JLabel hoursLabel;
private JLabel minsLabel;
private static String hoursString = " hours: ";
private static String minsString = " minutes: ";
private JFormattedTextField hoursField;
private NumberFormat hoursFormat;
public FormattedTextFields() {
super(new BorderLayout());
hoursLabel = new JLabel(hoursString);
minsLabel = new JLabel(minsString);
hoursField = new JFormattedTextField(hoursFormat);
hoursField.setValue(new Integer(hours));
hoursField.setColumns(10);
hoursLabel.setLabelFor(hoursField);
minsLabel.setLabelFor(minsLabel);
JPanel fieldPane = new JPanel(new GridLayout(0, 2));
JButton cntButton = new JButton("Continue");
cntButton.setActionCommand("cnt");
cntButton.addActionListener(this);
JButton prevButton = new JButton("Back");
String[] quarters = { "15", "30", "45" };
JComboBox timeList = new JComboBox(quarters);
timeList.setSelectedIndex(2);
timeList.addActionListener(this);
fieldPane.add(hoursField);
fieldPane.add(hoursLabel);
fieldPane.add(timeList);
fieldPane.add(minsLabel);
fieldPane.add(prevButton);
fieldPane.add(cntButton);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(fieldPane, BorderLayout.CENTER);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("FormattedTextFieldDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FormattedTextFields());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equalsIgnoreCase("cnt")) {
hours = ((Number) hoursField.getValue()).intValue();
minutes = Integer.parseInt(timeList.getSelectedItem().toString());
// \d mean every digit charater
Pattern p = Pattern.compile("\\d");
Matcher m = p.matcher(hoursField.getValue().toString());
if (m.matches()) {
System.out.println("Hours: " + hours);
System.out.println("Minutes: " + minutes);
} else {
hoursField.setValue(0);
JOptionPane.showMessageDialog(null, "Numbers only please.");
}
}
}
} // end class
- 编辑 -
更新了ActionPerformed方法
答案 0 :(得分:7)
您需要对动作侦听器中可见的组合框的有效引用,以便ActionListener能够在其上调用方法并提取它所持有的值。目前,您的JComboBox在类的构造函数中声明,因此仅在构造函数中可见,而在其他位置不可见。要解决这个问题,组合框需要是一个类字段,这意味着它在类本身中声明,而不是某些方法或构造函数。
例如:
import java.awt.event.*;
import javax.swing.*;
public class Foo002 extends JPanel implements ActionListener {
JComboBox combo1 = new JComboBox(new String[]{"Fe", "Fi", "Fo", "Fum"});
public Foo002() {
JComboBox combo2 = new JComboBox(new String[]{"One", "Two", "Three", "Four"});
JButton helloBtn = new JButton("Hello");
helloBtn.addActionListener(this); // I really hate doing this!
add(combo1);
add(combo2);
add(helloBtn);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("FormattedTextFieldDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Foo002());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
// this works because combo1 is visible in this method
System.out.println(combo1.getSelectedItem().toString());
// this doesn't work because combo2's scope is limited to
// the constructor and it isn't visible in this method.
System.out.println(combo2.getSelectedItem().toString());
}
}
答案 1 :(得分:3)
对于解析数测试,您有两个解决方案:
第一
try{
Integer.parseInt(myString);
catch(Exception e){
System.out.print("not a number");
}
第二:我认为更清洁的方法是使用正则表达式:
// \d mean every digit charater you can find a full description [here][1]
Pattern p = Pattern.compile("\\d");
Matcher m = p.matcher( myString );
if( m.matches() ){
//it's a number
}else{
//it's not a number
}
如果您想要更强大的正则表达式,请查看此java regex tester。
晚安&祝你好运PS:在图形元素之间进行交互没有问题,您只需要保留图形对象的引用。
答案 2 :(得分:2)
检查此代码段,添加一些注释以提供有关NumberFormat的信息,并在单击“继续”按钮时显示时间。由于你想要应用的检查类型,我在一个简单的JTextField上做了这个,不需要JFormattedTextField。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class FormattedTextFields extends JPanel implements ActionListener
{
private int hours;
private JLabel hoursLabel;
private JLabel minsLabel;
private static String hoursString = " hours: ";
private static String minsString = " minutes: ";
private JComboBox timeList;
private JTextField hoursField;
public FormattedTextFields()
{
super(new BorderLayout());
hoursLabel = new JLabel(hoursString);
minsLabel = new JLabel(minsString);
hoursField = new JTextField();
//hoursField.setValue(new Integer(hours));
hoursField.setColumns(10);
hoursLabel.setLabelFor(hoursField);
minsLabel.setLabelFor(minsLabel);
Document doc = hoursField.getDocument();
if (doc instanceof AbstractDocument)
{
AbstractDocument abDoc = (AbstractDocument) doc;
abDoc.setDocumentFilter(new DocumentInputFilter());
}
JPanel fieldPane = new JPanel(new GridLayout(0, 2));
JButton cntButton = new JButton("Continue");
cntButton.setActionCommand("cnt");
cntButton.addActionListener(this);
JButton prevButton = new JButton("Back");
String[] quarters = { "15", "30", "45" };
/*
* Declared timeList as an Instance Variable, so that
* it can be accessed inside the actionPerformed(...)
* method.
*/
timeList = new JComboBox(quarters);
timeList.setSelectedIndex(2);
timeList.addActionListener(this);
fieldPane.add(hoursField);
fieldPane.add(hoursLabel);
fieldPane.add(timeList);
fieldPane.add(minsLabel);
fieldPane.add(prevButton);
fieldPane.add(cntButton);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(fieldPane, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("FormattedTextFieldDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FormattedTextFields());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
@Override
public void actionPerformed(ActionEvent e)
{
String time = "";
if (e.getActionCommand().equalsIgnoreCase("cnt"))
{
hours = Integer.parseInt(hoursField.getText());
time = hours + " : " + ( (String) timeList.getSelectedItem());
System.out.println(time);
}
}
/*
* This class will check for any invalid input and present
* a Dialog Message to user, for entering appropriate input.
* you can let it make sound when user tries to enter the
* invalid input. Do see the beep() part for that inside
* the class's body.
*/
class DocumentInputFilter extends DocumentFilter
{
public void insertString(FilterBypass fb
, int offset, String text, AttributeSet as) throws BadLocationException
{
int len = text.length();
if (len > 0)
{
/* Here you can place your other checks
* that you need to perform and do add
* the same checks for replace method
* as well.
*/
if (Character.isDigit(text.charAt(len - 1)))
super.insertString(fb, offset, text, as);
else
{
JOptionPane.showMessageDialog(null, "Please Enter a valid Integer Value."
, "Invalid Input : ", JOptionPane.ERROR_MESSAGE);
Toolkit.getDefaultToolkit().beep();
}
}
}
public void replace(FilterBypass fb, int offset
, int length, String text, AttributeSet as) throws BadLocationException
{
int len = text.length();
if (len > 0)
{
if (Character.isDigit(text.charAt(len - 1)))
super.replace(fb, offset, length, text, as);
else
{
JOptionPane.showMessageDialog(null, "Please Enter a valid Integer Value."
, "Invalid Input : ", JOptionPane.ERROR_MESSAGE);
Toolkit.getDefaultToolkit().beep();
}
}
}
}
} // end class