All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.wfh.libs.common.gui.widgets.WDateTimePanel Maven / Gradle / Ivy

There is a newer version: 0.17
Show newest version
package se.wfh.libs.common.gui.widgets;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.swing.JButton;
import javax.swing.JPanel;

import se.wfh.libs.common.gui.exceptions.ChangeVetoException;
import se.wfh.libs.common.gui.widgets.datepicker.ColorTheme;
import se.wfh.libs.common.gui.widgets.events.DataChangedEvent;
import se.wfh.libs.common.gui.widgets.icons.ClearIcon;
import se.wfh.libs.common.gui.widgets.icons.OkIcon;

public class WDateTimePanel extends AbstractWPickerPanel {
	private static final long serialVersionUID = 1L;

	private final WDatePanel pnlDate;
	private final WTimePanel pnlTime;

	private ScheduledThreadPoolExecutor clock = null;
	private final WLabel lblNow;
	private final DateTimeFormatter dtf;

	public WDateTimePanel() {
		this(null);
	}

	public WDateTimePanel(final LocalDateTime defval) {
		super(defval);

		if (defval != null) {
			pnlDate = new WDatePanel(defval.toLocalDate());
			pnlTime = new WTimePanel(defval.toLocalTime());
		} else {
			pnlDate = new WDatePanel();
			pnlTime = new WTimePanel();
		}

		pnlDate.setInDateTimePanel(true);
		pnlTime.setInDateTimePanel(true);

		pnlDate.addDataChangedListener(event -> dateChanged(event));
		pnlTime.addDataChangedListener(event -> timeChanged(event));

		lblNow = new WLabel("--:--:--");
		lblNow.setOpaque(false);
		dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(
				Locale.getDefault());

		JPanel component = getComponent();
		component.setOpaque(false);

		JPanel pnlData = new JPanel(new BorderLayout());
		pnlData.setOpaque(false);
		pnlData.add(pnlDate, BorderLayout.CENTER);
		pnlData.add(pnlTime, BorderLayout.SOUTH);

		component.add(pnlData, BorderLayout.CENTER);
		component.add(createButtons(), BorderLayout.SOUTH);
	}

	private JPanel createButtons() {
		lblNow.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent event) {
				setValue(LocalDateTime.now());
			}
		});
		lblNow.setForeground(getTheme().fgTodaySelector());

		JPanel pnlBottom = new JPanel(new GridLayout(1, 2));
		JPanel pnlButtons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));

		pnlBottom.setBackground(getTheme().bgBottomPanel());

		JButton btnClear = new JButton(new ClearIcon());
		btnClear.addActionListener(event -> setValue(null));

		JButton btnOk = new JButton(new OkIcon());
		btnOk.addActionListener(event -> commitChanges());

		pnlButtons.setOpaque(false);
		pnlButtons.add(btnClear);
		pnlButtons.add(btnOk);

		pnlBottom.add(lblNow);
		pnlBottom.add(pnlButtons);
		return pnlBottom;
	}

	@Override
	protected void currentValueChanging(LocalDateTime newVal)
			throws ChangeVetoException {
		LocalDate date = null;
		LocalTime time = LocalTime.MIDNIGHT;
		if (newVal != null) {
			date = newVal.toLocalDate();
			time = newVal.toLocalTime();
		}

		pnlTime.setValue(time);
		pnlDate.setValue(date);
	}

	private void dateChanged(DataChangedEvent event) {
		LocalDate date = (LocalDate) event.getNewValue();
		LocalTime time = pnlTime.getValue();

		setValue(parseAndBuild(date, time));
	}

	@Override
	public ColorTheme getTheme() {
		return pnlDate.getTheme();
	}

	@Override
	public boolean isReadonly() {
		return pnlDate.isReadonly();
	}

	private LocalDateTime parseAndBuild(LocalDate date, LocalTime time) {
		if (date == null && time != null) {
			// only time given
			return LocalDateTime.of(LocalDate.now(), time);
		} else if (date != null && time == null) {
			// only date given
			return LocalDateTime.of(date, LocalTime.MIDNIGHT);
		} else if (date != null && time != null) {
			// both given
			return LocalDateTime.of(date, time);
		} else {
			// none given
			return null;
		}
	}

	@Override
	public void setReadonly(boolean readonly) {
		pnlDate.setReadonly(readonly);
		pnlTime.setReadonly(readonly);
	}

	@Override
	public void setTheme(ColorTheme theme) {
		pnlDate.setTheme(theme);
		pnlTime.setTheme(theme);
	}

	@Override
	public void startClock() {
		synchronized (this) {
			if (clock == null && !isInDateTimePanel()) {
				clock = new ScheduledThreadPoolExecutor(1);
				clock.scheduleAtFixedRate(
						() -> lblNow.setValue(dtf.format(LocalDateTime.now())), 0, 1,
						TimeUnit.SECONDS);
			}
		}
	}

	@Override
	public void stopClock() {
		synchronized (this) {
			if (clock != null) {
				clock.shutdown();
				clock = null;
			}
		}
	}

	private void timeChanged(DataChangedEvent event) {
		LocalDate date = pnlDate.getValue();
		LocalTime time = (LocalTime) event.getNewValue();

		setValue(parseAndBuild(date, time));
	}

	@Override
	protected void toggleClock() {
		synchronized (this) {
			if (clock == null) {
				startClock();
			} else {
				stopClock();
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy