Merge pull request #2561 from SiboVG/better-ca-comp-select

Use selectable component tree for CA plot/export components selection
This commit is contained in:
Sibo Van Gool 2024-09-22 08:45:19 +02:00 committed by GitHub
commit 803935fc06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 835 additions and 851 deletions

View File

@ -715,8 +715,6 @@ SimulationStepper.error.totalMassZero = Total mass of active states is 0
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = Variables to export SimExpPan.border.Vartoexport = Variables to export
SimExpPan.border.Stage = Stage to export SimExpPan.border.Stage = Stage to export
SimExpPan.but.Selectall = Select all
SimExpPan.but.Selectnone = Select none
SimExpPan.border.FormatSettings = Format settings SimExpPan.border.FormatSettings = Format settings
SimExpPan.lbl.Fieldsepstr = Field separator string: SimExpPan.lbl.Fieldsepstr = Field separator string:
SimExpPan.lbl.longA1 = <html>The string used to separate the fields in the exported file.<br> SimExpPan.lbl.longA1 = <html>The string used to separate the fields in the exported file.<br>
@ -737,12 +735,17 @@ SimExpPan.lbl.ttip.Commentchar = The character(s) that mark a comment line.
SimExpPan.Fileexists.desc1 = File \" SimExpPan.Fileexists.desc1 = File \"
SimExpPan.Fileexists.desc2 = \" exists. Overwrite? SimExpPan.Fileexists.desc2 = \" exists. Overwrite?
SimExpPan.Fileexists.title = File exists SimExpPan.Fileexists.title = File exists
SimExpPan.ExportingVar.desc1 = Exporting 1 variable out of
SimExpPan.ExportingVar.desc2 = Exporting
SimExpPan.ExportingVar.desc3 = variables out of
SimExpPan.Col.Variable = Variable
SimExpPan.Col.Unit = Unit
! CSVExportPanel
CSVExportPanel.but.Selectall = Select all
CSVExportPanel.but.Selectnone = Select none
CSVExportPanel.ExportingVar.desc1 = Exporting 1 variable out of
CSVExportPanel.ExportingVar.desc2 = Exporting
CSVExportPanel.ExportingVar.desc3 = variables out of
CSVExportPanel.lbl.Export = Export
CSVExportPanel.lbl.Variable = Variable
CSVExportPanel.lbl.Unit = Unit
CSVExportPanel.lbl.Extra = Extra
CsvOptionPanel.separator.space = SPACE CsvOptionPanel.separator.space = SPACE
CsvOptionPanel.separator.tab = TAB CsvOptionPanel.separator.tab = TAB
@ -980,6 +983,7 @@ CAExportPanel.checkbox.ttip.Includecadesc = Include information at the beginning
CAExportPanel.dlg.MissingComponents.txt1 = The following data type(s) have no selected components and will be ignored during exporting: CAExportPanel.dlg.MissingComponents.txt1 = The following data type(s) have no selected components and will be ignored during exporting:
CAExportPanel.dlg.MissingComponents.txt2 = Do you want to continue with the export? CAExportPanel.dlg.MissingComponents.txt2 = Do you want to continue with the export?
CAExportPanel.dlg.MissingComponents.title = No components selected CAExportPanel.dlg.MissingComponents.title = No components selected
CAExportPanel.btn.SelectComponents = Select components
! CADataTypeGroup ! CADataTypeGroup
CADataTypeGroup.DOMAIN = Domain Parameter CADataTypeGroup.DOMAIN = Domain Parameter
@ -997,11 +1001,14 @@ CADomainDataType.lbl.rollrate = Roll rate
CAPlotConfiguration.TotalCD = <html>Total C<sub>D</sub> vs. Mach number</html> CAPlotConfiguration.TotalCD = <html>Total C<sub>D</sub> vs. Mach number</html>
! CAPlotTypeSelector ! CAPlotTypeSelector
CAPlotTypeSelector.lbl.component = Component: CAPlotTypeSelector.btn.SelectComponents = Select components
! CAPlotPanel ! CAPlotPanel
CAPlotPanel.lbl.PlotTitle = Component Analysis Plot CAPlotPanel.lbl.PlotTitle = Component Analysis Plot
! ComponentSelectionDialog
ComponentSelectionDialog.btn.ConfirmSelection = Confirm selection
! Custom Material dialog ! Custom Material dialog
custmatdlg.title.Custommaterial = Custom material custmatdlg.title.Custommaterial = Custom material
custmatdlg.lbl.Materialname = Material name: custmatdlg.lbl.Materialname = Material name:

View File

