<commit_before>package org.minimalj.frontend.page;

import java.util.List;

import org.minimalj.frontend.Frontend;
import org.minimalj.frontend.Frontend.IContent;
import org.minimalj.frontend.Frontend.ITable;
import org.minimalj.frontend.Frontend.TableActionListener;


/**
 * Shows a table of objects of one class. 
 *
 * @param <T> Class of objects in this overview
 */
public abstract class TablePage<T> extends Page implements TableActionListener<T> {

	private final Object[] keys;
	private transient ITable<T> table;
	private transient List<T> objects;
	
	/*
	 * this flag indicates if the next call of getContent should trigger a new loading
	 * of the data. A second call of getContent probably means that the user revisits
	 * the page and doesn't want to see the old data. 
	 */
	private transient boolean reloadFlag;
	
	public TablePage(Object[] keys) {
		this.keys = keys;
	}

	protected abstract List<T> load();

	@Override
	public IContent getContent() {
		table = Frontend.getInstance().createTable(keys, this);
		if (objects == null || reloadFlag) {
			objects = load();
			reloadFlag = true;
		}
		table.setObjects(objects);
		return table;
	}

	public int getResultCount() {
		if (objects == null) {
			objects = load();
			reloadFlag = false;
		}
		return objects.size();
	}
	
	public void refresh() {
		if (table != null) {
			objects = load();
			table.setObjects(objects);
			reloadFlag = false;
		}
	}
	
	public static abstract class TablePageWithDetail<T, DETAIL_PAGE extends Page> extends TablePage<T> {
		
		private DETAIL_PAGE detailPage;

		public TablePageWithDetail(Object[] keys) {
			super(keys);
		}

		protected abstract DETAIL_PAGE createDetailPage(T mainObject);

		protected abstract DETAIL_PAGE updateDetailPage(DETAIL_PAGE page, T mainObject);

		@Override
		public void action(T selectedObject) {
			if (detailPage != null) {
				updateDetailPage(selectedObject);
			} else {
				detailPage = createDetailPage(selectedObject);
				if (detailPage != null) {
					Frontend.showDetail(TablePageWithDetail.this, detailPage);
				}
			}
		}

		@Override
		public void selectionChanged(T selectedObject, List<T> selectedObjects) {
			if (detailPage != null && Frontend.isDetailShown(detailPage)) {
				updateDetailPage(selectedObject);
			}
		}
		
		private void updateDetailPage(T selectedObject) {
			DETAIL_PAGE updatedDetailPage = updateDetailPage(detailPage, selectedObject);<commit_msg>TablePageWithDetail: No error if no selection in table and open detail<commit_after>package org.minimalj.frontend.page;

import java.util.List;

import org.minimalj.frontend.Frontend;
import org.minimalj.frontend.Frontend.IContent;
import org.minimalj.frontend.Frontend.ITable;
import org.minimalj.frontend.Frontend.TableActionListener;


/**
 * Shows a table of objects of one class. 
 *
 * @param <T> Class of objects in this overview
 */
public abstract class TablePage<T> extends Page implements TableActionListener<T> {

	private final Object[] keys;
	private transient ITable<T> table;
	private transient List<T> objects;
	
	/*
	 * this flag indicates if the next call of getContent should trigger a new loading
	 * of the data. A second call of getContent probably means that the user revisits
	 * the page and doesn't want to see the old data. 
	 */
	private transient boolean reloadFlag;
	
	public TablePage(Object[] keys) {
		this.keys = keys;
	}

	protected abstract List<T> load();

	@Override
	public IContent getContent() {
		table = Frontend.getInstance().createTable(keys, this);
		if (objects == null || reloadFlag) {
			objects = load();
			reloadFlag = true;
		}
		table.setObjects(objects);
		return table;
	}

	public int getResultCount() {
		if (objects == null) {
			objects = load();
			reloadFlag = false;
		}
		return objects.size();
	}
	
	public void refresh() {
		if (table != null) {
			objects = load();
			table.setObjects(objects);
			reloadFlag = false;
		}
	}
	
	public static abstract class TablePageWithDetail<T, DETAIL_PAGE extends Page> extends TablePage<T> {
		
		private DETAIL_PAGE detailPage;

		public TablePageWithDetail(Object[] keys) {
			super(keys);
		}

		protected abstract DETAIL_PAGE createDetailPage(T mainObject);

		protected abstract DETAIL_PAGE updateDetailPage(DETAIL_PAGE page, T mainObject);

		@Override
		public void action(T selectedObject) {
			if (detailPage != null) {
				updateDetailPage(selectedObject);
			} else {
				detailPage = createDetailPage(selectedObject);
				if (detailPage != null) {
					Frontend.showDetail(TablePageWithDetail.this, detailPage);
				}
			}
		}

		@Override
		public void selectionChanged(T selectedObject, List<T> selectedObjects) {
			boolean detailVisible = detailPage != null && Frontend.isDetailShown(detailPage); 
			if (detailVisible) {
				if (selectedObject != null) {
					updateDetailPage(selectedObject);
				} else {
					Frontend.hideDetail(detailPage);
				}
			}
		}
		
		private void updateDetailPage(T selectedObject) {
			DETAIL_PAGE updatedDetailPage = updateDetailPage(detailPage, selectedObject);
{'fraction_non_alphanumeric': 0.09734337827121332, 'fraction_numerical': 0.0, 'mean_word_length': 4.1062753036437245, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4623577', 'n_tokens_mistral': 1716, 'n_tokens_neox': 1465, 'n_words': 429}