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

org.tentackle.fx.rdc.table.TablePopup Maven / Gradle / Ivy

There is a newer version: 21.16.1.0
Show newest version
/**
 * Tentackle - http://www.tentackle.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


// Created on January 31, 2003, 11:30 AM

package org.tentackle.fx.rdc.table;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.prefs.BackingStoreException;
import javafx.collections.ObservableList;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.stage.FileChooser;
import org.tentackle.fx.Fx;
import org.tentackle.fx.FxFxBundle;
import org.tentackle.fx.FxUtilities;
import org.tentackle.fx.component.FxTableView;
import org.tentackle.log.Logger;
import org.tentackle.log.LoggerFactory;
import org.tentackle.common.StringHelper;
import org.tentackle.prefs.PersistedPreferences;
import org.tentackle.prefs.PersistedPreferencesFactory;



/**
 * Table popup.
* Provides a context menu with several handy features such as export to excel, * save and load table settings, etc... * * @author harald * @param the table element type */ public class TablePopup { /** * the logger for this class. */ private static final Logger LOGGER = LoggerFactory.getLogger(TablePopup.class); private static final String EXCEL_EXTENSION = ".xls"; private static final String LAST_EXCEL_PREFIX = "/_lastExcelNames_"; private static final String EXCEL_KEY = "path"; private static final String XML_EXTENSION = ".xml"; private static final String LAST_XML_PREFIX = "/_lastXmlNames_"; private static final String XML_KEY = "path"; private final FxTableView table; // the table private final String preferencesSuffix; // suffix for the preferences private final boolean noViewSize; // true if don't set the table view's size private String title; // the title of the printed table private boolean columnMenuEnabled = true; // true if user is allowed to hide/show columns (default) /** * Creates a table popup. * * @param table the table * @param preferencesSuffix the preferences suffix to load/save table preferences * @param noViewSize true if don't set the table view's size * @param title the title of the printed table */ public TablePopup(FxTableView table, String preferencesSuffix, boolean noViewSize, String title) { this.table = table; this.preferencesSuffix = preferencesSuffix; this.noViewSize = noViewSize; this.title = title; ContextMenu menu = createContextMenu(); table.setContextMenu(menu); for (TableColumn column: table.getColumns()) { column.setContextMenu(menu); } } /** * Gets the table. * * @return the table */ public FxTableView getTable() { return table; } /** * Gets the printed title. * * @return the title */ public String getTitle() { return title; } /** * Sets the printed title. * * @param title the title for printings */ public void setTitle(String title) { this.title = title; } /** * Gets the table preferences suffix. * * @return the suffix */ public String getPreferencesSuffix() { return preferencesSuffix; } /** * Returns whether the column menu is enabled. * * @return true if column menu is enabled */ public boolean isColumnMenuEnabled() { return columnMenuEnabled; } /** * Enables or disables the column menu.
* The column menu allows to set the visibility of columns. * * @param columnMenuEnabled true to enable column menu (default) */ public void setColumnMenuEnabled(boolean columnMenuEnabled) { this.columnMenuEnabled = columnMenuEnabled; } /** * Creates the context menu. * * @return the context menu */ public ContextMenu createContextMenu() { ContextMenu menu = new ContextMenu(); ObservableList> columns = table.getColumns(); final Menu columnMenu; if (columnMenuEnabled) { // build columns-menu columnMenu = new Menu(); columnMenu.setText(FxFxBundle.getString("COLUMNS...")); menu.getItems().add(columnMenu); } else { columnMenu = null; } MenuItem autoWidthItem = new MenuItem(); autoWidthItem.setText(FxFxBundle.getString("AUTO WIDTH")); autoWidthItem.setOnAction(e -> autoWidth()); menu.getItems().add(autoWidthItem); MenuItem printItem = new MenuItem(); printItem.setText(FxFxBundle.getString("PRINT")); printItem.setOnAction(e -> print()); menu.getItems().add(printItem); MenuItem excelItem = new MenuItem(); excelItem.setText(FxFxBundle.getString("EXPORT TO EXCEL")); excelItem.setOnAction(e -> toSpreadsheet(false)); menu.getItems().add(excelItem); MenuItem selectedExcelItem = new MenuItem(); selectedExcelItem.setText(FxFxBundle.getString("EXPORT TO EXCEL (ONLY SELECTED)")); selectedExcelItem.setOnAction(e -> toSpreadsheet(true)); menu.getItems().add(selectedExcelItem); MenuItem xmlItem = new MenuItem(); xmlItem.setText(FxFxBundle.getString("EXPORT TO XML")); xmlItem.setOnAction(e -> toXml(false)); menu.getItems().add(xmlItem); MenuItem selectedXmlItem = new MenuItem(); selectedXmlItem.setText(FxFxBundle.getString("EXPORT TO XML (ONLY SELECTED)")); selectedXmlItem.setOnAction(e -> toXml(true)); menu.getItems().add(selectedXmlItem); if (PersistedPreferencesFactory.getInstance().isSystemOnly()) { if (!PersistedPreferencesFactory.getInstance().isReadOnly()) { MenuItem saveItem = new MenuItem(); saveItem.setText(FxFxBundle.getString("SAVE SYSTEM PREFERENCES")); saveItem.setOnAction(e -> savePreferences(true)); menu.getItems().add(saveItem); } MenuItem restoreItem = new MenuItem(); restoreItem.setText(FxFxBundle.getString("LOAD SYSTEM PREFERENCES")); restoreItem.setOnAction(e -> loadPreferences(true)); menu.getItems().add(restoreItem); } else { if (!PersistedPreferencesFactory.getInstance().isReadOnly()) { MenuItem saveItem = new MenuItem(); saveItem.setText(FxFxBundle.getString("SAVE USER PREFERENCES")); saveItem.setOnAction(e -> savePreferences(false)); menu.getItems().add(saveItem); } MenuItem restoreItem = new MenuItem(); restoreItem.setText(FxFxBundle.getString("LOAD USER PREFERENCES")); restoreItem.setOnAction(e -> loadPreferences(false)); menu.getItems().add(restoreItem); MenuItem restoreSysItem = new MenuItem(); restoreSysItem.setText(FxFxBundle.getString("LOAD SYSTEM PREFERENCES")); restoreSysItem.setOnAction(e -> loadPreferences(true)); menu.getItems().add(restoreSysItem); } menu.setOnShowing(event -> { if (columnMenu != null) { columnMenu.getItems().clear(); boolean allVisible = true; boolean allInvisible = true; for (TableColumn column: columns) { CheckMenuItem item = new CheckMenuItem(column.getText()); item.setSelected(column.isVisible()); if (column.isVisible()) { allInvisible = false; } else { allVisible = false; } item.setOnAction(e -> column.setVisible(item.isSelected())); columnMenu.getItems().add(item); } if (!allVisible) { MenuItem showAllItem = new MenuItem(FxFxBundle.getString("SHOW ALL")); showAllItem.setOnAction(e -> { for (TableColumn column: columns) { column.setVisible(true); } }); columnMenu.getItems().add(showAllItem); } if (!allInvisible) { MenuItem hideAllItem = new MenuItem(FxFxBundle.getString("HIDE ALL")); hideAllItem.setOnAction(e -> { for (TableColumn column: columns) { column.setVisible(false); } }); columnMenu.getItems().add(hideAllItem); } } }); return menu; } /** * Resizes all columns to fit their content. */ public void autoWidth() { FxUtilities.getInstance().resizeColumnsToFitContent(table); } /** * Prints the table. */ public void print() { TableUtilities.getInstance().print(table, title); } /** * Opens a dialog to export a table to an Excel sheet. * * @param onlySelected true if export only selected rows */ public void toSpreadsheet(boolean onlySelected) { try { // remember the pathname String prefName = StringHelper.trimRight(LAST_EXCEL_PREFIX + table.getConfiguration().getName(), '/'); PersistedPreferences prefs = PersistedPreferences.userRoot().node(prefName); String lastName = prefs.get(EXCEL_KEY, null); FileChooser fc = new FileChooser(); if (lastName != null) { fc.setInitialFileName(lastName); } fc.getExtensionFilters().addAll( new FileChooser.ExtensionFilter(FxFxBundle.getString("EXCEL FILE"), EXCEL_EXTENSION) ); File selectedFile = fc.showSaveDialog(Fx.getStage(table)); if (selectedFile != null) { if (!selectedFile.getName().toLowerCase().endsWith(EXCEL_EXTENSION)) { selectedFile = new File(selectedFile.getPath() + EXCEL_EXTENSION); } TableUtilities.getInstance().toSpreadsheet(table, selectedFile, onlySelected); if (!PersistedPreferencesFactory.getInstance().isReadOnly()) { prefs.put(EXCEL_KEY, selectedFile.getAbsolutePath()); prefs.flush(); } } // open Excel if (selectedFile != null) { final File excelFile = selectedFile; new Thread(() -> { // needs another thread because Desktop will block the FX-application thread try { LOGGER.info("launching EDIT action for {0}", excelFile); Desktop.getDesktop().edit(excelFile); } catch (UnsupportedOperationException | IOException ex) { LOGGER.info("{0} -> trying OPEN action for {1}", ex.getMessage(), excelFile); try { Desktop.getDesktop().open(excelFile); LOGGER.info("success!"); } catch (IOException ex2) { LOGGER.severe("cannot open spreadsheet file", ex2); } } }).start(); } } catch (BackingStoreException | RuntimeException ex) { LOGGER.severe("creating spreadsheet failed", ex); Fx.error(FxFxBundle.getString("COULD NOT CREATE EXCEL FILE"), ex); } } /** * Opens a dialog to export a table to an Excel sheet. * * @param onlySelected true if export only selected rows */ public void toXml(boolean onlySelected) { try { // Pfadname fuer diese Tabelle merken (immer in den userPrefs und immer abseits der normalen prefs) String prefName = StringHelper.trimRight(LAST_XML_PREFIX + table.getConfiguration().getName(), '/'); PersistedPreferences prefs = PersistedPreferences.userRoot().node(prefName); String lastName = prefs.get(XML_KEY, null); FileChooser fc = new FileChooser(); if (lastName != null) { fc.setInitialFileName(lastName); } fc.getExtensionFilters().addAll( new FileChooser.ExtensionFilter(FxFxBundle.getString("XML FILE"), XML_EXTENSION) ); File selectedFile = fc.showSaveDialog(Fx.getStage(table)); if (selectedFile != null) { if (!selectedFile.getName().toLowerCase().endsWith(XML_EXTENSION)) { selectedFile = new File(selectedFile.getPath() + XML_EXTENSION); } TableUtilities.getInstance().toXml(table, selectedFile, onlySelected); if (!PersistedPreferencesFactory.getInstance().isReadOnly()) { prefs.put(XML_KEY, selectedFile.getAbsolutePath()); prefs.flush(); } } // open XML if (selectedFile != null) { final File xmlFile = selectedFile; new Thread(() -> { // needs another thread because Desktop will block the FX-application thread try { LOGGER.info("launching EDIT action for {0}", xmlFile); Desktop.getDesktop().edit(xmlFile); } catch (UnsupportedOperationException | IOException ex) { LOGGER.info("{0} -> trying OPEN action for {1}", ex.getMessage(), xmlFile); try { Desktop.getDesktop().open(xmlFile); LOGGER.info("success!"); } catch (IOException ex2) { LOGGER.severe("cannot open XML file", ex2); } } }).start(); } } catch (BackingStoreException | RuntimeException ex) { LOGGER.severe("creating XML file failed", ex); Fx.error(FxFxBundle.getString("COULD NOT CREATE XML FILE"), ex); } } /** * Saves the table preferences. * * @param system true if system scope, else user */ public void savePreferences(boolean system) { try { table.savePreferences(preferencesSuffix, system); } catch (RuntimeException ex) { LOGGER.severe("saving table preferences failed", ex); Fx.error(FxFxBundle.getString("PREFERENCES COULD NOT BE SAVED"), ex); } } /** * Saves the table preferences.
* System- or user scope is determined from {@link PersistedPreferencesFactory}. */ public void savePreferences() { savePreferences(PersistedPreferencesFactory.getInstance().isSystemOnly()); } /** * Loads the table preferences. * * @param system true if from system scope only, else try user first */ public void loadPreferences(boolean system) { try { table.loadPreferences(preferencesSuffix, system, noViewSize); } catch (RuntimeException ex) { LOGGER.severe("loading table preferences failed", ex); Fx.error(FxFxBundle.getString("PREFERENCES COULD NOT BE LOADED"), ex); } } /** * Loads the table preferences.
* System- or user scope is determined from {@link PersistedPreferencesFactory}. */ public void loadPreferences() { loadPreferences(PersistedPreferencesFactory.getInstance().isSystemOnly()); } }