@ -567,8 +567,8 @@ SimulationModifierTree.OptimizationParameters = معايير التحسين
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = متغيرات للتصدير SimExpPan.border.Vartoexport = متغيرات للتصدير
SimExpPan.border.Stage = مرحلة التصدير SimExpPan.border.Stage = مرحلة التصدير
SimExpPan.but.Selectall = حدد الكل CSVExportPanel.but.Selectall = حدد الكل
SimExpPan.but.Selectnone = لا تختر شيء CSVExportPanel.but.Selectnone = لا تختر شيء
SimExpPan.border.FormatSettings = إعدادات التنسيق SimExpPan.border.FormatSettings = إعدادات التنسيق
SimExpPan.lbl.Fieldsepstr = :سلسلة فاصل المجال SimExpPan.lbl.Fieldsepstr = :سلسلة فاصل المجال
SimExpPan.lbl.longA1 = <html>.السلسلة المستخدمة لفصل الحقول في الملف المصدر<br> SimExpPan.lbl.longA1 = <html>.السلسلة المستخدمة لفصل الحقول في الملف المصدر<br>
@ -589,11 +589,11 @@ SimExpPan.lbl.ttip.Commentchar = .الذي يميز سطر التعليق (ال
SimExpPan.Fileexists.desc1 = \" الملف SimExpPan.Fileexists.desc1 = \" الملف
SimExpPan.Fileexists.desc2 = \" موجود. هل تريد الكتابة فوقه؟ SimExpPan.Fileexists.desc2 = \" موجود. هل تريد الكتابة فوقه؟
SimExpPan.Fileexists.title = الملف موجود SimExpPan.Fileexists.title = الملف موجود
SimExpPan.ExportingVar.desc1 = تصدير متغير واحد من CSVExportPanel.ExportingVar.desc1 = تصدير متغير واحد من
SimExpPan.ExportingVar.desc2 = تصدير CSVExportPanel.ExportingVar.desc2 = تصدير
SimExpPan.ExportingVar.desc3 = المتغيرات من أصل CSVExportPanel.ExportingVar.desc3 = المتغيرات من أصل
SimExpPan.Col.Variable = متغيرات CSVExportPanel.lbl.Variable = متغيرات
SimExpPan.Col.Unit = وحدة CSVExportPanel.lbl.Unit = وحدة
CsvOptionPanel.separator.space = مفتاح المساحة CsvOptionPanel.separator.space = مفتاح المساحة

View File

@ -411,8 +411,8 @@ RK4SimulationStepper.error.valuesTooLarge = Hodnoty simulace prekrocily limity.
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = Promenné k exportu SimExpPan.border.Vartoexport = Promenné k exportu
SimExpPan.but.Selectall = Oznac v\u0161e CSVExportPanel.but.Selectall = Oznac v\u0161e
SimExpPan.but.Selectnone = Nic neoznacuj CSVExportPanel.but.Selectnone = Nic neoznacuj
SimExpPan.border.Fieldsep = Oddelovac prvku SimExpPan.border.Fieldsep = Oddelovac prvku
SimExpPan.lbl.Fieldsepstr = Retezec slou\u017Eící k oddelování prvku: SimExpPan.lbl.Fieldsepstr = Retezec slou\u017Eící k oddelování prvku:
SimExpPan.lbl.longA1 = <html>Retezec slou\u017Eící k oddelení prvku v exportovaném souboru.<br> SimExpPan.lbl.longA1 = <html>Retezec slou\u017Eící k oddelení prvku v exportovaném souboru.<br>
@ -430,11 +430,11 @@ SimExpPan.but.Exporttofile = Exportuj do souboru...
SimExpPan.Fileexists.desc1 = Soubor \" SimExpPan.Fileexists.desc1 = Soubor \"
SimExpPan.Fileexists.desc2 = \" existuje. Chcete ho prepsat? SimExpPan.Fileexists.desc2 = \" existuje. Chcete ho prepsat?
SimExpPan.Fileexists.title = Soubor existuje SimExpPan.Fileexists.title = Soubor existuje
SimExpPan.ExportingVar.desc1 = Exportuji 1 promennou od CSVExportPanel.ExportingVar.desc1 = Exportuji 1 promennou od
SimExpPan.ExportingVar.desc2 = Exportuji CSVExportPanel.ExportingVar.desc2 = Exportuji
SimExpPan.ExportingVar.desc3 = promenné od CSVExportPanel.ExportingVar.desc3 = promenné od
SimExpPan.Col.Variable = Promenná CSVExportPanel.lbl.Variable = Promenná
SimExpPan.Col.Unit = Jednoty CSVExportPanel.lbl.Unit = Jednoty
CsvOptionPanel.separator.space = Mezerník CsvOptionPanel.separator.space = Mezerník

View File

@ -414,8 +414,8 @@ RK4SimulationStepper.error.valuesTooLarge = Simulationswerte
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = zu exportierende Variablen SimExpPan.border.Vartoexport = zu exportierende Variablen
SimExpPan.but.Selectall = Alle auswählen CSVExportPanel.but.Selectall = Alle auswählen
SimExpPan.but.Selectnone = Keine auswählen CSVExportPanel.but.Selectnone = Keine auswählen
SimExpPan.border.Fieldsep = Feldtrennung SimExpPan.border.Fieldsep = Feldtrennung
SimExpPan.lbl.Fieldsepstr = Trennzeichen SimExpPan.lbl.Fieldsepstr = Trennzeichen
SimExpPan.lbl.longA1 = <html>Das Trennzeichen wird benutzt, um die Felder in der exportierten Datei voneinander zu trennen.<br> SimExpPan.lbl.longA1 = <html>Das Trennzeichen wird benutzt, um die Felder in der exportierten Datei voneinander zu trennen.<br>
@ -433,11 +433,11 @@ SimExpPan.but.Exporttofile = In Datei exportieren...
SimExpPan.Fileexists.desc1 = File \"",Datei \«" SimExpPan.Fileexists.desc1 = File \"",Datei \«"
SimExpPan.Fileexists.desc2 = \" existiert bereits. Überschreiben?" SimExpPan.Fileexists.desc2 = \" existiert bereits. Überschreiben?"
SimExpPan.Fileexists.title = Datei existiert bereits SimExpPan.Fileexists.title = Datei existiert bereits
SimExpPan.ExportingVar.desc1 = Exportiere Variable 1 aus CSVExportPanel.ExportingVar.desc1 = Exportiere Variable 1 aus
SimExpPan.ExportingVar.desc2 = Exportiere CSVExportPanel.ExportingVar.desc2 = Exportiere
SimExpPan.ExportingVar.desc3 = Variablen aus CSVExportPanel.ExportingVar.desc3 = Variablen aus
SimExpPan.Col.Variable = Variable CSVExportPanel.lbl.Variable = Variable
SimExpPan.Col.Unit = Einheit CSVExportPanel.lbl.Unit = Einheit
CsvOptionPanel.separator.space = LEER CsvOptionPanel.separator.space = LEER

View File

@ -969,11 +969,11 @@ ShockCordCfg.lbl.plus = Localizaci\u00f3n:
ShockCordCfg.tab.General = General ShockCordCfg.tab.General = General
ShockCordCfg.tab.ttip.General = Propiedades generales ShockCordCfg.tab.ttip.General = Propiedades generales
SimExpPan.Col.Unit = Unidad CSVExportPanel.lbl.Unit = Unidad
SimExpPan.Col.Variable = Variable CSVExportPanel.lbl.Variable = Variable
SimExpPan.ExportingVar.desc1 = Exportar variables CSVExportPanel.ExportingVar.desc1 = Exportar variables
SimExpPan.ExportingVar.desc2 = Exportar CSVExportPanel.ExportingVar.desc2 = Exportar
SimExpPan.ExportingVar.desc3 = variables de CSVExportPanel.ExportingVar.desc3 = variables de
SimExpPan.Fileexists.desc1 = Archivo " SimExpPan.Fileexists.desc1 = Archivo "
SimExpPan.Fileexists.desc2 = " ya existe. \u00bfDesea sobrescribirlo? SimExpPan.Fileexists.desc2 = " ya existe. \u00bfDesea sobrescribirlo?
SimExpPan.Fileexists.title = El archivo ya existe SimExpPan.Fileexists.title = El archivo ya existe
@ -982,8 +982,8 @@ SimExpPan.border.Fieldsep = Separador de campo
SimExpPan.border.Stage = Etapa a exportar SimExpPan.border.Stage = Etapa a exportar
SimExpPan.border.Vartoexport = Variables para exportar SimExpPan.border.Vartoexport = Variables para exportar
SimExpPan.but.Exporttofile = Exportar al documento ... SimExpPan.but.Exporttofile = Exportar al documento ...
SimExpPan.but.Selectall = Seleccionar todo CSVExportPanel.but.Selectall = Seleccionar todo
SimExpPan.but.Selectnone = No seleccionar nada CSVExportPanel.but.Selectnone = No seleccionar nada
SimExpPan.checkbox.Incflightevents = Incluir los eventos del vuelo. SimExpPan.checkbox.Incflightevents = Incluir los eventos del vuelo.
SimExpPan.checkbox.Includefielddesc = Incluir descripciones del campo. SimExpPan.checkbox.Includefielddesc = Incluir descripciones del campo.
SimExpPan.checkbox.Includesimudesc = Incluir descripci\u00f3n de la simulaci\u00f3n. SimExpPan.checkbox.Includesimudesc = Incluir descripci\u00f3n de la simulaci\u00f3n.

View File

@ -959,11 +959,11 @@ ShockCordCfg.lbl.plus = plus
ShockCordCfg.tab.General = G\u00E9n\u00E9ral ShockCordCfg.tab.General = G\u00E9n\u00E9ral
ShockCordCfg.tab.ttip.General = Propri\u00E9t\u00E9s g\u00E9n\u00E9rales ShockCordCfg.tab.ttip.General = Propri\u00E9t\u00E9s g\u00E9n\u00E9rales
SimExpPan.Col.Unit = Unit\u00E9 CSVExportPanel.lbl.Unit = Unit\u00E9
SimExpPan.Col.Variable = Variable CSVExportPanel.lbl.Variable = Variable
SimExpPan.ExportingVar.desc1 = Exporter 1 variable sur un total de CSVExportPanel.ExportingVar.desc1 = Exporter 1 variable sur un total de
SimExpPan.ExportingVar.desc2 = Exportation CSVExportPanel.ExportingVar.desc2 = Exportation
SimExpPan.ExportingVar.desc3 = variable sur un total de CSVExportPanel.ExportingVar.desc3 = variable sur un total de
SimExpPan.Fileexists.desc1 = Le fichier " SimExpPan.Fileexists.desc1 = Le fichier "
SimExpPan.Fileexists.desc2 = " existe d\u00E9j\u00E0. Ecraser? SimExpPan.Fileexists.desc2 = " existe d\u00E9j\u00E0. Ecraser?
SimExpPan.Fileexists.title = Le fichier existe SimExpPan.Fileexists.title = Le fichier existe
@ -972,8 +972,8 @@ SimExpPan.border.Fieldsep = S\u00E9parateur de champ
SimExpPan.border.Stage = Etage \u00E0 exporter SimExpPan.border.Stage = Etage \u00E0 exporter
SimExpPan.border.Vartoexport = Variables \u00E0 exporter SimExpPan.border.Vartoexport = Variables \u00E0 exporter
SimExpPan.but.Exporttofile = Exporter dans un fichier... SimExpPan.but.Exporttofile = Exporter dans un fichier...
SimExpPan.but.Selectall = Tout s\u00E9lectionner CSVExportPanel.but.Selectall = Tout s\u00E9lectionner
SimExpPan.but.Selectnone = Ne rien s\u00E9lectionner CSVExportPanel.but.Selectnone = Ne rien s\u00E9lectionner
SimExpPan.checkbox.Incflightevents = Inclure les \u00E9v\u00E9nements de vol SimExpPan.checkbox.Incflightevents = Inclure les \u00E9v\u00E9nements de vol
SimExpPan.checkbox.Includefielddesc = Inclure les descriptions des champs SimExpPan.checkbox.Includefielddesc = Inclure les descriptions des champs
SimExpPan.checkbox.Includesimudesc = Inclure la description de la simulation SimExpPan.checkbox.Includesimudesc = Inclure la description de la simulation

View File

@ -417,8 +417,8 @@ RK4SimulationStepper.error.valuesTooLarge = I valori di simulazione anno eccedut
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = Variabili da esportare SimExpPan.border.Vartoexport = Variabili da esportare
SimExpPan.but.Selectall = Seleziona tutto CSVExportPanel.but.Selectall = Seleziona tutto
SimExpPan.but.Selectnone = Deseleziona tutto CSVExportPanel.but.Selectnone = Deseleziona tutto
SimExpPan.border.Fieldsep = Separatore di campo SimExpPan.border.Fieldsep = Separatore di campo
SimExpPan.lbl.Fieldsepstr = Stringa di separatore di campo: SimExpPan.lbl.Fieldsepstr = Stringa di separatore di campo:
SimExpPan.lbl.longA1 = <html>La stringa usata per separare i campi nel file esportato.<br> SimExpPan.lbl.longA1 = <html>La stringa usata per separare i campi nel file esportato.<br>
@ -436,11 +436,11 @@ SimExpPan.but.Exporttofile = Esporta nel file...
SimExpPan.Fileexists.desc1 = Il file \" SimExpPan.Fileexists.desc1 = Il file \"
SimExpPan.Fileexists.desc2 = \" esiste. Sovrascrivo? SimExpPan.Fileexists.desc2 = \" esiste. Sovrascrivo?
SimExpPan.Fileexists.title = Il file esiste SimExpPan.Fileexists.title = Il file esiste
SimExpPan.ExportingVar.desc1 = Sto esportando 1 variabile su CSVExportPanel.ExportingVar.desc1 = Sto esportando 1 variabile su
SimExpPan.ExportingVar.desc2 = Sto esportando CSVExportPanel.ExportingVar.desc2 = Sto esportando
SimExpPan.ExportingVar.desc3 = variabili su CSVExportPanel.ExportingVar.desc3 = variabili su
SimExpPan.Col.Variable = Variabile CSVExportPanel.lbl.Variable = Variabile
SimExpPan.Col.Unit = Unita' CSVExportPanel.lbl.Unit = Unita'
CsvOptionPanel.separator.space = SPAZIO CsvOptionPanel.separator.space = SPAZIO

View File

@ -422,8 +422,8 @@ SimulationModifierTree.OptimizationParameters = \u6700\u9069\u5316\u30D1\u30E9\
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u5909\u6570 SimExpPan.border.Vartoexport = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u5909\u6570
SimExpPan.but.Selectall = \u5168\u3066\u9078\u629E CSVExportPanel.but.Selectall = \u5168\u3066\u9078\u629E
SimExpPan.but.Selectnone = \u5168\u3066\u975E\u9078\u629E CSVExportPanel.but.Selectnone = \u5168\u3066\u975E\u9078\u629E
SimExpPan.border.Fieldsep = \u533A\u5207\u308A\u6587\u5B57 SimExpPan.border.Fieldsep = \u533A\u5207\u308A\u6587\u5B57
SimExpPan.lbl.Fieldsepstr = \u533A\u5207\u308A\u6587\u5B57\uFF1A SimExpPan.lbl.Fieldsepstr = \u533A\u5207\u308A\u6587\u5B57\uFF1A
SimExpPan.lbl.longA1 = <html>\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u30D5\u30A1\u30A4\u30EB\u3067\u306E\u533A\u5207\u308A\u6587\u5B57<br> SimExpPan.lbl.longA1 = <html>\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u30D5\u30A1\u30A4\u30EB\u3067\u306E\u533A\u5207\u308A\u6587\u5B57<br>
@ -441,11 +441,11 @@ SimExpPan.but.Exporttofile = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
SimExpPan.Fileexists.desc1 = \u30D5\u30A1\u30A4\u30EB \" SimExpPan.Fileexists.desc1 = \u30D5\u30A1\u30A4\u30EB \"
SimExpPan.Fileexists.desc2 = \" \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u307E\u3059\u304B\uFF1F SimExpPan.Fileexists.desc2 = \" \u306F\u65E2\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u307E\u3059\u304B\uFF1F
SimExpPan.Fileexists.title = \u30D5\u30A1\u30A4\u30EB\u306E\u4E0A\u66F8\u304D SimExpPan.Fileexists.title = \u30D5\u30A1\u30A4\u30EB\u306E\u4E0A\u66F8\u304D
SimExpPan.ExportingVar.desc1 = Exporting 1 variable out of CSVExportPanel.ExportingVar.desc1 = Exporting 1 variable out of
SimExpPan.ExportingVar.desc2 = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8 CSVExportPanel.ExportingVar.desc2 = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
SimExpPan.ExportingVar.desc3 = \u5909\u6570\u3001\u5168\u4F53\u306E\u5909\u6570 CSVExportPanel.ExportingVar.desc3 = \u5909\u6570\u3001\u5168\u4F53\u306E\u5909\u6570
SimExpPan.Col.Variable = \u5909\u6570 CSVExportPanel.lbl.Variable = \u5909\u6570
SimExpPan.Col.Unit = \u5358\u4F4D CSVExportPanel.lbl.Unit = \u5358\u4F4D
CsvOptionPanel.separator.space = SPACE CsvOptionPanel.separator.space = SPACE

View File

@ -541,8 +541,8 @@ SimulationModifierTree.OptimizationParameters = Optimalisatieparameters
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = Variabelen om te exporteren SimExpPan.border.Vartoexport = Variabelen om te exporteren
SimExpPan.border.Stage = Trap om te exporteren SimExpPan.border.Stage = Trap om te exporteren
SimExpPan.but.Selectall = Selecteer alles CSVExportPanel.but.Selectall = Selecteer alles
SimExpPan.but.Selectnone = Selecteer niets CSVExportPanel.but.Selectnone = Selecteer niets
SimExpPan.border.Fieldsep = Veldscheider SimExpPan.border.Fieldsep = Veldscheider
SimExpPan.lbl.Fieldsepstr = Veldscheidersteken: SimExpPan.lbl.Fieldsepstr = Veldscheidersteken:
SimExpPan.lbl.longA1 = <html>De tekenreeks die wordt gebruikt om de velden in het geëxporteerde bestand van elkaar te scheiden.<br> SimExpPan.lbl.longA1 = <html>De tekenreeks die wordt gebruikt om de velden in het geëxporteerde bestand van elkaar te scheiden.<br>
@ -559,11 +559,11 @@ SimExpPan.lbl.ttip.Commentchar = Het teken of de tekens die een opmerkingregel m
SimExpPan.Fileexists.desc1 = Bestand \" SimExpPan.Fileexists.desc1 = Bestand \"
SimExpPan.Fileexists.desc2 = \" bestaat reeds. Overschrijven? SimExpPan.Fileexists.desc2 = \" bestaat reeds. Overschrijven?
SimExpPan.Fileexists.title = Bestand bestaat reeds SimExpPan.Fileexists.title = Bestand bestaat reeds
SimExpPan.ExportingVar.desc1 = Exporteren van 1 variabele uit CSVExportPanel.ExportingVar.desc1 = Exporteren van 1 variabele uit
SimExpPan.ExportingVar.desc2 = Exporteren CSVExportPanel.ExportingVar.desc2 = Exporteren
SimExpPan.ExportingVar.desc3 = variabelen uit CSVExportPanel.ExportingVar.desc3 = variabelen uit
SimExpPan.Col.Variable = Variabele CSVExportPanel.lbl.Variable = Variabele
SimExpPan.Col.Unit = Eenheid CSVExportPanel.lbl.Unit = Eenheid
CsvOptionPanel.separator.space = SPACE CsvOptionPanel.separator.space = SPACE

View File

@ -414,8 +414,8 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = Zmienne do wyeksportowania SimExpPan.border.Vartoexport = Zmienne do wyeksportowania
SimExpPan.but.Selectall = Wybierz wszystko CSVExportPanel.but.Selectall = Wybierz wszystko
SimExpPan.but.Selectnone = Odznacz wszystko CSVExportPanel.but.Selectnone = Odznacz wszystko
SimExpPan.border.Fieldsep = Separator pól SimExpPan.border.Fieldsep = Separator pól
SimExpPan.lbl.Fieldsepstr = Ci\u0105g znaków - separator pól: SimExpPan.lbl.Fieldsepstr = Ci\u0105g znaków - separator pól:
SimExpPan.lbl.longA1 = <html>Ci\u0105g znaków stosowany do oddzielania pól w eksportowanym pliku.<br> SimExpPan.lbl.longA1 = <html>Ci\u0105g znaków stosowany do oddzielania pól w eksportowanym pliku.<br>
@ -433,11 +433,11 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
SimExpPan.Fileexists.desc1 = Plik \" SimExpPan.Fileexists.desc1 = Plik \"
SimExpPan.Fileexists.desc2 = \" istnieje. Nadpisa\u0107? SimExpPan.Fileexists.desc2 = \" istnieje. Nadpisa\u0107?
SimExpPan.Fileexists.title = Plik ju\u017C istnieje SimExpPan.Fileexists.title = Plik ju\u017C istnieje
SimExpPan.ExportingVar.desc1 = Eksportuj\u0119 1 zmienn\u0105 z CSVExportPanel.ExportingVar.desc1 = Eksportuj\u0119 1 zmienn\u0105 z
SimExpPan.ExportingVar.desc2 = Eksportuj\u0119 CSVExportPanel.ExportingVar.desc2 = Eksportuj\u0119
SimExpPan.ExportingVar.desc3 = zmienne z CSVExportPanel.ExportingVar.desc3 = zmienne z
SimExpPan.Col.Variable = Zmienna CSVExportPanel.lbl.Variable = Zmienna
SimExpPan.Col.Unit = Jednostka CSVExportPanel.lbl.Unit = Jednostka
CsvOptionPanel.separator.space = SPACJA CsvOptionPanel.separator.space = SPACJA

View File

@ -944,11 +944,11 @@ ShockCordCfg.lbl.plus = mais
ShockCordCfg.tab.General = Geral ShockCordCfg.tab.General = Geral
ShockCordCfg.tab.ttip.General = Propriedades gerais ShockCordCfg.tab.ttip.General = Propriedades gerais
SimExpPan.Col.Unit = Unidade CSVExportPanel.lbl.Unit = Unidade
SimExpPan.Col.Variable = Vari\u00e1vel CSVExportPanel.lbl.Variable = Vari\u00e1vel
SimExpPan.ExportingVar.desc1 = Exportando uma vari\u00e1vel de CSVExportPanel.ExportingVar.desc1 = Exportando uma vari\u00e1vel de
SimExpPan.ExportingVar.desc2 = Exportando CSVExportPanel.ExportingVar.desc2 = Exportando
SimExpPan.ExportingVar.desc3 = vari\u00e1veis fora de CSVExportPanel.ExportingVar.desc3 = vari\u00e1veis fora de
SimExpPan.Fileexists.desc1 = Arquivo " SimExpPan.Fileexists.desc1 = Arquivo "
SimExpPan.Fileexists.desc2 = " existe. Sobreescrever? SimExpPan.Fileexists.desc2 = " existe. Sobreescrever?
SimExpPan.Fileexists.title = Arquivo existe SimExpPan.Fileexists.title = Arquivo existe
@ -956,8 +956,8 @@ SimExpPan.border.Comments = Coment\u00e1rios
SimExpPan.border.Fieldsep = Separador de campo SimExpPan.border.Fieldsep = Separador de campo
SimExpPan.border.Vartoexport = Vari\u00e1veis para exportar SimExpPan.border.Vartoexport = Vari\u00e1veis para exportar
SimExpPan.but.Exporttofile = Exportar para arquivo... SimExpPan.but.Exporttofile = Exportar para arquivo...
SimExpPan.but.Selectall = Selecionar todos CSVExportPanel.but.Selectall = Selecionar todos
SimExpPan.but.Selectnone = Limpar sele\u00e7\u00e3o CSVExportPanel.but.Selectnone = Limpar sele\u00e7\u00e3o
SimExpPan.checkbox.Incflightevents = Incluir eventos de voo SimExpPan.checkbox.Incflightevents = Incluir eventos de voo
SimExpPan.checkbox.Includefielddesc = Incluir descri\u00e7\u00f5es de campo SimExpPan.checkbox.Includefielddesc = Incluir descri\u00e7\u00f5es de campo
SimExpPan.checkbox.Includesimudesc = Incluir a descri\u00e7\u00e3o de simula\u00e7\u00e3o SimExpPan.checkbox.Includesimudesc = Incluir a descri\u00e7\u00e3o de simula\u00e7\u00e3o

View File

@ -555,8 +555,8 @@ SimulationModifierTree.OptimizationParameters = \u041E\u043F\u0442\u0438\u043C\u
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u043C\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 SimExpPan.border.Vartoexport = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u043C\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435
SimExpPan.border.Stage = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0443\u043F\u0435\u043D\u044C SimExpPan.border.Stage = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0443\u043F\u0435\u043D\u044C
SimExpPan.but.Selectall = \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435 CSVExportPanel.but.Selectall = \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435
SimExpPan.but.Selectnone = \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0432\u044B\u0431\u043E\u0440 CSVExportPanel.but.Selectnone = \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0432\u044B\u0431\u043E\u0440
SimExpPan.border.FormatSettings = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F SimExpPan.border.FormatSettings = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F
SimExpPan.lbl.Fieldsepstr = \u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u043F\u043E\u043B\u0435\u0439: SimExpPan.lbl.Fieldsepstr = \u0420\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u043F\u043E\u043B\u0435\u0439:
SimExpPan.lbl.longA1 = <html>\u0421\u0442\u0440\u043E\u043A\u0430, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u0430\u044F \u0434\u043B\u044F \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0435\u0439 \u0432 \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u043C\u043E\u043C \u0444\u0430\u0439\u043B\u0435.<br> SimExpPan.lbl.longA1 = <html>\u0421\u0442\u0440\u043E\u043A\u0430, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u0430\u044F \u0434\u043B\u044F \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0435\u0439 \u0432 \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u043C\u043E\u043C \u0444\u0430\u0439\u043B\u0435.<br>
@ -577,11 +577,11 @@ SimExpPan.lbl.ttip.Commentchar = \u0421\u0438\u043C\u0432\u043E\u043B(\u044B), \
SimExpPan.Fileexists.desc1 = \u0424\u0430\u0439\u043B \" SimExpPan.Fileexists.desc1 = \u0424\u0430\u0439\u043B \"
SimExpPan.Fileexists.desc2 = \" \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C? SimExpPan.Fileexists.desc2 = \" \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C?
SimExpPan.Fileexists.title = \u0424\u0430\u0439\u043B \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 SimExpPan.Fileexists.title = \u0424\u0430\u0439\u043B \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
SimExpPan.ExportingVar.desc1 = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F \u043E\u0434\u043D\u0430 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F \u0438\u0437 CSVExportPanel.ExportingVar.desc1 = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F \u043E\u0434\u043D\u0430 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F \u0438\u0437
SimExpPan.ExportingVar.desc2 = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F CSVExportPanel.ExportingVar.desc2 = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F
SimExpPan.ExportingVar.desc3 = \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445 \u0438\u0437 CSVExportPanel.ExportingVar.desc3 = \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445 \u0438\u0437
SimExpPan.Col.Variable = \u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F CSVExportPanel.lbl.Variable = \u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F
SimExpPan.Col.Unit = \u0415\u0434\u0438\u043D\u0438\u0446\u0430 \u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F CSVExportPanel.lbl.Unit = \u0415\u0434\u0438\u043D\u0438\u0446\u0430 \u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F
CsvOptionPanel.separator.space = \u041F\u0440\u043E\u0431\u0435\u043B CsvOptionPanel.separator.space = \u041F\u0440\u043E\u0431\u0435\u043B

View File

@ -682,8 +682,8 @@ SimulationStepper.error.totalMassZero = \u0417\u0430\u0433\u0430\u043b\u044c\u04
! SimulationExportPanel ! SimulationExportPanel
SimExpPan.border.Vartoexport = \u0417\u043c\u0456\u043d\u043d\u0456 \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443 SimExpPan.border.Vartoexport = \u0417\u043c\u0456\u043d\u043d\u0456 \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
SimExpPan.border.Stage = \u0415\u0442\u0430\u043f \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443 SimExpPan.border.Stage = \u0415\u0442\u0430\u043f \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
SimExpPan.but.Selectall = \u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0435 CSVExportPanel.but.Selectall = \u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0435
SimExpPan.but.Selectnone = \u0412\u0456\u0434\u043c\u0456\u043d\u0438\u0442\u0438 \u0432\u0441\u0435 CSVExportPanel.but.Selectnone = \u0412\u0456\u0434\u043c\u0456\u043d\u0438\u0442\u0438 \u0432\u0441\u0435
SimExpPan.border.FormatSettings = \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0443 SimExpPan.border.FormatSettings = \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0443
SimExpPan.lbl.Fieldsepstr = \u0420\u044f\u0434\u043e\u043a \u0440\u043e\u0437\u0434\u0456\u043b\u044c\u043d\u0438\u043a\u0430 \u043f\u043e\u043b\u0456\u0432: SimExpPan.lbl.Fieldsepstr = \u0420\u044f\u0434\u043e\u043a \u0440\u043e\u0437\u0434\u0456\u043b\u044c\u043d\u0438\u043a\u0430 \u043f\u043e\u043b\u0456\u0432:
SimExpPan.lbl.longA1 = <html>\u0420\u044f\u0434\u043e\u043a, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u043b\u0456\u0432 \u0443 \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u043e\u0432\u0430\u043d\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0456.<br> SimExpPan.lbl.longA1 = <html>\u0420\u044f\u0434\u043e\u043a, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u043b\u0456\u0432 \u0443 \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u043e\u0432\u0430\u043d\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0456.<br>
@ -704,11 +704,11 @@ SimExpPan.lbl.ttip.Commentchar = \u0421\u0438\u043c\u0432\u043e\u043b(\u0438), \
SimExpPan.Fileexists.desc1 = \u0424\u0430\u0439\u043b \" SimExpPan.Fileexists.desc1 = \u0424\u0430\u0439\u043b \"
SimExpPan.Fileexists.desc2 = \" \u0456\u0441\u043d\u0443\u0454. \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438? SimExpPan.Fileexists.desc2 = \" \u0456\u0441\u043d\u0443\u0454. \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438?
SimExpPan.Fileexists.title = \u0424\u0430\u0439\u043b \u0456\u0441\u043d\u0443\u0454 SimExpPan.Fileexists.title = \u0424\u0430\u0439\u043b \u0456\u0441\u043d\u0443\u0454
SimExpPan.ExportingVar.desc1 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0437\u043c\u0456\u043d\u043d\u043e\u0457 1 \u0437 CSVExportPanel.ExportingVar.desc1 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0437\u043c\u0456\u043d\u043d\u043e\u0457 1 \u0437
SimExpPan.ExportingVar.desc2 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442 CSVExportPanel.ExportingVar.desc2 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442
SimExpPan.ExportingVar.desc3 = \u0437\u043c\u0456\u043d\u043d\u0438\u0445 \u0437 CSVExportPanel.ExportingVar.desc3 = \u0437\u043c\u0456\u043d\u043d\u0438\u0445 \u0437
SimExpPan.Col.Variable = \u0417\u043c\u0456\u043d\u043d\u0430 CSVExportPanel.lbl.Variable = \u0417\u043c\u0456\u043d\u043d\u0430
SimExpPan.Col.Unit = \u041e\u0434\u0438\u043d\u0438\u0446\u044f CSVExportPanel.lbl.Unit = \u041e\u0434\u0438\u043d\u0438\u0446\u044f
CsvOptionPanel.separator.space = \u041f\u0420\u041e\u0411\u0406\u041b CsvOptionPanel.separator.space = \u041f\u0420\u041e\u0411\u0406\u041b
CsvOptionPanel.separator.tab = \u0412\u041a\u041b\u0410\u0414\u041a\u0410 CsvOptionPanel.separator.tab = \u0412\u041a\u041b\u0410\u0414\u041a\u0410

View File

@ -1026,11 +1026,11 @@ ShockCordCfg.lbl.plus = \u52A0
ShockCordCfg.tab.General = \u5E38\u89C4 ShockCordCfg.tab.General = \u5E38\u89C4
ShockCordCfg.tab.ttip.General = \u5E38\u89C4\u5C5E\u6027 ShockCordCfg.tab.ttip.General = \u5E38\u89C4\u5C5E\u6027
SimExpPan.Col.Unit = \u5355\u4F4D CSVExportPanel.lbl.Unit = \u5355\u4F4D
SimExpPan.Col.Variable = \u53D8\u91CF CSVExportPanel.lbl.Variable = \u53D8\u91CF
SimExpPan.ExportingVar.desc1 = \u8F93\u51FA1\u4E2A\u53D8\u91CF\uFF0C\u5171\u8BA1 CSVExportPanel.ExportingVar.desc1 = \u8F93\u51FA1\u4E2A\u53D8\u91CF\uFF0C\u5171\u8BA1
SimExpPan.ExportingVar.desc2 = \u8F93\u51FA CSVExportPanel.ExportingVar.desc2 = \u8F93\u51FA
SimExpPan.ExportingVar.desc3 = \u4E2A\u53D8\u91CF, \u5171\u8BA1 CSVExportPanel.ExportingVar.desc3 = \u4E2A\u53D8\u91CF, \u5171\u8BA1
SimExpPan.Fileexists.desc1 = \u6587\u4EF6 " SimExpPan.Fileexists.desc1 = \u6587\u4EF6 "
SimExpPan.Fileexists.desc2 = " \u5DF2\u5B58\u5728. \u8986\u76D6? SimExpPan.Fileexists.desc2 = " \u5DF2\u5B58\u5728. \u8986\u76D6?
SimExpPan.Fileexists.title = \u6587\u4EF6\u5DF2\u5B58\u5728 SimExpPan.Fileexists.title = \u6587\u4EF6\u5DF2\u5B58\u5728
@ -1038,8 +1038,8 @@ SimExpPan.border.Comments = \u6CE8\u91CA
SimExpPan.border.Fieldsep = \u6570\u636E\u5206\u9694\u7B26 SimExpPan.border.Fieldsep = \u6570\u636E\u5206\u9694\u7B26
SimExpPan.border.Stage = \u5BFC\u51FA\u706B\u7BAD\u7EA7 SimExpPan.border.Stage = \u5BFC\u51FA\u706B\u7BAD\u7EA7
SimExpPan.border.Vartoexport = \u5BFC\u51FA\u53D8\u91CF SimExpPan.border.Vartoexport = \u5BFC\u51FA\u53D8\u91CF
SimExpPan.but.Selectall = \u5168\u9009 CSVExportPanel.but.Selectall = \u5168\u9009
SimExpPan.but.Selectnone = \u53D6\u6D88\u5168\u9009 CSVExportPanel.but.Selectnone = \u53D6\u6D88\u5168\u9009
SimExpPan.checkbox.Incflightevents = \u98DE\u884C\u4E8B\u4EF6 SimExpPan.checkbox.Incflightevents = \u98DE\u884C\u4E8B\u4EF6
SimExpPan.checkbox.Includefielddesc = \u6570\u636E\u57DF\u63CF\u8FF0 SimExpPan.checkbox.Includefielddesc = \u6570\u636E\u57DF\u63CF\u8FF0
SimExpPan.checkbox.Includesimudesc = \u4EFF\u771F\u63CF\u8FF0 SimExpPan.checkbox.Includesimudesc = \u4EFF\u771F\u63CF\u8FF0

View File

@ -2,7 +2,6 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
import info.openrocket.core.componentanalysis.CADataBranch; import info.openrocket.core.componentanalysis.CADataBranch;
import info.openrocket.core.componentanalysis.CADataType; import info.openrocket.core.componentanalysis.CADataType;
import info.openrocket.core.l10n.Translator;
import info.openrocket.core.rocketcomponent.RocketComponent; import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
@ -13,75 +12,122 @@ import info.openrocket.swing.gui.util.SaveCSVWorker;
import info.openrocket.swing.gui.util.SwingPreferences; import info.openrocket.swing.gui.util.SwingPreferences;
import info.openrocket.swing.gui.widgets.CSVExportPanel; import info.openrocket.swing.gui.widgets.CSVExportPanel;
import info.openrocket.swing.gui.widgets.SaveFileChooser; import info.openrocket.swing.gui.widgets.SaveFileChooser;
import net.miginfocom.swing.MigLayout;
import javax.swing.AbstractCellEditor; import javax.swing.JButton;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTable; import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.UIManager;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Dimension;
import java.awt.GridBagConstraints; import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class CAExportPanel extends CSVExportPanel<CADataType> { public class CAExportPanel extends CSVExportPanel<CADataType> {
private static final long serialVersionUID = 4423905472892675964L; private static final long serialVersionUID = 4423905472892675964L;
private static final Translator trans = Application.getTranslator(); private static final SwingPreferences prefs = (SwingPreferences) Application.getPreferences();
private static final int FIXED_COMPONENT_COLUMN_WIDTH = 500;
private final ComponentAnalysisPlotExportPanel parent;
private final Map<CADataType, List<RocketComponent>> selectedComponents = new HashMap<>();
private List<JTextArea> selectedComponentsLabels;
private List<JScrollPane> selectedComponentsScrollPanes;
private static final int OPTION_COMPONENT_ANALYSIS_COMMENTS = 0; private static final int OPTION_COMPONENT_ANALYSIS_COMMENTS = 0;
private static final int OPTION_FIELD_DESCRIPTIONS = 1; private static final int OPTION_FIELD_DESCRIPTIONS = 1;
private final List<Map<RocketComponent, Boolean>> selectedComponents; public CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types, boolean[] selected) {
private final ComponentAnalysisPlotExportPanel parent; super(types, selected,
new CsvOptionPanel(CAExportPanel.class, true,
private CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types, trans.get("CAExportPanel.checkbox.Includecadesc"),
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) { trans.get("CAExportPanel.checkbox.ttip.Includecadesc"),
super(types, selected, csvOptions, true, extraComponents); trans.get("SimExpPan.checkbox.Includefielddesc"),
trans.get("SimExpPan.checkbox.ttip.Includefielddesc")),
false);
this.parent = parent; this.parent = parent;
selectedComponents = new ArrayList<>(types.length); // Initialize selected components map
Map<RocketComponent, Boolean> componentSelectedMap; for (int i = 0; i < types.length; i++) {
List<RocketComponent> components; updateSelectedComponents(types[i], new ArrayList<>(), parent.getComponentsForType(types[i]),
for (CADataType type : types) { selectedComponentsLabels.get(i), selectedComponentsScrollPanes.get(i));
components = parent.getComponentsForType(type);
componentSelectedMap = new HashMap<>(components.size());
for (int i = 0; i < components.size(); i++) {
// Select the first component by default
componentSelectedMap.put(components.get(i), i == 0);
}
selectedComponents.add(componentSelectedMap);
} }
}
// Set row heights dynamically @Override
for (int row = 0; row < table.getRowCount(); row++) { protected Component createExtraComponent(CADataType type, int index) {
int numComponents = ((Map<?, ?>) table.getValueAt(row, 3)).size(); JPanel panel = new JPanel(new MigLayout("ins 0, fill", "[grow]", "[][]"));
double correctNumComponents = Math.ceil(numComponents / 3.0); // 3 components per row
double height = Math.round(correctNumComponents * 25) + 10; // 25 pixels per component + 10 pixel margin // Label for displaying selected components
int rowHeight = Math.max(table.getRowHeight(), (int) height); JTextArea selectedComponentsLabel = new JTextArea();
table.setRowHeight(row, rowHeight); selectedComponentsLabel.setEditable(false);
} selectedComponentsLabel.setWrapStyleWord(true);
selectedComponentsLabel.setLineWrap(true);
selectedComponentsLabel.setOpaque(false);
selectedComponentsLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.PLAIN, prefs.getUIFontSize() - 1));
JScrollPane scrollPane = new JScrollPane(selectedComponentsLabel);
scrollPane.setPreferredSize(new Dimension(200, 50)); // Adjust as needed
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollPane, "growx, wrap");
selectedComponentsLabels = selectedComponentsLabels != null ? selectedComponentsLabels : new ArrayList<>();
selectedComponentsScrollPanes = selectedComponentsScrollPanes != null ? selectedComponentsScrollPanes : new ArrayList<>();
selectedComponentsLabels.add(selectedComponentsLabel);
selectedComponentsScrollPanes.add(scrollPane);
// Select components button
JButton selectComponentsBtn = new JButton(trans.get("CAExportPanel.btn.SelectComponents"));
panel.add(selectComponentsBtn, "growx, wrap");
selectComponentsBtn.addActionListener(e -> {
List<RocketComponent> availableComponents = parent.getComponentsForType(type);
ComponentSelectionDialog dialog = new ComponentSelectionDialog(
SwingUtilities.getWindowAncestor(this),
parent.getDocument(),
availableComponents,
selectedComponents.get(type)
);
List<RocketComponent> newSelectedComponents = dialog.showDialog();
updateSelectedComponents(type, newSelectedComponents, availableComponents, selectedComponentsLabel, scrollPane);
});
return panel;
}
@Override
protected String getExtraColumnLabelKey() {
return "CAExportPanel.Col.Components";
}
private void updateSelectedComponents(CADataType type, List<RocketComponent> components,
List<RocketComponent> componentsForType, JTextArea label,
JScrollPane scrollPane) {
components = (components != null && !components.isEmpty()) ? components : componentsForType.subList(0, 1);
List<RocketComponent> selectedComponentsList = this.selectedComponents.computeIfAbsent(type, k -> new ArrayList<>());
selectedComponentsList.clear();
selectedComponentsList.addAll(components);
updateSelectedComponentsLabel(label, scrollPane, components);
}
private void updateSelectedComponentsLabel(JTextArea label, JScrollPane scrollPane, List<RocketComponent> components) {
String componentNames = components.stream()
.map(RocketComponent::getName)
.reduce((a, b) -> a + ", " + b)
.orElse("");
label.setText(componentNames);
label.setToolTipText(componentNames); // Add tooltip in case the text is too long
scrollPane.revalidate();
scrollPane.repaint();
} }
public static CAExportPanel create(ComponentAnalysisPlotExportPanel parent, CADataType[] types) { public static CAExportPanel create(ComponentAnalysisPlotExportPanel parent, CADataType[] types) {
@ -90,39 +136,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
selected[i] = ((SwingPreferences) Application.getPreferences()).isComponentAnalysisDataTypeExportSelected(types[i]); selected[i] = ((SwingPreferences) Application.getPreferences()).isComponentAnalysisDataTypeExportSelected(types[i]);
} }
CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class, false, return new CAExportPanel(parent, types, selected);
trans.get("CAExportPanel.checkbox.Includecadesc"),
trans.get("CAExportPanel.checkbox.ttip.Includecadesc"),
trans.get("SimExpPan.checkbox.Includefielddesc"),
trans.get("SimExpPan.checkbox.ttip.Includefielddesc"));
return new CAExportPanel(parent, types, selected, csvOptions);
}
protected void initializeTable(CADataType[] types) {
super.initializeTable(types);
// Set custom renderers for each column
TableColumn firstColumn = table.getColumnModel().getColumn(0);
firstColumn.setCellRenderer(new CheckBoxRenderer());
firstColumn.setCellEditor(new CheckBoxEditor());
table.getColumnModel().getColumn(1).setCellRenderer(new LeftAlignedRenderer());
table.getColumnModel().getColumn(2).setCellRenderer(new LeftAlignedRenderer());
ComponentCheckBoxPanel.ComponentSelectionListener listener = (newStates) -> {
int row = table.getSelectedRow();
if (row != -1) {
selectedComponents.set(row, newStates);
}
};
TableColumn componentColumn = table.getColumnModel().getColumn(3);
componentColumn.setCellRenderer(new ComponentCheckBoxRenderer(listener));
componentColumn.setCellEditor(new ComponentCheckBoxEditor(listener));
componentColumn.setPreferredWidth(FIXED_COMPONENT_COLUMN_WIDTH);
// Set specific client properties for FlatLaf
table.setShowHorizontalLines(true);
} }
@Override @Override
@ -133,7 +147,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
List<CADataType> typesWithNoComponents = new ArrayList<>(); List<CADataType> typesWithNoComponents = new ArrayList<>();
for (int i = 0; i < selected.length; i++) { for (int i = 0; i < selected.length; i++) {
if (selected[i]) { if (selected[i]) {
boolean hasSelectedComponent = selectedComponents.get(i).values().stream().anyMatch(v -> v); boolean hasSelectedComponent = !selectedComponents.get(i).isEmpty();
if (!hasSelectedComponent) { if (!hasSelectedComponent) {
typesWithNoComponents.add(types[i]); typesWithNoComponents.add(types[i]);
} }
@ -188,12 +202,9 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
csvOptions.storePreferences(); csvOptions.storePreferences();
// Store preferences and export // Store preferences and export
int n = 0;
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory()); ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
for (int i = 0; i < selected.length; i++) { for (int i = 0; i < selected.length; i++) {
((SwingPreferences) Application.getPreferences()).setComponentAnalysisExportSelected(types[i], selected[i]); ((SwingPreferences) Application.getPreferences()).setComponentAnalysisExportSelected(types[i], selected[i]);
if (selected[i])
n++;
} }
List<CADataType> fieldTypes = new ArrayList<>(); List<CADataType> fieldTypes = new ArrayList<>();
@ -203,12 +214,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
// Iterate through the table to get selected items // Iterate through the table to get selected items
for (int i = 0; i < selected.length; i++) { for (int i = 0; i < selected.length; i++) {
if (selected[i]) { if (selected[i]) {
List<RocketComponent> selectedComponentsList = new ArrayList<>(); List<RocketComponent> selectedComponentsList = new ArrayList<>(selectedComponents.get(i));
for (Map.Entry<RocketComponent, Boolean> entry : selectedComponents.get(i).entrySet()) {
if (entry.getValue()) {
selectedComponentsList.add(entry.getKey());
}
}
if (!selectedComponentsList.isEmpty()) { if (!selectedComponentsList.isEmpty()) {
fieldTypes.add(types[i]); fieldTypes.add(types[i]);
fieldUnits.add(units[i]); fieldUnits.add(units[i]);
@ -232,315 +238,4 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
return true; return true;
} }
@Override
protected CSVExportPanel<CADataType>.SelectionTableModel createTableModel() {
return new CASelectionTableModel();
}
protected class CASelectionTableModel extends SelectionTableModel {
private static final int COMPONENTS = 3;
@Override
public int getColumnCount() {
return 4;
}
@Override
public String getColumnName(int column) {
//// Components
if (column == COMPONENTS) {
return trans.get("CAExportPanel.Col.Components");
}
return super.getColumnName(column);
}
@Override
public Class<?> getColumnClass(int column) {
//// Components
if (column == COMPONENTS) {
return Map.class;
}
return super.getColumnClass(column);
}
@Override
public Object getValueAt(int row, int column) {
if (column == COMPONENTS) {
return selectedComponents.get(row);
}
return super.getValueAt(row, column);
}
@Override
public void setValueAt(Object value, int row, int column) {
if (column == COMPONENTS) {
selectedComponents.set(row, (Map<RocketComponent, Boolean>) value);
fireTableCellUpdated(row, column);
} else {
super.setValueAt(value, row, column);
}
}
@Override
public boolean isCellEditable(int row, int column) {
if (column == COMPONENTS) {
return true;
}
return super.isCellEditable(row, column);
}
}
private static class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
public CheckBoxRenderer() {
setHorizontalAlignment(JLabel.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setSelected((Boolean) value);
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); // Add top padding
setVerticalAlignment(JLabel.TOP);
return this;
}
}
private static class CheckBoxEditor extends DefaultCellEditor {
public CheckBoxEditor() {
super(new JCheckBox());
((JCheckBox)getComponent()).setHorizontalAlignment(JLabel.CENTER);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);
if (c instanceof JCheckBox) {
JCheckBox cb = (JCheckBox) c;
cb.setVerticalAlignment(JLabel.TOP);
cb.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
}
return c;
}
}
private static class LeftAlignedRenderer extends DefaultTableCellRenderer {
public LeftAlignedRenderer() {
setHorizontalAlignment(JLabel.LEFT);
setVerticalAlignment(JLabel.TOP);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
c.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
c.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
((JComponent) c).setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); // Add top and left padding
return c;
}
}
private static class ComponentCheckBoxRenderer implements TableCellRenderer {
private ComponentCheckBoxPanel panel;
private final ComponentCheckBoxPanel.ComponentSelectionListener listener;
public ComponentCheckBoxRenderer(ComponentCheckBoxPanel.ComponentSelectionListener listener) {
this.listener = listener;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (!(value instanceof Map)) {
JLabel errorLabel = new JLabel("Invalid data");
errorLabel.setForeground(Color.RED);
return errorLabel;
}
@SuppressWarnings("unchecked")
Map<RocketComponent, Boolean> componentMap = (Map<RocketComponent, Boolean>) value;
if (panel == null) {
panel = new ComponentCheckBoxPanel(componentMap);
panel.setComponentSelectionListener(listener);
} else {
panel.updateComponentStates(componentMap);
}
panel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
panel.setGridColor(table.getGridColor());
panel.setSelected(isSelected);
return panel;
}
}
private static class ComponentCheckBoxPanel extends JPanel {
private final Map<RocketComponent, JCheckBox> checkBoxMap = new HashMap<>();
private final AtomicBoolean updatingState = new AtomicBoolean(false);
private Color gridColor = Color.GRAY;
private boolean isSelected = false;
public ComponentCheckBoxPanel(Map<RocketComponent, Boolean> componentMap) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
createCheckBoxes(componentMap, gbc);
// Add an empty component to push everything to the top-left
gbc.gridx = 0;
gbc.gridy = (componentMap.size() + 2) / 3 + 1;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
add(new JPanel(), gbc);
// Ensure at least one checkbox is selected
if (checkBoxMap.values().stream().noneMatch(JCheckBox::isSelected) && !checkBoxMap.isEmpty()) {
checkBoxMap.values().iterator().next().setSelected(true);
}
}
private void createCheckBoxes(Map<RocketComponent, Boolean> componentMap, GridBagConstraints gbc) {
int row = 0;
int col = 0;
for (Map.Entry<RocketComponent, Boolean> entry : componentMap.entrySet()) {
RocketComponent component = entry.getKey();
Boolean isSelected = entry.getValue();
// Skip null components
if (component == null) {
continue;
}
String componentName = component.getName();
// Use a default name if getName() returns null
if (componentName == null) {
componentName = "Unnamed Component";
}
JCheckBox checkBox = new JCheckBox(componentName, isSelected != null && isSelected);
checkBox.setOpaque(false);
checkBox.setMargin(new Insets(0, 0, 0, 0));
checkBox.addItemListener(checkBoxListener);
checkBoxMap.put(component, checkBox);
gbc.gridx = col;
gbc.gridy = row;
add(checkBox, gbc);
col++;
if (col > 2) {
col = 0;
row++;
}
}
}
public void updateComponentStates(Map<RocketComponent, Boolean> newStates) {
updatingState.set(true);
try {
for (Map.Entry<RocketComponent, Boolean> entry : newStates.entrySet()) {
JCheckBox checkBox = checkBoxMap.get(entry.getKey());
if (checkBox != null) {
checkBox.setSelected(entry.getValue());
}
}
} finally {
updatingState.set(false);
}
}
public Map<RocketComponent, Boolean> getComponentStates() {
return checkBoxMap.entrySet().stream()
.collect(HashMap::new,
(m, e) -> m.put(e.getKey(), e.getValue().isSelected()),
HashMap::putAll);
}
public void setGridColor(Color color) {
this.gridColor = color;
}
public void setSelected(boolean selected) {
this.isSelected = selected;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw the bottom border
g.setColor(gridColor);
g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
// If selected, draw a slight highlight
if (isSelected) {
g.setColor(new Color(0, 0, 255, 30)); // Semi-transparent blue
g.fillRect(0, 0, getWidth(), getHeight() - 1);
}
}
public interface ComponentSelectionListener {
void onComponentSelectionChanged(Map<RocketComponent, Boolean> newStates);
}
private ComponentSelectionListener listener;
public void setComponentSelectionListener(ComponentSelectionListener listener) {
this.listener = listener;
}
private final ItemListener checkBoxListener = e -> {
if (updatingState.get()) return;
// Remove the check for deselection and forced selection
if (listener != null) {
listener.onComponentSelectionChanged(getComponentStates());
}
// Notify the table that the value has changed
firePropertyChange("value", null, getComponentStates());
};
}
private static class ComponentCheckBoxEditor extends AbstractCellEditor implements TableCellEditor {
private ComponentCheckBoxPanel panel;
private final ComponentCheckBoxPanel.ComponentSelectionListener listener;
public ComponentCheckBoxEditor(ComponentCheckBoxPanel.ComponentSelectionListener listener) {
this.listener = listener;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if (!(value instanceof Map)) {
// Return a default component if value is not a Map
JLabel errorLabel = new JLabel("Invalid data");
errorLabel.setForeground(Color.RED);
return errorLabel;
}
@SuppressWarnings("unchecked")
Map<RocketComponent, Boolean> componentMap = (Map<RocketComponent, Boolean>) value;
if (panel == null) {
panel = new ComponentCheckBoxPanel(componentMap);
panel.setComponentSelectionListener(listener);
} else {
panel.updateComponentStates(componentMap);
}
panel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return panel;
}
@Override
public Object getCellEditorValue() {
return panel.getComponentStates();
}
}
} }

View File

@ -2,11 +2,12 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
import info.openrocket.core.componentanalysis.CADataBranch; import info.openrocket.core.componentanalysis.CADataBranch;
import info.openrocket.core.componentanalysis.CADataType; import info.openrocket.core.componentanalysis.CADataType;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
import info.openrocket.swing.gui.plot.Plot; import info.openrocket.swing.gui.plot.Plot;
import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeries;
import java.util.Collections; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration> { public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration> {
@ -18,12 +19,27 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
@Override @Override
protected List<XYSeries> createSeriesForType(int dataIndex, int startIndex, CADataType type, Unit unit, protected List<XYSeries> createSeriesForType(int dataIndex, int startIndex, CADataType type, Unit unit,
CADataBranch branch, int branchIdx, String branchName, String baseName) { CADataBranch branch, int branchIdx, String branchName, String baseName) {
// Default implementation for regular DataBranch // Get the component info
MetadataXYSeries series = new MetadataXYSeries(startIndex, false, true, branchIdx, unit.getUnit(), List<RocketComponent> components = filledConfig.getComponents(dataIndex);
branchName, baseName); List<String> componentNames = filledConfig.getComponentNames(dataIndex);
// Get the component name // Create the series for each component
String componentName = filledConfig.getComponentName(dataIndex); List<XYSeries> allSeries = new ArrayList<>();
for (int i = 0; i < components.size(); i++) {
XYSeries series = createSingleSeries(startIndex*1000 + i, type, unit, branch, branchIdx, branchName, baseName,
components.get(i), componentNames.get(i));
allSeries.add(series);
}
return allSeries;
}
private XYSeries createSingleSeries(int key, CADataType type, Unit unit,
CADataBranch branch, int branchIdx, String branchName, String baseName,
RocketComponent component, String componentName) {
// Default implementation for regular DataBranch
MetadataXYSeries series = new MetadataXYSeries(key, false, true, branchIdx, unit.getUnit(),
branchName, baseName);
// Create a new description that includes the component name // Create a new description that includes the component name
String newBaseName = baseName; String newBaseName = baseName;
@ -34,7 +50,7 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
series.updateDescription(); series.updateDescription();
List<Double> plotx = branch.get(filledConfig.getDomainAxisType()); List<Double> plotx = branch.get(filledConfig.getDomainAxisType());
List<Double> ploty = branch.get(type, filledConfig.getComponent(dataIndex)); List<Double> ploty = branch.get(type, component);
int pointCount = plotx.size(); int pointCount = plotx.size();
for (int j = 0; j < pointCount; j++) { for (int j = 0; j < pointCount; j++) {
@ -43,6 +59,6 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
series.add(x, y); series.add(x, y);
} }
return Collections.singletonList(series); return series;
} }
} }

View File

@ -7,21 +7,21 @@ import info.openrocket.core.l10n.Translator;
import info.openrocket.core.rocketcomponent.RocketComponent; import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
import info.openrocket.core.util.ArrayList;
import info.openrocket.swing.gui.plot.Axis; import info.openrocket.swing.gui.plot.Axis;
import info.openrocket.swing.gui.plot.PlotConfiguration; import info.openrocket.swing.gui.plot.PlotConfiguration;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBranch> { public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBranch> {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private ArrayList<RocketComponent> plotDataComponents = new ArrayList<>(); private List<List<RocketComponent>> plotDataComponents = new ArrayList<>();
public static final CAPlotConfiguration[] DEFAULT_CONFIGURATIONS; public static final CAPlotConfiguration[] DEFAULT_CONFIGURATIONS;
static { static {
ArrayList<CAPlotConfiguration> configs = new ArrayList<>(); List<CAPlotConfiguration> configs = new ArrayList<>();
CAPlotConfiguration config; CAPlotConfiguration config;
//// Total CD vs Mach //// Total CD vs Mach
@ -53,17 +53,21 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
plotDataComponents.add(null); plotDataComponents.add(null);
} }
public RocketComponent getComponent(int index) { public List<RocketComponent> getComponents(int index) {
return plotDataComponents.get(index); return plotDataComponents.get(index);
} }
public void setPlotDataComponent(int index, RocketComponent component) { public void setPlotDataComponents(int index, List<RocketComponent> components) {
plotDataComponents.set(index, component); plotDataComponents.set(index, components);
} }
public String getComponentName(int dataIndex) { public List<String> getComponentNames(int dataIndex) {
RocketComponent component = getComponent(dataIndex); List<RocketComponent> components = getComponents(dataIndex);
return component != null ? component.getName() : ""; List<String> names = new ArrayList<>(components.size());
for (RocketComponent c : components) {
names.add(c != null ? c.getName() : "");
}
return names;
} }
@Override @Override
@ -78,8 +82,12 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
} }
Axis axis = allAxes.get(index); Axis axis = allAxes.get(index);
double min = unit.toUnit(data.get(0).getMinimum(type, getComponent(i))); double min = Double.MAX_VALUE;
double max = unit.toUnit(data.get(0).getMaximum(type, getComponent(i))); double max = Double.MIN_VALUE;
for (RocketComponent c : getComponents(i)) {
min = Math.min(min, unit.toUnit(data.get(0).getMinimum(type, c)));
max = Math.max(max, unit.toUnit(data.get(0).getMaximum(type, c)));
}
for (int j = 1; j < data.size(); j++) { for (int j = 1; j < data.size(); j++) {
// Ignore empty data // Ignore empty data
@ -98,7 +106,10 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public CAPlotConfiguration cloneConfiguration() { public CAPlotConfiguration cloneConfiguration() {
CAPlotConfiguration clone = super.cloneConfiguration(); CAPlotConfiguration clone = super.cloneConfiguration();
clone.plotDataComponents = this.plotDataComponents.clone(); clone.plotDataComponents = new ArrayList<>(plotDataComponents.size());
for (List<RocketComponent> components : plotDataComponents) {
clone.plotDataComponents.add(components != null ? new ArrayList<>(components) : null);
}
return clone; return clone;
} }
} }

View File

@ -4,7 +4,6 @@ import info.openrocket.core.componentanalysis.CADataBranch;
import info.openrocket.core.componentanalysis.CADataType; import info.openrocket.core.componentanalysis.CADataType;
import info.openrocket.core.componentanalysis.CADataTypeGroup; import info.openrocket.core.componentanalysis.CADataTypeGroup;
import info.openrocket.core.componentanalysis.CADomainDataType; import info.openrocket.core.componentanalysis.CADomainDataType;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
import info.openrocket.swing.gui.plot.PlotPanel; import info.openrocket.swing.gui.plot.PlotPanel;
@ -38,8 +37,7 @@ public class CAPlotPanel extends PlotPanel<CADataType, CADataBranch, CADataTypeG
PRESET_ARRAY[PRESET_ARRAY.length - 1] = CUSTOM_CONFIGURATION; PRESET_ARRAY[PRESET_ARRAY.length - 1] = CUSTOM_CONFIGURATION;
} }
private CAPlotPanel(ComponentAnalysisPlotExportPanel parent, private CAPlotPanel(ComponentAnalysisPlotExportPanel parent, CADomainDataType[] typesX, CADataType[] typesY) {
CADomainDataType[] typesX, CADataType[] typesY) {
super(typesX, typesY, CUSTOM_CONFIGURATION, PRESET_ARRAY, DEFAULT_CONFIGURATION, null, null); super(typesX, typesY, CUSTOM_CONFIGURATION, PRESET_ARRAY, DEFAULT_CONFIGURATION, null, null);
this.parent = parent; this.parent = parent;
@ -63,15 +61,14 @@ public class CAPlotPanel extends PlotPanel<CADataType, CADataBranch, CADataTypeG
selector.addComponentSelectionListener(e -> { selector.addComponentSelectionListener(e -> {
if (modifying > 0) return; if (modifying > 0) return;
RocketComponent component = selector.getSelectedComponent(); configuration.setPlotDataComponents(idx, selector.getSelectedComponents());
configuration.setPlotDataComponent(idx, component);
}); });
} }
@Override @Override
protected CAPlotTypeSelector createSelector(int i, CADataType type, Unit unit, int axis) { protected CAPlotTypeSelector createSelector(int i, CADataType type, Unit unit, int axis) {
return new CAPlotTypeSelector(parent, i, type, unit, axis, List.of(typesY), return new CAPlotTypeSelector(parent, parent.getDocument(), i, type, unit, axis, List.of(typesY),
parent.getComponentsForType(type), configuration, configuration.getComponent(i)); parent.getComponentsForType(type), configuration, configuration.getComponents(i));
} }
public void setXAxis(CADomainDataType type) { public void setXAxis(CADomainDataType type) {

View File

@ -2,39 +2,79 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
import info.openrocket.core.componentanalysis.CADataType; import info.openrocket.core.componentanalysis.CADataType;
import info.openrocket.core.componentanalysis.CADataTypeGroup; import info.openrocket.core.componentanalysis.CADataTypeGroup;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.rocketcomponent.RocketComponent; import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.startup.Application;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
import info.openrocket.core.util.StringUtils; import info.openrocket.core.util.StringUtils;
import info.openrocket.swing.gui.plot.PlotTypeSelector; import info.openrocket.swing.gui.plot.PlotTypeSelector;
import info.openrocket.swing.gui.util.SwingPreferences;
import net.miginfocom.swing.MigLayout;
import javax.swing.JComboBox; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ItemListener; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class CAPlotTypeSelector extends PlotTypeSelector<CADataType, CADataTypeGroup> { public class CAPlotTypeSelector extends PlotTypeSelector<CADataType, CADataTypeGroup> {
private final JComboBox<RocketComponent> componentSelector; private static final SwingPreferences prefs = (SwingPreferences) Application.getPreferences();
public CAPlotTypeSelector(final ComponentAnalysisPlotExportPanel parent, int plotIndex, private final JTextArea selectedComponentsLabel;
CADataType type, Unit unit, int position, List<CADataType> availableTypes, private final JScrollPane selectedComponentsScrollPane;
private final List<RocketComponent> selectedComponents = new ArrayList<>();
private List<RocketComponent> componentsForType;
private final List<ComponentSelectionListener> componentSelectionListeners = new ArrayList<>();
public CAPlotTypeSelector(final ComponentAnalysisPlotExportPanel parent, OpenRocketDocument document,
int plotIndex, CADataType type, Unit unit, int position, List<CADataType> availableTypes,
List<RocketComponent> componentsForType, CAPlotConfiguration configuration, List<RocketComponent> componentsForType, CAPlotConfiguration configuration,
RocketComponent selectedComponent) { List<RocketComponent> initialSelectedComponents) {
super(plotIndex, type, unit, position, availableTypes, false); super(plotIndex, type, unit, position, availableTypes, false);
if (componentsForType.isEmpty()) { // Selected components label
throw new IllegalArgumentException("No components for type " + type); selectedComponentsLabel = new JTextArea();
} selectedComponentsLabel.setEditable(false);
selectedComponentsLabel.setWrapStyleWord(true);
selectedComponentsLabel.setLineWrap(true);
selectedComponentsLabel.setOpaque(false);
selectedComponentsLabel.setFont(UIManager.getFont("Label.font").deriveFont(Font.PLAIN, prefs.getUIFontSize() - 1));
selectedComponentsScrollPane = new JScrollPane(selectedComponentsLabel);
selectedComponentsScrollPane.setPreferredSize(new Dimension(200, 60)); // Adjust as needed
selectedComponentsScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
// Update the data
setComponentsForType(type, componentsForType);
updateSelectedComponents(initialSelectedComponents, componentsForType, configuration, plotIndex);
// Component selector // Component selector
selectedComponent = selectedComponent != null ? selectedComponent : componentsForType.get(0); final JPanel componentSelectorPanel = new JPanel(new MigLayout("ins 0"));
this.add(new JLabel(trans.get("CAPlotTypeSelector.lbl.component"))); JButton selectComponentButton = new JButton(trans.get("CAPlotTypeSelector.btn.SelectComponents"));
componentSelector = new JComboBox<>(componentsForType.toArray(new RocketComponent[0])); selectComponentButton.addActionListener(new ActionListener() {
componentSelector.setSelectedItem(selectedComponent); @Override
configuration.setPlotDataComponent(plotIndex, selectedComponent); public void actionPerformed(ActionEvent e) {
this.add(componentSelector, "growx, gapright para"); ComponentSelectionDialog dialog = new ComponentSelectionDialog(parent.getParentWindow(), document,
CAPlotTypeSelector.this.componentsForType, CAPlotTypeSelector.this.selectedComponents);
List<RocketComponent> selectedComponents = dialog.showDialog();
if (selectedComponents != null) {
updateSelectedComponents(selectedComponents, CAPlotTypeSelector.this.componentsForType,
configuration, plotIndex);
}
}
});
componentSelectorPanel.add(selectComponentButton, "spanx, wrap");
componentSelectorPanel.add(selectedComponentsScrollPane, "wrap");
this.add(componentSelectorPanel, "growx, gapleft para, gapright para");
// Remove button
addRemoveButton(); addRemoveButton();
typeSelector.addActionListener(new ActionListener() { typeSelector.addActionListener(new ActionListener() {
@ -42,32 +82,65 @@ public class CAPlotTypeSelector extends PlotTypeSelector<CADataType, CADataTypeG
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
CADataType type = (CADataType) typeSelector.getSelectedItem(); CADataType type = (CADataType) typeSelector.getSelectedItem();
List<RocketComponent> componentsForType = parent.getComponentsForType(type); List<RocketComponent> componentsForType = parent.getComponentsForType(type);
componentSelector.removeAllItems(); setComponentsForType(type, componentsForType);
for (RocketComponent component : componentsForType) { updateSelectedComponents(null, componentsForType, configuration, plotIndex);
componentSelector.addItem(component);
}
componentSelector.setSelectedIndex(0);
configuration.setPlotDataComponent(plotIndex, (RocketComponent) componentSelector.getSelectedItem());
} }
}); });
} }
public CAPlotTypeSelector(final ComponentAnalysisPlotExportPanel parent, int plotIndex, private void setComponentsForType(CADataType type, List<RocketComponent> componentsForType) {
CADataType type, Unit unit, int position, List<CADataType> availableTypes, if (componentsForType.isEmpty()) {
List<RocketComponent> componentsForType, CAPlotConfiguration configuration) { throw new IllegalArgumentException("No components for type " + type);
this(parent, plotIndex, type, unit, position, availableTypes, componentsForType, configuration, null); }
this.componentsForType = componentsForType;
} }
public void addComponentSelectionListener(ItemListener listener) { private void updateSelectedComponents(List<RocketComponent> components, List<RocketComponent> componentsForType,
componentSelector.addItemListener(listener); CAPlotConfiguration configuration, int plotIndex) {
components = (components != null && !components.isEmpty()) ? components : componentsForType.subList(0, 1);
this.selectedComponents.clear();
this.selectedComponents.addAll(components);
updateSelectedComponentsLabel(this.selectedComponents);
configuration.setPlotDataComponents(plotIndex, this.selectedComponents);
notifyComponentSelectionListeners();
} }
public RocketComponent getSelectedComponent() { private void updateSelectedComponentsLabel(List<RocketComponent> components) {
return (RocketComponent) componentSelector.getSelectedItem(); List<String> names = new ArrayList<>(components.size());
for (RocketComponent c : components) {
names.add(c.getName());
}
selectedComponentsLabel.setText(StringUtils.join(", ", names));
selectedComponentsLabel.setToolTipText(StringUtils.join(", ", names)); // Add tooltip in case the text is too long
selectedComponentsScrollPane.revalidate();
selectedComponentsScrollPane.repaint();
}
public void addComponentSelectionListener(ComponentSelectionListener listener) {
componentSelectionListeners.add(listener);
}
public void removeComponentSelectionListener(ComponentSelectionListener listener) {
componentSelectionListeners.remove(listener);
}
private void notifyComponentSelectionListeners() {
for (ComponentSelectionListener listener : this.componentSelectionListeners) {
listener.componentsSelected(this.selectedComponents);
}
}
public List<RocketComponent> getSelectedComponents() {
return this.selectedComponents;
} }
@Override @Override
protected String getDisplayString(CADataType item) { protected String getDisplayString(CADataType item) {
return StringUtils.removeHTMLTags(item.getName()); return StringUtils.removeHTMLTags(item.getName());
} }
public interface ComponentSelectionListener {
void componentsSelected(List<RocketComponent> selectedComponents);
}
} }

