[英]Formatted text field and JComboBox together
我有一個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方法
您需要對動作偵聽器中可見的組合框的有效引用,以便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());
}
}
對於解析數測試,您有兩個解決方案:
第一:
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正則表達式測試器 。
晚安,祝你好運
PS:在圖形元素之間進行交互沒有問題,您只需要保留圖形對象的引用。
檢查此片段,添加一些注釋以提供有關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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.