From 30c4b84d878939df3c56ae7a820088952d7fffe4 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 23 Oct 2023 17:13:09 +0200 Subject: [PATCH] [#2357] Save column width, order, and visibility in preset table --- .../preset/ComponentPresetChooserDialog.java | 8 +- .../gui/dialogs/preset/XTableColumnModel.java | 9 ++ .../net/sf/openrocket/gui/util/GUIUtil.java | 30 ------ .../openrocket/gui/util/SwingPreferences.java | 32 +++++-- .../gui/util/TableUIPreferences.java | 93 +++++++++++++++++++ 5 files changed, 133 insertions(+), 39 deletions(-) create mode 100644 swing/src/net/sf/openrocket/gui/util/TableUIPreferences.java diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index 8a6203ca9..b06123c93 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -36,6 +36,7 @@ import net.sf.openrocket.gui.adaptors.PresetModel; import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.gui.util.TableUIPreferences; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.TypedKey; @@ -52,6 +53,7 @@ import net.sf.openrocket.utils.TableRowTraversalPolicy; */ @SuppressWarnings("serial") public class ComponentPresetChooserDialog extends JDialog { + private static final String TABLE_ID = "CmpPrst."; private static final Translator trans = Application.getTranslator(); @@ -202,6 +204,8 @@ public class ComponentPresetChooserDialog extends JDialog { closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + TableUIPreferences.storeTableUIPreferences(componentSelectionTable, TABLE_ID + component.getComponentName(), + preferences.getTablePreferences()); ComponentPresetChooserDialog.this.setVisible(false); applySelectedPreset(); } @@ -214,7 +218,9 @@ public class ComponentPresetChooserDialog extends JDialog { GUIUtil.rememberWindowSize(this); this.setLocationByPlatform(true); GUIUtil.rememberWindowPosition(this); - GUIUtil.rememberTableColumnWidths(componentSelectionTable, "Presets" + component.getClass().getCanonicalName()); + + TableUIPreferences.loadTableUIPreferences(componentSelectionTable, TABLE_ID + component.getComponentName(), + preferences.getTablePreferences()); updateFilters(); } diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java index 6155fe091..a19455359 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java @@ -239,4 +239,13 @@ public class XTableColumnModel extends DefaultTableColumnModel { public TableColumn getColumn(int columnIndex, boolean onlyVisible) { return tableColumns.elementAt(columnIndex); } + + /** + * Returns an Enumeration of all columns, regardless of their visibility. + * + * @return an Enumeration of all TableColumn objects in this model + */ + public Enumeration getAllColumns() { + return allTableColumns.elements(); + } } diff --git a/swing/src/net/sf/openrocket/gui/util/GUIUtil.java b/swing/src/net/sf/openrocket/gui/util/GUIUtil.java index 2becea7c8..2eee2078d 100644 --- a/swing/src/net/sf/openrocket/gui/util/GUIUtil.java +++ b/swing/src/net/sf/openrocket/gui/util/GUIUtil.java @@ -404,36 +404,6 @@ public class GUIUtil { } } - public static void rememberTableColumnWidths(final JTable table, String keyName) { - final String key = keyName == null ? table.getClass().getName() : keyName; - Enumeration columns = table.getColumnModel().getColumns(); - while (columns.hasMoreElements()) { - TableColumn column = columns.nextElement(); - column.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals("width")) { - log.debug("Storing width of " + table.getName() + "-" + column + ": " + column.getWidth()); - ((SwingPreferences) Application.getPreferences()).setTableColumnWidth( - key, column.getModelIndex(), column.getWidth()); - } - } - }); - - final Integer width = ((SwingPreferences) Application.getPreferences()).getTableColumnWidth( - key, column.getModelIndex()); - if (width != null) { - column.setPreferredWidth(width); - } else { - column.setPreferredWidth(getOptimalColumnWidth(table, column.getModelIndex())); - } - } - } - - public static void rememberTableColumnWidths(final JTable table) { - rememberTableColumnWidths(table, null); - } - public static int getOptimalColumnWidth(JTable table, int columnIndex) { if (columnIndex >= table.getColumnModel().getColumnCount()) { return -1; diff --git a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java index f0aa48b88..e544fcd8d 100644 --- a/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java +++ b/swing/src/net/sf/openrocket/gui/util/SwingPreferences.java @@ -136,6 +136,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public Preferences getPreferences() { return PREFNODE; } + + /** + * Returns the preference node responsible for saving UI window information (position, size...) + * @return the preference node for window information + */ + public Preferences getWindowsPreferences() { + return PREFNODE.node(NODE_WINDOWS); + } + + /** + * Returns the preference node responsible for saving table information (column widths, order...) + * @return the preference node for table information + */ + public Preferences getTablePreferences() { + return PREFNODE.node(NODE_TABLES); + } public void clearPreferences() { try { @@ -550,7 +566,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public Point getWindowPosition(Class c) { int x, y; - String pref = PREFNODE.node(NODE_WINDOWS).get("position." + c.getCanonicalName(), null); + String pref = getWindowsPreferences().get("position." + c.getCanonicalName(), null); if (pref == null) return null; @@ -575,7 +591,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public void setWindowPosition(Class c, Point p) { - PREFNODE.node(NODE_WINDOWS).put("position." + c.getCanonicalName(), "" + p.x + "," + p.y); + getWindowsPreferences().put("position." + c.getCanonicalName(), "" + p.x + "," + p.y); storeVersion(); } @@ -603,7 +619,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public Dimension getWindowSize(Class c) { int x, y; - String pref = PREFNODE.node(NODE_WINDOWS).get("size." + c.getCanonicalName(), null); + String pref = getWindowsPreferences().get("size." + c.getCanonicalName(), null); if (pref == null) return null; @@ -622,22 +638,22 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { public boolean isWindowMaximized(Class c) { - String pref = PREFNODE.node(NODE_WINDOWS).get("size." + c.getCanonicalName(), null); + String pref = getWindowsPreferences().get("size." + c.getCanonicalName(), null); return "max".equals(pref); } public void setWindowSize(Class c, Dimension d) { - PREFNODE.node(NODE_WINDOWS).put("size." + c.getCanonicalName(), "" + d.width + "," + d.height); + getWindowsPreferences().put("size." + c.getCanonicalName(), "" + d.width + "," + d.height); storeVersion(); } public void setWindowMaximized(Class c) { - PREFNODE.node(NODE_WINDOWS).put("size." + c.getCanonicalName(), "max"); + getWindowsPreferences().put("size." + c.getCanonicalName(), "max"); storeVersion(); } public Integer getTableColumnWidth(String keyName, int columnIdx) { - String pref = PREFNODE.node(NODE_TABLES).get( + String pref = getTablePreferences().get( "cw." + keyName + "." + columnIdx, null); if (pref == null) return null; @@ -655,7 +671,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences { } public void setTableColumnWidth(String keyName, int columnIdx, Integer width) { - PREFNODE.node(NODE_TABLES).put( + getTablePreferences().put( "cw." + keyName + "." + columnIdx, width.toString()); storeVersion(); } diff --git a/swing/src/net/sf/openrocket/gui/util/TableUIPreferences.java b/swing/src/net/sf/openrocket/gui/util/TableUIPreferences.java new file mode 100644 index 000000000..d5887d4bb --- /dev/null +++ b/swing/src/net/sf/openrocket/gui/util/TableUIPreferences.java @@ -0,0 +1,93 @@ +package net.sf.openrocket.gui.util; + +import net.sf.openrocket.gui.dialogs.preset.XTableColumnModel; + +import javax.swing.JTable; +import javax.swing.table.TableColumn; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.prefs.Preferences; + +/** + * Utility class for storing and loading the following table UI preferences: + * - column width + * - column order + * - column visibility + */ +public class TableUIPreferences { + + private static final String TABLE_COLUMN_WIDTH_PREFIX = ".cw."; + private static final String TABLE_COLUMN_ORDER_PREFIX = ".co."; + private static final String TABLE_COLUMN_VISIBILITY_PREFIX = ".cv."; + + public static void storeTableUIPreferences(JTable table, String tableName, Preferences preferences) { + // Store column widths + for (int i = 0; i < table.getColumnCount(); i++) { + TableColumn column = table.getColumnModel().getColumn(i); + int width = column.getWidth(); + preferences.putInt(tableName + TABLE_COLUMN_WIDTH_PREFIX + column.getIdentifier(), width); + } + + // Store column order + for (int i = 0; i < table.getColumnCount(); i++) { + TableColumn column = table.getColumnModel().getColumn(i); + preferences.putInt(tableName + TABLE_COLUMN_ORDER_PREFIX + column.getIdentifier(), i); + } + + // Store column visibility + if (table.getColumnModel() instanceof XTableColumnModel customModel) { + Enumeration columns = customModel.getAllColumns(); + while (columns.hasMoreElements()) { + TableColumn column = columns.nextElement(); + boolean isVisible = customModel.isColumnVisible(column); + preferences.putBoolean(tableName + TABLE_COLUMN_VISIBILITY_PREFIX + column.getIdentifier(), isVisible); + } + } + } + + public static void loadTableUIPreferences(JTable table, String tableName, Preferences preferences) { + // Ensure all columns are visible + Enumeration allColumns = table.getColumnModel().getColumns(); + List removedColumns = new ArrayList<>(); + while (allColumns.hasMoreElements()) { + TableColumn column = allColumns.nextElement(); + if (table.convertColumnIndexToView(column.getModelIndex()) == -1) { + removedColumns.add(column); + } + } + for (TableColumn col : removedColumns) { + table.addColumn(col); + } + + // Restore column order + for (int i = 0; i < table.getColumnCount(); i++) { + TableColumn column = table.getColumnModel().getColumn(i); + int storedOrder = preferences.getInt(tableName + TABLE_COLUMN_ORDER_PREFIX + column.getIdentifier(), i); + if (storedOrder != i && storedOrder < table.getColumnCount()) { + table.moveColumn(table.convertColumnIndexToView(column.getModelIndex()), storedOrder); + } + } + + // Restore column widths + for (int i = 0; i < table.getColumnCount(); i++) { + TableColumn column = table.getColumnModel().getColumn(i); + int defaultWidth = column.getWidth(); + int width = preferences.getInt(tableName + TABLE_COLUMN_WIDTH_PREFIX + column.getIdentifier(), defaultWidth); + column.setPreferredWidth(width); + } + + // Get all columns from the table's column model + if (table.getColumnModel() instanceof XTableColumnModel customModel) { + Enumeration columns = customModel.getAllColumns(); // Use getAllColumns to get all columns, including invisible ones + + while (columns.hasMoreElements()) { + TableColumn column = columns.nextElement(); + String identifier = column.getIdentifier().toString(); + // Default to true if the preference is not found + boolean isVisible = preferences.getBoolean(tableName + TABLE_COLUMN_VISIBILITY_PREFIX + identifier, true); + customModel.setColumnVisible(column, isVisible); + } + } + } +} \ No newline at end of file