View File

@ -1,5 +1,6 @@
package info.openrocket.swing.gui.dialogs.componentanalysis; package info.openrocket.swing.gui.dialogs.componentanalysis;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.l10n.Translator; import info.openrocket.core.l10n.Translator;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
@ -28,7 +29,7 @@ public class ComponentAnalysisDialog extends JDialog {
private JButton okButton; private JButton okButton;
public ComponentAnalysisDialog(RocketPanel rocketPanel) { public ComponentAnalysisDialog(OpenRocketDocument document, RocketPanel rocketPanel) {
//// Component analysis //// Component analysis
super(SwingUtilities.getWindowAncestor(rocketPanel), trans.get("ComponentAnalysisDialog.componentanalysis")); super(SwingUtilities.getWindowAncestor(rocketPanel), trans.get("ComponentAnalysisDialog.componentanalysis"));
@ -42,8 +43,8 @@ public class ComponentAnalysisDialog extends JDialog {
tabbedPane.addTab(trans.get("ComponentAnalysisDialog.tab.General"), generalTab); tabbedPane.addTab(trans.get("ComponentAnalysisDialog.tab.General"), generalTab);
// Plot export tab // Plot export tab
ComponentAnalysisPlotExportPanel plotExportTab = new ComponentAnalysisPlotExportPanel(this, generalTab.getParameters(), ComponentAnalysisPlotExportPanel plotExportTab = new ComponentAnalysisPlotExportPanel(this, document,
generalTab.getAerodynamicCalculator(), generalTab.getRocket()); generalTab.getParameters(), generalTab.getAerodynamicCalculator(), generalTab.getRocket());
tabbedPane.addTab(trans.get("ComponentAnalysisDialog.tab.PlotExport"), plotExportTab); tabbedPane.addTab(trans.get("ComponentAnalysisDialog.tab.PlotExport"), plotExportTab);
panel.add(tabbedPane, "span, pushy, grow, wrap"); panel.add(tabbedPane, "span, pushy, grow, wrap");
@ -94,10 +95,10 @@ public class ComponentAnalysisDialog extends JDialog {
///////// Singleton implementation ///////// Singleton implementation
public static void showDialog(RocketPanel rocketpanel) { public static void showDialog(OpenRocketDocument document, RocketPanel rocketpanel) {
if (singletonDialog != null) if (singletonDialog != null)
singletonDialog.dispose(); singletonDialog.dispose();
singletonDialog = new ComponentAnalysisDialog(rocketpanel); singletonDialog = new ComponentAnalysisDialog(document, rocketpanel);
singletonDialog.setVisible(true); singletonDialog.setVisible(true);
} }

View File

@ -6,6 +6,7 @@ import info.openrocket.core.componentanalysis.CADataType;
import info.openrocket.core.componentanalysis.CADomainDataType; import info.openrocket.core.componentanalysis.CADomainDataType;
import info.openrocket.core.componentanalysis.CAParameterSweep; import info.openrocket.core.componentanalysis.CAParameterSweep;
import info.openrocket.core.componentanalysis.CAParameters; import info.openrocket.core.componentanalysis.CAParameters;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.l10n.Translator; import info.openrocket.core.l10n.Translator;
import info.openrocket.core.rocketcomponent.Rocket; import info.openrocket.core.rocketcomponent.Rocket;
import info.openrocket.core.rocketcomponent.RocketComponent; import info.openrocket.core.rocketcomponent.RocketComponent;
@ -41,6 +42,7 @@ public class ComponentAnalysisPlotExportPanel extends JPanel implements PlotPane
private static final Logger log = LoggerFactory.getLogger(ComponentAnalysisPlotExportPanel.class); private static final Logger log = LoggerFactory.getLogger(ComponentAnalysisPlotExportPanel.class);
private final Window parent; private final Window parent;
private final OpenRocketDocument document;
private final JTabbedPane tabbedPane; private final JTabbedPane tabbedPane;
JComboBox<CADomainDataType> parameterSelector; JComboBox<CADomainDataType> parameterSelector;
private JButton okButton; private JButton okButton;
@ -62,11 +64,13 @@ public class ComponentAnalysisPlotExportPanel extends JPanel implements PlotPane
private final Map<CADataType, List<RocketComponent>> componentCache; private final Map<CADataType, List<RocketComponent>> componentCache;
private boolean isCacheValid; private boolean isCacheValid;
public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, CAParameters parameters, public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, OpenRocketDocument document,
AerodynamicCalculator aerodynamicCalculator, Rocket rocket) { CAParameters parameters, AerodynamicCalculator aerodynamicCalculator,
Rocket rocket) {
super(new MigLayout("fill, height 700px!", "[]", "[grow]")); super(new MigLayout("fill, height 700px!", "[]", "[grow]"));
this.parent = parent; this.parent = parent;
this.document = document;
this.parameters = parameters; this.parameters = parameters;
this.parameterSweep = new CAParameterSweep(parameters, aerodynamicCalculator, rocket); this.parameterSweep = new CAParameterSweep(parameters, aerodynamicCalculator, rocket);
this.componentCache = new HashMap<>(); this.componentCache = new HashMap<>();
@ -216,6 +220,10 @@ public class ComponentAnalysisPlotExportPanel extends JPanel implements PlotPane
}); });
} }
public OpenRocketDocument getDocument() {
return document;
}
public CADomainDataType getSelectedParameter() { public CADomainDataType getSelectedParameter() {
return (CADomainDataType) parameterSelector.getSelectedItem(); return (CADomainDataType) parameterSelector.getSelectedItem();
} }

