【问题标题】:java swing DatePicker done wrong using a JTextField and want to changejava swing DatePicker 使用 JTextField 出错并想要更改
【发布时间】:2011-12-22 22:52:00
【问题描述】:

我最初构建了一个 DatePicker。只要有人单击 JtextField,就会在 JTextField 旁边打开一个日历对话框。如果一个人想要键入日期而不是选择日期,那么他将首先关闭打开的对话框,然后键入日期。

它的外观如下:

public class DateTextField extends JTextField implements Observer {

public void update(Observable o, Object arg) {
    Calendar calendar = (Calendar) arg;
    DatePicker dp = (DatePicker) o;
    setText(dp.formatDate(calendar));
}

public DateTextField() {
    final Observer obs = this;
    final JTextField tf = this;
    this.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseReleased(MouseEvent e) {
            if(tf.isEditable()){
                DatePicker dp = new DatePicker(obs);
                Date selectedDate = dp.parseDate(tf.getText());
                dp.setSelectedDate(selectedDate);
                dp.start(tf);
            }
        }
    });
}

我没有展示 DatePicker 类,因为这不是这里的问题。问题是,一个人每次都关闭日历对话框来输入日期是非常烦人的。相反,我想做的是在 JtextField 的一侧保留一个按钮,并且只有当用户单击该按钮时才会弹出对话框。

但要做到这一点,我需要 DatePicker 来扩展 JPanel 类,并且我可以并排布置 JTextfield 和 JButton。但不幸的是,DatePicker 类扩展了 JtextField,并且在我的整个应用程序中,我期望 DatePicker 是一个 JtextField。在此 DatePicker 上有从 JComponent 到 JTextfield 的强制转换以及对 get 和 setText() 的调用。

如果我必须更改 DatePicker 以扩展 JPanel 表单,那么它将在任何地方破坏我的应用程序。我想知道我是否可以通过绘画或其他方式修饰 JTextfield 以在侧面显示按钮?这可能吗?

【问题讨论】:

  • 为什么要重新发明轮子?您可以使用 JXDatePicker(在 SwingX 项目中)为您完成所有繁重的工作:-)
  • 我之前尝试过,但它不允许用户正确选择年份或其他内容。这是我在大约 1.5 年前尝试过的。因此构建了我自己的组件。现在它的使用遍布我的代码库..寻找不涉及再次更改所有地方的东西.​​.

标签: java swing


【解决方案1】:

我想,你应该重写paintComponent 方法并稍微改变MouseListener。 像这样的:

    protected void paintComponent(Graphics g) {  
        super.paintComponent(g);  
        int y = (getHeight() - image.getHeight())/2;  
        g.drawImage(image, x, y, this);  
    }  

并以某种方式在您的 MouseListener 中跟踪 e.getX() e.getY() 事件的坐标。

【讨论】:

    【解决方案2】:

    1) public class DateTextField extends JSpinner implements Observer {

    2) JSpinnerSpinnerDateModel,然后从/到另一个实例的解析没有问题

    3) 使用JWindow 弹出窗口,有7x7 JLabelsJButtons

    【讨论】:

    • 感谢您的回答...但我真的不想更改层次结构,因为这意味着我需要更新整个代码库以进行此更改。
    【解决方案3】:

    对于任何想看看以后如何.. 下面列出了代码。您覆盖绘画并在文本字段的左角绘制图像。然后实现 mouseClicked 以仅在单击图像时才响应。还实现一个鼠标运动侦听器,如果光标在图像上,则将光标更改为手形指针,如果不在,则将光标更改为文本光标。

    public class DateTextField extends JTextField implements Observer {
    
    public void update(Observable o, Object arg) {
        Calendar calendar = (Calendar) arg;
        DatePicker dp = (DatePicker) o;
        setText(dp.formatDate(calendar));
    }
    
    public DateTextField() {
        final Observer obs = this;
        final JTextField tf = this;
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(tf.isEditable()){
                    Point p = e.getPoint();
                    if(p.x>=getWidth()-22 && p.x <getWidth()
                            && p.y<=getHeight()) {
                        DatePicker dp = new DatePicker(obs);
                        Date selectedDate = dp.parseDate(tf.getText());
                        dp.setSelectedDate(selectedDate);
                        dp.start(tf);
                    }
                }
            }
        });
    
        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                Point p = e.getPoint();
                if(p.x>=getWidth()-22 && p.x <getWidth()
                        && p.y<=getHeight()) {
                    DateTextField.this.setCursor(new Cursor(Cursor.HAND_CURSOR));
                }else {
                    DateTextField.this.setCursor(new Cursor(Cursor.TEXT_CURSOR));
                }
            }
        });
    }
    
    public DateTextField(String text) {
        this();
        this.setText(text);
    }
    
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        try {
            BufferedImage img = ImageIO.read(new File(DateTextField.class.getResource("/images/calendar.png").getFile()));
            int x=getWidth()-22;
            g.drawImage(img,x,1,20,getHeight()-2,null);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-15
      • 2012-01-08
      • 1970-01-01
      • 2013-03-02
      • 2012-12-10
      • 2016-06-21
      相关资源
      最近更新 更多