Reputation: 8431
I had initially built a DatePicker. A Calendar Dialog will open next to a JTextField as soon as a person clicks on the JtextField. If a person wants to type the date instead of selecting the date, then he would have first close the open dialog and then type the date.
Here's how it looks:
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);
}
}
});
}
I havent shown the DatePicker class because that's not the issue here. The issue is, it was very irritating for a person to close the Calendar dialog everytime to type the date. Instead what I wanted to do was keep a button on the side of the JtextField and only if the person clicks on the button would the dialog pop up.
But to do that I would need the DatePicker to extend a JPanel class and I could layout the JTextfield and the JButton side by side. But unfortunately, the DatePicker class extends JtextField and all over my application I am expecting DatePicker to be a JtextField. There are casts from JComponent to JTextfield and calls to get and setText() on this DatePicker.
If I have to change DatePicker to extend form JPanel then it would break my application everywhere. I was wondering if I can somehow dress up the JTextfield to show the button on the side maybe by painting it or something? Is this is possible?
Upvotes: 0
Views: 2256
Reputation: 8431
For anyone wanting to see how later on.. the code is listed below. You override paint and draw the image on the left hand corner of the text field. Then implement the mouseClicked to only response if the image has been clicked. Also implement a mouse motion listener to change the cursor to a hand pointer if its on the image and a text cursor if it is not.
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();
}
}
}
Upvotes: 0
Reputation: 109823
1) public class DateTextField extends JSpinner implements Observer {
2) JSpinner
with SpinnerDateModel
, then there no issue with parsing from/to another instance
3) use JWindow
for popup, there place 7x7 JLabels
or JButtons
Upvotes: 1
Reputation: 4907
I guess, you should override paintComponent
method and change MouseListener
a bit.
Something like this:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = (getHeight() - image.getHeight())/2;
g.drawImage(image, x, y, this);
}
and somehow track e.getX() e.getY()
coordiantes of the event in your MouseListener.
Upvotes: 1