View File

@ -0,0 +1,85 @@
package info.openrocket.swing.gui.dialogs.componentanalysis;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.l10n.Translator;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.startup.Application;
import info.openrocket.swing.gui.main.componenttree.SelectableComponentTree;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
public class ComponentSelectionDialog extends JDialog {
private static final Translator trans = Application.getTranslator();
private final SelectableComponentTree componentTree;
private List<RocketComponent> selectedComponents;
public ComponentSelectionDialog(Window owner, OpenRocketDocument document, List<RocketComponent> enabledComponents,
List<RocketComponent> initialSelection) {
super(owner, "Select Components", ModalityType.APPLICATION_MODAL);
// Component tree
componentTree = new SelectableComponentTree(document, enabledComponents, initialSelection);
JScrollPane scrollPane = new JScrollPane(componentTree);
// Confirm button
JButton confirmButton = new JButton(trans.get("ComponentSelectionDialog.btn.ConfirmSelection"));
confirmButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateSelectedComponents();
dispose();
}
});
// Cancel button
JButton cancelButton = new JButton(trans.get("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectedComponents = null;
dispose();
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(confirmButton);
buttonPanel.add(cancelButton);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
setSize(400, 500);
setLocationRelativeTo(owner);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
}
private void updateSelectedComponents() {
TreePath[] selectedPaths = componentTree.getSelectionPaths();
selectedComponents = new ArrayList<>();
if (selectedPaths != null) {
for (TreePath path : selectedPaths) {
Object component = path.getLastPathComponent();
if (component instanceof RocketComponent) {
selectedComponents.add((RocketComponent) component);
}
}
}
}
public List<RocketComponent> showDialog() {
setVisible(true);
return selectedComponents;
}
}

