【问题标题】:How to set the Date Picker just below the button如何在按钮下方设置日期选择器
【发布时间】:2011-08-01 00:52:29
【问题描述】:

我想通过点击按钮打开一个日期选择器。但是当我点击按钮时,它会在屏幕的左上角显示一个日历。我想在按钮下方看到它。我该怎么做?

另外,我怎样才能改变日历的大小以使它有点小?

下面是例子。


package practiceproblems; 

import java.awt.*;  
import java.awt.event.*;  
import javax.swing.*;

class DatePicker {  

int month = java.util.Calendar.getInstance().get(java.util.Calendar.MONTH);
int year = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR);
JLabel l = new JLabel("", JLabel.CENTER);  
String day = "";
JDialog d;
JButton[] button = new JButton[49];

public DatePicker(JFrame parent) {  
d = new JDialog();
d.setModal(true);
String[] header = { "Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat" };
JPanel p1 = new JPanel(new GridLayout(7, 7));
p1.setPreferredSize(new Dimension(430, 120));
for (int x = 0; x < button.length; x++) {
    final int selection = x;
    button[x] = new JButton();
    button[x].setFocusPainted(false);
    button[x].setBackground(Color.white);
    if (x > 6)
        button[x].addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                day = button[selection].getActionCommand();
                d.dispose();
            }
        });
        if (x < 7) {
            button[x].setText(header[x]);
            button[x].setForeground(Color.red);
        }
        p1.add(button[x]);
}
JPanel p2 = new JPanel(new GridLayout(1, 3));
JButton previous = new JButton("<< Previous");
previous.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        month--;
        displayDate();
    }
});
p2.add(previous);
p2.add(l);
JButton next = new JButton("Next >>");
next.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        month++;
        displayDate();
    }
});
p2.add(next);
d.add(p1, BorderLayout.CENTER);
d.add(p2, BorderLayout.SOUTH);
d.pack();
d.setLocationRelativeTo(parent);
displayDate();
d.setVisible(true);

}

public void displayDate() {
for (int x = 7; x < button.length; x++)
    button[x].setText("");
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("MMMM yyyy");
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.set(year, month, 1);
int dayOfWeek = cal.get(java.util.Calendar.DAY_OF_WEEK);
int daysInMonth = cal.getActualMaximum(java.util.Calendar.DAY_OF_MONTH);
for (int x = 6 + dayOfWeek, day = 1; day <= daysInMonth; x++, day++)
    button[x].setText("" + day);
l.setText(sdf.format(cal.getTime()));
d.setTitle("Date Picker");

}

public String setPickedDate() {
if (day.equals(""))
    return day;
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd-MM-yyyy");
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.set(year, month, Integer.parseInt(day));
return sdf.format(cal.getTime());
}

}

 class Picker {   

   public static void main(String[] args) {  
    JLabel label = new JLabel("Selected Date:");
    final JTextField text = new JTextField(20);
    JButton b = new JButton("popup");
    JPanel p = new JPanel();
    p.add(label);
    p.add(text);
    p.add(b);
    final JFrame f = new JFrame();
    f.getContentPane().add(p);
    f.pack();
    f.setVisible(true);
    b.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            text.setText(new DatePicker(f).setPickedDate());
        }
    });
}

}

【问题讨论】:

  • sscce+1。
  • 为什么要重新发明轮子?特别是,如果轮子不完全是微不足道的。 SwingX 自带 JXDatePicker,你可能想看看它是如何实现的
  • @kleopatra 我听到了你的话,但即便如此,我还是不得不佩服 OP 的小日期选择器。我从没想过在屏幕上获得一个基本的日期选择器会这么容易! @bsm 使用已经开发和全面测试的库日期选择器具有明显的优势。

标签: java swing datepicker


【解决方案1】:

因此,您在按钮下显示日历所需的代码如下。但在您使用它之前,您必须 (1)、应该 (2) 和可以 (3) 对代码进行一些更改。

  1. 在 DatePicker 构造函数中去掉 d.setVisible(true);因为我们要在实际显示对话框之前在动作侦听器中进行一些设置。
  2. 在创建框架时,添加这一行总是很有用的 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);因此您的应用程序将始终关闭,否则您的应用程序会消耗您的计算机资源。
  3. 我建议日期选择器扩展 JDialog 而不是将对话框作为变量。因为实际上日期选择器在您的代码中的样子。


        b.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                DatePicker dp = new DatePicker(f);
                Point bP = b.getLocationOnScreen();
                dp.d.setLocation(bP.x, bP.y + b.getHeight()); 
                dp.d.setVisible(true);
                text.setText(dp.setPickedDate());
            }
        });

当谈到考虑尺寸变化的问题的第二部分时,Andrew Thompson 回答得很好,因为你已经在调用 pack,所以任何尺寸修改都是不希望的。

享受吧,波罗。

【讨论】:

  • 很好的答案,因为它更好地解决了 OP 的第一个问题。
  • 非常感谢您的帮助。特别感谢@Boro 和@Andrew Thompson。
  • 我仍然没有成功解决的一件事是:我们如何设置DatePicker(日历)的最小(日历的所有内容都可见)大小?我是否必须单独设置面板和所有按钮的大小?我怎样才能准确地获得按钮文本清晰可见的最小尺寸?我应该通过试错法找到它吗?
  • 我说你必须在日期选择器中设置每个单元格的大小。为了尽可能减少将每个单元格的大小设置为适合两位数(假设您很乐意将列名减少为两个字符)。最好在这里使用 FontMetrics 来获取字体中文本的宽度。但更好的是使用一些布局管理器来控制组件的大小调整,而不是单独处理每个组件。我个人最喜欢的是 TableLayout。有了它,我停止使用任何 GUI 构建器。
  • 是的,我也在考虑通过布局管理器。谢谢。
【解决方案2】:

我想在按钮下方看到它。我该怎么做? ..

Component.setLocation(int, int)Window.setLocationRelativeTo(Component)

..如何更改日历的大小以使其小一点?

Component.setSize(int, int),或者像垃圾神建议的那样,打电话给Window.pack()

后者更好,因为pack() 在不截断内容的情况下计算窗口(框架、对话框等)可以有多小 这不是一件容易的事确定最小尺寸。

【讨论】:

  • +1 但我反对让它小于pack(),因为它考虑了 L&F。
  • 是的,回想起来我认为你是对的。 pack() 为我们工作,那么为什么要尝试第二次猜测呢?
猜你喜欢
  • 1970-01-01
  • 2016-10-10
  • 2016-11-29
  • 1970-01-01
  • 2017-03-12
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
相关资源
最近更新 更多