View File

@ -663,7 +663,7 @@ public class BasicFrame extends JFrame {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Component analysis selected"); log.info(Markers.USER_MARKER, "Component analysis selected");
ComponentAnalysisDialog.showDialog(rocketpanel); ComponentAnalysisDialog.showDialog(document, rocketpanel);
} }
}); });
toolsMenu.add(item); toolsMenu.add(item);

View File

@ -35,10 +35,6 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private static Color textSelectionBackgroundColor;
private static Color textSelectionForegroundColor;
private static Color componentTreeBackgroundColor;
private static Color componentTreeForegroundColor;
private static Color visibilityHiddenForegroundColor; private static Color visibilityHiddenForegroundColor;
private static Icon massOverrideSubcomponentIcon; private static Icon massOverrideSubcomponentIcon;
private static Icon massOverrideIcon; private static Icon massOverrideIcon;

View File

@ -0,0 +1,42 @@
package info.openrocket.swing.gui.main.componenttree;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.rocketcomponent.RocketComponent;
import javax.swing.tree.TreePath;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
public class SelectableComponentTree extends ComponentTree {
public SelectableComponentTree(OpenRocketDocument document, List<RocketComponent> enabledComponents,
List<RocketComponent> initialSelection) {
super(document);
Set<RocketComponent> enabledComponents1 = new HashSet<>(enabledComponents);
// Use a custom cell renderer that considers the enabled state
setCellRenderer(new SelectableComponentTreeRenderer(enabledComponents1));
// Use a custom selection model that allows toggling of selection
ToggleTreeSelectionModel selectionModel = new ToggleTreeSelectionModel();
setSelectionModel(selectionModel);
// Disable component selection for disabled components
for (RocketComponent component : document.getRocket()) {
if (!enabledComponents.contains(component)) {
TreePath path = ComponentTreeModel.makeTreePath(component);
selectionModel.addDisabledPath(path);
}
}
// Apply initial selection
selectionModel.setSelectionPath(null);
if (initialSelection != null && !initialSelection.isEmpty()) {
for (RocketComponent component : initialSelection) {
TreePath path = ComponentTreeModel.makeTreePath(component);
selectionModel.addSelectionPath(path);
}
}
}
}

View File

@ -0,0 +1,78 @@
package info.openrocket.swing.gui.main.componenttree;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.swing.gui.theme.UITheme;
import info.openrocket.swing.gui.util.GUIUtil;
import info.openrocket.swing.gui.util.Icons;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.UIManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Set;
public class SelectableComponentTreeRenderer extends ComponentTreeRenderer {
private final Set<RocketComponent> enabledComponents;
private static Color disabledTextColor;
private static Font regularFont;
private static Font italicFont;
static {
initColors();
initFonts();
}
public SelectableComponentTreeRenderer(Set<RocketComponent> enabledComponents) {
this.enabledComponents = enabledComponents;
}
private static void initColors() {
updateColors();
UITheme.Theme.addUIThemeChangeListener(SelectableComponentTreeRenderer::updateColors);
}
private static void initFonts() {
regularFont = UIManager.getFont("Tree.font");
italicFont = regularFont.deriveFont(Font.ITALIC);
}
private static void updateColors() {
disabledTextColor = GUIUtil.getUITheme().getDisabledTextColor();
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean sel, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component rendererComponent = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof RocketComponent component) {
boolean isEnabled = enabledComponents.contains(component);
rendererComponent.setEnabled(isEnabled);
if (rendererComponent instanceof JPanel panel) {
for (Component c : panel.getComponents()) {
if (c instanceof JLabel label) {
if (!isEnabled) {
label.setForeground(disabledTextColor);
label.setFont(italicFont);
Icon icon = label.getIcon();
if (icon != null) {
label.setIcon(Icons.createDisabledIcon(icon));
}
} else {
label.setFont(regularFont);
}
}
}
}
}
return rendererComponent;
}
}

View File

@ -0,0 +1,53 @@
package info.openrocket.swing.gui.main.componenttree;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import java.util.HashSet;
import java.util.Set;
public class ToggleTreeSelectionModel extends DefaultTreeSelectionModel {
private final Set<TreePath> disabledPaths;
public ToggleTreeSelectionModel() {
setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
disabledPaths = new HashSet<>();
}
@Override
public void setSelectionPath(TreePath path) {
if (isPathEnabled(path)) {
if (isPathSelected(path)) {
removeSelectionPath(path);
} else {
addSelectionPath(path);
}
}
}
@Override
public void addSelectionPath(TreePath path) {
if (isPathEnabled(path)) {
super.addSelectionPath(path);
}
}
@Override
public void removeSelectionPath(TreePath path) {
if (isPathEnabled(path)) {
super.removeSelectionPath(path);
}
}
public void addDisabledPath(TreePath path) {
disabledPaths.add(path);
removeSelectionPath(path);
}
public void removeDisabledPath(TreePath path) {
disabledPaths.remove(path);
}
public boolean isPathEnabled(TreePath path) {
return !disabledPaths.contains(path);
}
}

View File

@ -52,19 +52,19 @@ public class PlotTypeSelector<T extends Groupable<G> & UnitValue, G extends Grou
} }
}; };
typeSelector.setSelectedItem(type); typeSelector.setSelectedItem(type);
this.add(typeSelector, "gapright para"); this.add(typeSelector, "gapright para, top");
this.add(new JLabel("Unit:")); this.add(new JLabel("Unit:"), "top");
unitSelector = new UnitSelector(type.getUnitGroup()); unitSelector = new UnitSelector(type.getUnitGroup());
if (unit != null) { if (unit != null) {
unitSelector.setSelectedUnit(unit); unitSelector.setSelectedUnit(unit);
} }
this.add(unitSelector, "width 40lp, gapright para"); this.add(unitSelector, "width 40lp, gapright para, top");
this.add(new JLabel("Axis:")); this.add(new JLabel("Axis:"), "top");
axisSelector = new JComboBox<>(POSITIONS); axisSelector = new JComboBox<>(POSITIONS);
axisSelector.setSelectedIndex(position + 1); axisSelector.setSelectedIndex(position + 1);
this.add(axisSelector); this.add(axisSelector, "top");
removeButton = new JButton(Icons.EDIT_DELETE); removeButton = new JButton(Icons.EDIT_DELETE);
removeButton.setToolTipText("Remove this plot"); removeButton.setToolTipText("Remove this plot");
@ -79,7 +79,7 @@ public class PlotTypeSelector<T extends Groupable<G> & UnitValue, G extends Grou
} }
protected void addRemoveButton() { protected void addRemoveButton() {
this.add(removeButton, "gapright 0"); this.add(removeButton, "gapright 0, top");
} }
public int getIndex() { public int getIndex() {

View File

@ -44,7 +44,7 @@ public class SimulationExportPanel extends CSVExportPanel<FlightDataType> {
private SimulationExportPanel(Simulation simulation, FlightDataBranch branch, FlightDataType[] types, private SimulationExportPanel(Simulation simulation, FlightDataBranch branch, FlightDataType[] types,
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) { boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
super(types, selected, csvOptions, extraComponents); super(types, selected, csvOptions, false, extraComponents);
this.simulation = simulation; this.simulation = simulation;
this.branch = branch; this.branch = branch;
} }
@ -165,4 +165,9 @@ public class SimulationExportPanel extends CSVExportPanel<FlightDataType> {
return true; return true;
} }
@Override
protected String getDisplayName(FlightDataType type) {
return type.getName();
}
} }

View File

@ -1041,7 +1041,7 @@ public class UITheme {
@Override @Override
public Color getDisabledTextColor() { public Color getDisabledTextColor() {
return new Color(128, 128, 128); return new Color(128, 128, 128, 223);
} }

View File

@ -7,11 +7,13 @@ import info.openrocket.core.startup.Application;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.swing.GrayFilter;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Image; import java.awt.Image;
import java.awt.image.BufferedImage;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -183,4 +185,13 @@ public class Icons {
} }
}; };
} }
public static Icon createDisabledIcon(Icon icon) {
Image image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
return new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) icon).getImage()));
}
} }

View File

@ -3,334 +3,240 @@ package info.openrocket.swing.gui.widgets;
import info.openrocket.core.l10n.Translator; import info.openrocket.core.l10n.Translator;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.unit.Unit; import info.openrocket.core.unit.Unit;
import info.openrocket.core.unit.UnitGroup;
import info.openrocket.core.util.UnitValue; import info.openrocket.core.util.UnitValue;
import info.openrocket.swing.gui.components.CsvOptionPanel; import info.openrocket.swing.gui.components.CsvOptionPanel;
import info.openrocket.swing.gui.components.UnitCellEditor; import info.openrocket.swing.gui.components.UnitSelector;
import info.openrocket.swing.gui.theme.UITheme;
import info.openrocket.swing.gui.util.GUIUtil; import info.openrocket.swing.gui.util.GUIUtil;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel; import java.awt.Color;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.Component; import java.awt.Component;
import java.awt.event.ActionEvent; import java.awt.Dimension;
import java.awt.event.ActionListener; import java.awt.GridBagConstraints;
import java.lang.reflect.ParameterizedType; import java.awt.GridBagLayout;
import java.lang.reflect.Type; import java.awt.Insets;
import java.util.Arrays; import java.util.ArrayList;
import java.util.List;
public class CSVExportPanel<T extends UnitValue> extends JPanel { public class CSVExportPanel<T extends UnitValue> extends JPanel {
private static final Translator trans = Application.getTranslator(); private static final long serialVersionUID = 1L;
protected static final Translator trans = Application.getTranslator();
protected static final String SPACE = "SPACE"; protected static final String SPACE = "SPACE";
protected static final String TAB = "TAB"; protected static final String TAB = "TAB";
private static Color ALTERNATE_ROW_COLOR;
protected final JTable table; protected final List<DataTypeRow> dataTypeRows = new ArrayList<>();
protected final SelectionTableModel tableModel;
private final JLabel selectedCountLabel;
protected final boolean[] selected;
protected final T[] types;
protected final Unit[] units;
protected final CsvOptionPanel csvOptions; protected final CsvOptionPanel csvOptions;
protected final JLabel selectedCountLabel;
public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, boolean separateRowForTable, Component... extraComponents) { protected final T[] types;
super(new MigLayout("fill, flowy")); protected boolean[] selected;
protected Unit[] units;
static {
initColors();
}
public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, boolean separateRowForOptions,
Component... extraComponents) {
super(new MigLayout("fill, wrap 2", "[grow,fill][]", "[grow,fill][]"));
this.types = types; this.types = types;
this.selected = selected; this.selected = selected;
this.csvOptions = csvOptions; this.csvOptions = csvOptions;
this.units = new Unit[types.length]; this.units = new Unit[types.length];
for (int i = 0; i < types.length; i++) { for (int i = 0; i < types.length; i++) {
units[i] = types[i].getUnitGroup().getDefaultUnit(); units[i] = types[i].getUnitGroup().getDefaultUnit();
} }
//// Create the panel JPanel exportPanel = new JPanel(new MigLayout("ins 0, fill"));
JPanel panel;
JButton button;
// Set up the variable selection table boolean addExtras = createExtraComponent(types[0], 0) != null;
tableModel = createTableModel(); JPanel contentPanel = new JPanel(new GridBagLayout());
table = new JTable(tableModel); contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
initializeTable(types); GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0, 0, 0, 0); // No padding
c.fill = GridBagConstraints.BOTH;
// Add table // Header
panel = new JPanel(new MigLayout("fill")); c.gridy = 0;
panel.setBorder(BorderFactory.createTitledBorder(trans.get("SimExpPan.border.Vartoexport"))); c.weightx = 0;
addHeaderRowLabel(contentPanel, "CSVExportPanel.lbl.Export", c, 0);
c.weightx = 1;
addHeaderRowLabel(contentPanel, "CSVExportPanel.lbl.Variable", c, 1);
c.weightx = 0;
addHeaderRowLabel(contentPanel, "CSVExportPanel.lbl.Unit", c, 2);
if (addExtras) {
c.weightx = 1;
addHeaderRowLabel(contentPanel, getExtraColumnLabelKey(), c, 3);
}
panel.add(new JScrollPane(table), "wmin 300lp, width 300lp, pushy, grow 100, wrap"); // Data rows
for (int i = 0; i < types.length; i++) {
DataTypeRow row = new DataTypeRow(types[i], selected[i], units[i], i);
dataTypeRows.add(row);
Color bgColor = i % 2 == 0 ? UIManager.getColor("Table.background") : ALTERNATE_ROW_COLOR;
c.gridy = i + 1;
addDataRowWidget(contentPanel, row.exportCheckBox, c, bgColor, 0);
addDataRowWidget(contentPanel, row.nameLabel, c, bgColor, 1);
addDataRowWidget(contentPanel, row.unitSelector, c, bgColor, 2);
if (addExtras) {
addDataRowWidget(contentPanel, createExtraComponent(types[i], i), c, bgColor, 3);
}
}
JScrollPane scrollPane = new JScrollPane(contentPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(300, 400));
exportPanel.add(scrollPane, "grow, wrap");
// Select all/none buttons // Select all/none buttons
button = new JButton(trans.get("SimExpPan.but.Selectall")); JPanel buttonPanel = new JPanel(new MigLayout("insets 0"));
button.addActionListener(new ActionListener() { JButton selectAllButton = new JButton(trans.get("CSVExportPanel.but.Selectall"));
@Override selectAllButton.addActionListener(e -> selectAll());
public void actionPerformed(ActionEvent e) { buttonPanel.add(selectAllButton, "split 2, growx");
tableModel.selectAll();
}
});
panel.add(button, "split 2, growx 1, sizegroup selectbutton");
button = new JButton(trans.get("SimExpPan.but.Selectnone")); JButton selectNoneButton = new JButton(trans.get("CSVExportPanel.but.Selectnone"));
button.addActionListener(new ActionListener() { selectNoneButton.addActionListener(e -> selectNone());
@Override buttonPanel.add(selectNoneButton, "growx");
public void actionPerformed(ActionEvent e) {
tableModel.selectNone();
}
});
panel.add(button, "growx 1, sizegroup selectbutton, wrap");
exportPanel.add(buttonPanel, "growx, wrap");
// Exporting xx variables out of yy // Selected count label
selectedCountLabel = new JLabel(); selectedCountLabel = new JLabel();
updateSelectedCount(); updateSelectedCount();
panel.add(selectedCountLabel); exportPanel.add(selectedCountLabel, "growx");
add(exportPanel, "grow, gapright para" + (separateRowForOptions ? ", spanx, wrap" : ""));
if (separateRowForTable) { // CSV options and extra components
this.add(panel, "spanx, grow 100, wrap"); if (separateRowForOptions) {
} else { add(csvOptions, "growx");
this.add(panel, "grow 100, wrap"); for (Component comp : extraComponents) {
} add(comp, "growx, top");
// Add CSV options
if (separateRowForTable) {
this.add(csvOptions, "grow 1");
} else {
this.add(csvOptions, "spany, split, growx 1");
}
//// Add extra widgets
if (extraComponents != null) {
for (Component c : extraComponents) {
if (separateRowForTable) {
this.add(c, "grow 1");
} else {
this.add(c, "spany, split, growx 1");
}
} }
} } else {
JPanel optionsPanel = new JPanel(new MigLayout("insets 0"));
// Space-filling panel optionsPanel.add(csvOptions, "growx");
if (!separateRowForTable) { for (Component comp : extraComponents) {
panel = new JPanel(); optionsPanel.add(comp, "growx");
this.add(panel, "width 1, height 1, grow 1");
}
}
public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
this(types, selected, csvOptions, false, extraComponents);
}
protected SelectionTableModel createTableModel() {
return new SelectionTableModel();
}
protected void initializeTable(T[] types) {
table.setDefaultRenderer(Object.class,
new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Object.class)));
table.setDefaultRenderer(Boolean.class,
new SelectionBackgroundCellRenderer(table.getDefaultRenderer(Boolean.class)));
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(false);
table.setDefaultEditor(Unit.class, new UnitCellEditor() {
private static final long serialVersionUID = 1088570433902420935L;
@Override
protected UnitGroup getUnitGroup(Unit value, int row, int column) {
return types[row].getUnitGroup();
} }
}); add(optionsPanel, "growx, top");
}
// Set column widths
TableColumnModel columnModel = table.getColumnModel();
TableColumn col = columnModel.getColumn(0);
int w = table.getRowHeight();
col.setMinWidth(w);
col.setPreferredWidth(w);
col.setMaxWidth(w);
col = columnModel.getColumn(1);
col.setPreferredWidth(200);
col = columnModel.getColumn(2);
col.setPreferredWidth(100);
table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
} }
public boolean doExport() { private static void initColors() {
throw new RuntimeException("Not implemented"); updateColors();
UITheme.Theme.addUIThemeChangeListener(CSVExportPanel::updateColors);
} }
private void updateSelectedCount() { private static void updateColors() {
ALTERNATE_ROW_COLOR = GUIUtil.getUITheme().getRowBackgroundLighterColor();
}
private void addHeaderRowLabel(JPanel contentPanel, String lblKey, GridBagConstraints c, int x) {
c.gridx = x;
JPanel panel = new JPanel(new MigLayout("fill, ins 4 5 4 5"));
panel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIManager.getColor("Table.gridColor")));
panel.add(new JLabel("<html><b>" + trans.get(lblKey) + "</b></html>"), "growx");
contentPanel.add(panel, c);
}
private void addDataRowWidget(JPanel contentPanel, Component widget, GridBagConstraints c, Color bgColor, int x) {
c.gridx = x;
JPanel panel = new JPanel(new MigLayout("fill, ins 4 5 4 5"));
panel.setBackground(bgColor);
if (widget instanceof JPanel) {
widget.setBackground(bgColor);
}
panel.add(widget, "growx");
contentPanel.add(panel, c);
}
protected String getExtraColumnLabelKey() {
return "CSVExportPanel.lbl.Extra";
}
protected Component createExtraComponent(T type, int index) {
return null;
}
protected class DataTypeRow {
final JCheckBox exportCheckBox;
final JLabel nameLabel;
final UnitSelector unitSelector;
final int index;
DataTypeRow(T type, boolean isSelected, Unit unit, int index) {
this.index = index;
exportCheckBox = new JCheckBox();
exportCheckBox.setSelected(isSelected);
exportCheckBox.addActionListener(e -> {
selected[index] = exportCheckBox.isSelected();
updateSelectedCount();
});
nameLabel = new JLabel(getDisplayName(type));
unitSelector = new UnitSelector(type.getUnitGroup());
unitSelector.setSelectedUnit(unit);
unitSelector.addItemListener(e -> units[index] = unitSelector.getSelectedUnit());
}
}
protected String getDisplayName(T type) {
return type.toString();
}
protected void selectAll() {
for (DataTypeRow row : dataTypeRows) {
row.exportCheckBox.setSelected(true);
selected[row.index] = true;
}
updateSelectedCount();
}
protected void selectNone() {
for (DataTypeRow row : dataTypeRows) {
row.exportCheckBox.setSelected(false);
selected[row.index] = false;
}
updateSelectedCount();
}
protected void updateSelectedCount() {
int total = selected.length; int total = selected.length;
int n = 0; int n = 0;
String str;
for (boolean b : selected) { for (boolean b : selected) {
if (b) if (b) n++;
n++;
} }
String str;
if (n == 1) { if (n == 1) {
//// Exporting 1 variable out of str = trans.get("CSVExportPanel.ExportingVar.desc1") + " " + total + ".";
str = trans.get("SimExpPan.ExportingVar.desc1") + " " + total + ".";
} else { } else {
//// Exporting str = trans.get("CSVExportPanel.ExportingVar.desc2") + " " + n + " " +
//// variables out of trans.get("CSVExportPanel.ExportingVar.desc3") + " " + total + ".";
str = trans.get("SimExpPan.ExportingVar.desc2") + " " + n + " " +
trans.get("SimExpPan.ExportingVar.desc3") + " " + total + ".";
} }
selectedCountLabel.setText(str); selectedCountLabel.setText(str);
} }
/** public boolean doExport() {
* The table model for the variable selection. throw new UnsupportedOperationException("Export not implemented in base class");
*/
protected class SelectionTableModel extends AbstractTableModel {
private static final long serialVersionUID = 493067422917621072L;
protected static final int SELECTED = 0;
protected static final int NAME = 1;
protected static final int UNIT = 2;
@Override
public int getColumnCount() {
return 3;
}
@Override
public int getRowCount() {
return types.length;
}
@Override
public String getColumnName(int column) {
return switch (column) {
case SELECTED -> "";
case NAME ->
//// Variable
trans.get("SimExpPan.Col.Variable");
case UNIT ->
//// Unit
trans.get("SimExpPan.Col.Unit");
default -> throw new IndexOutOfBoundsException("column=" + column);
};
}
@Override
public Class<?> getColumnClass(int column) {
return switch (column) {
case SELECTED -> Boolean.class;
case NAME -> new TypeToken<T>(){}.getType().getClass();
case UNIT -> Unit.class;
default -> throw new IndexOutOfBoundsException("column=" + column);
};
}
@Override
public Object getValueAt(int row, int column) {
return switch (column) {
case SELECTED -> selected[row];
case NAME -> types[row];
case UNIT -> units[row];
default -> throw new IndexOutOfBoundsException("column=" + column);
};
}
@Override
public void setValueAt(Object value, int row, int column) {
switch (column) {
case SELECTED:
selected[row] = (Boolean) value;
this.fireTableRowsUpdated(row, row);
updateSelectedCount();
break;
case NAME:
break;
case UNIT:
units[row] = (Unit) value;
break;
default:
throw new IndexOutOfBoundsException("column=" + column);
}
}
@Override
public boolean isCellEditable(int row, int column) {
return switch (column) {
case SELECTED -> true;
case NAME -> false;
case UNIT -> types[row].getUnitGroup().getUnitCount() > 1;
default -> throw new IndexOutOfBoundsException("column=" + column);
};
}
public void selectAll() {
Arrays.fill(selected, true);
updateSelectedCount();
this.fireTableDataChanged();
}
public void selectNone() {
Arrays.fill(selected, false);
updateSelectedCount();
this.fireTableDataChanged();
}
} }
}
/**
* A table cell renderer that uses another renderer and sets the background and
* foreground of the returned component based on the selection of the variable.
*/
private class SelectionBackgroundCellRenderer implements TableCellRenderer {
private final TableCellRenderer renderer;
public SelectionBackgroundCellRenderer(TableCellRenderer renderer) {
this.renderer = renderer;
}
@Override
public Component getTableCellRendererComponent(JTable myTable, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component component = renderer.getTableCellRendererComponent(myTable,
value, isSelected, hasFocus, row, column);
if (selected[row]) {
component.setBackground(myTable.getSelectionBackground());
component.setForeground(myTable.getSelectionForeground());
} else {
component.setBackground(myTable.getBackground());
component.setForeground(myTable.getForeground());
}
return component;
}
}
public abstract static class TypeToken<T> {
private final Type type;
protected TypeToken(){
Type superClass = getClass().getGenericSuperclass();
this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
public Type getType() {
return type;
}
}
}