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:
commit
803935fc06
@ -715,8 +715,6 @@ SimulationStepper.error.totalMassZero = Total mass of active states is 0
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = Variables to export
|
||||
SimExpPan.border.Stage = Stage to export
|
||||
SimExpPan.but.Selectall = Select all
|
||||
SimExpPan.but.Selectnone = Select none
|
||||
SimExpPan.border.FormatSettings = Format settings
|
||||
SimExpPan.lbl.Fieldsepstr = Field separator string:
|
||||
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.desc2 = \" exists. Overwrite?
|
||||
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.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.txt2 = Do you want to continue with the export?
|
||||
CAExportPanel.dlg.MissingComponents.title = No components selected
|
||||
CAExportPanel.btn.SelectComponents = Select components
|
||||
|
||||
! CADataTypeGroup
|
||||
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>
|
||||
|
||||
! CAPlotTypeSelector
|
||||
CAPlotTypeSelector.lbl.component = Component:
|
||||
CAPlotTypeSelector.btn.SelectComponents = Select components
|
||||
|
||||
! CAPlotPanel
|
||||
CAPlotPanel.lbl.PlotTitle = Component Analysis Plot
|
||||
|
||||
! ComponentSelectionDialog
|
||||
ComponentSelectionDialog.btn.ConfirmSelection = Confirm selection
|
||||
|
||||
! Custom Material dialog
|
||||
custmatdlg.title.Custommaterial = Custom material
|
||||
custmatdlg.lbl.Materialname = Material name:
|
||||
|
@ -567,8 +567,8 @@ SimulationModifierTree.OptimizationParameters = معايير التحسين
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = متغيرات للتصدير
|
||||
SimExpPan.border.Stage = مرحلة التصدير
|
||||
SimExpPan.but.Selectall = حدد الكل
|
||||
SimExpPan.but.Selectnone = لا تختر شيء
|
||||
CSVExportPanel.but.Selectall = حدد الكل
|
||||
CSVExportPanel.but.Selectnone = لا تختر شيء
|
||||
SimExpPan.border.FormatSettings = إعدادات التنسيق
|
||||
SimExpPan.lbl.Fieldsepstr = :سلسلة فاصل المجال
|
||||
SimExpPan.lbl.longA1 = <html>.السلسلة المستخدمة لفصل الحقول في الملف المصدر<br>
|
||||
@ -589,11 +589,11 @@ SimExpPan.lbl.ttip.Commentchar = .الذي يميز سطر التعليق (ال
|
||||
SimExpPan.Fileexists.desc1 = \" الملف
|
||||
SimExpPan.Fileexists.desc2 = \" موجود. هل تريد الكتابة فوقه؟
|
||||
SimExpPan.Fileexists.title = الملف موجود
|
||||
SimExpPan.ExportingVar.desc1 = تصدير متغير واحد من
|
||||
SimExpPan.ExportingVar.desc2 = تصدير
|
||||
SimExpPan.ExportingVar.desc3 = المتغيرات من أصل
|
||||
SimExpPan.Col.Variable = متغيرات
|
||||
SimExpPan.Col.Unit = وحدة
|
||||
CSVExportPanel.ExportingVar.desc1 = تصدير متغير واحد من
|
||||
CSVExportPanel.ExportingVar.desc2 = تصدير
|
||||
CSVExportPanel.ExportingVar.desc3 = المتغيرات من أصل
|
||||
CSVExportPanel.lbl.Variable = متغيرات
|
||||
CSVExportPanel.lbl.Unit = وحدة
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = مفتاح المساحة
|
||||
|
@ -411,8 +411,8 @@ RK4SimulationStepper.error.valuesTooLarge = Hodnoty simulace prekrocily limity.
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = Promenné k exportu
|
||||
SimExpPan.but.Selectall = Oznac v\u0161e
|
||||
SimExpPan.but.Selectnone = Nic neoznacuj
|
||||
CSVExportPanel.but.Selectall = Oznac v\u0161e
|
||||
CSVExportPanel.but.Selectnone = Nic neoznacuj
|
||||
SimExpPan.border.Fieldsep = Oddelovac 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>
|
||||
@ -430,11 +430,11 @@ SimExpPan.but.Exporttofile = Exportuj do souboru...
|
||||
SimExpPan.Fileexists.desc1 = Soubor \"
|
||||
SimExpPan.Fileexists.desc2 = \" existuje. Chcete ho prepsat?
|
||||
SimExpPan.Fileexists.title = Soubor existuje
|
||||
SimExpPan.ExportingVar.desc1 = Exportuji 1 promennou od
|
||||
SimExpPan.ExportingVar.desc2 = Exportuji
|
||||
SimExpPan.ExportingVar.desc3 = promenné od
|
||||
SimExpPan.Col.Variable = Promenná
|
||||
SimExpPan.Col.Unit = Jednoty
|
||||
CSVExportPanel.ExportingVar.desc1 = Exportuji 1 promennou od
|
||||
CSVExportPanel.ExportingVar.desc2 = Exportuji
|
||||
CSVExportPanel.ExportingVar.desc3 = promenné od
|
||||
CSVExportPanel.lbl.Variable = Promenná
|
||||
CSVExportPanel.lbl.Unit = Jednoty
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = Mezerník
|
||||
|
@ -414,8 +414,8 @@ RK4SimulationStepper.error.valuesTooLarge = Simulationswerte
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = zu exportierende Variablen
|
||||
SimExpPan.but.Selectall = Alle auswählen
|
||||
SimExpPan.but.Selectnone = Keine auswählen
|
||||
CSVExportPanel.but.Selectall = Alle auswählen
|
||||
CSVExportPanel.but.Selectnone = Keine auswählen
|
||||
SimExpPan.border.Fieldsep = Feldtrennung
|
||||
SimExpPan.lbl.Fieldsepstr = Trennzeichen
|
||||
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.desc2 = \" existiert bereits. Überschreiben?"
|
||||
SimExpPan.Fileexists.title = Datei existiert bereits
|
||||
SimExpPan.ExportingVar.desc1 = Exportiere Variable 1 aus
|
||||
SimExpPan.ExportingVar.desc2 = Exportiere
|
||||
SimExpPan.ExportingVar.desc3 = Variablen aus
|
||||
SimExpPan.Col.Variable = Variable
|
||||
SimExpPan.Col.Unit = Einheit
|
||||
CSVExportPanel.ExportingVar.desc1 = Exportiere Variable 1 aus
|
||||
CSVExportPanel.ExportingVar.desc2 = Exportiere
|
||||
CSVExportPanel.ExportingVar.desc3 = Variablen aus
|
||||
CSVExportPanel.lbl.Variable = Variable
|
||||
CSVExportPanel.lbl.Unit = Einheit
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = LEER
|
||||
|
@ -969,11 +969,11 @@ ShockCordCfg.lbl.plus = Localizaci\u00f3n:
|
||||
ShockCordCfg.tab.General = General
|
||||
ShockCordCfg.tab.ttip.General = Propiedades generales
|
||||
|
||||
SimExpPan.Col.Unit = Unidad
|
||||
SimExpPan.Col.Variable = Variable
|
||||
SimExpPan.ExportingVar.desc1 = Exportar variables
|
||||
SimExpPan.ExportingVar.desc2 = Exportar
|
||||
SimExpPan.ExportingVar.desc3 = variables de
|
||||
CSVExportPanel.lbl.Unit = Unidad
|
||||
CSVExportPanel.lbl.Variable = Variable
|
||||
CSVExportPanel.ExportingVar.desc1 = Exportar variables
|
||||
CSVExportPanel.ExportingVar.desc2 = Exportar
|
||||
CSVExportPanel.ExportingVar.desc3 = variables de
|
||||
SimExpPan.Fileexists.desc1 = Archivo "
|
||||
SimExpPan.Fileexists.desc2 = " ya existe. \u00bfDesea sobrescribirlo?
|
||||
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.Vartoexport = Variables para exportar
|
||||
SimExpPan.but.Exporttofile = Exportar al documento ...
|
||||
SimExpPan.but.Selectall = Seleccionar todo
|
||||
SimExpPan.but.Selectnone = No seleccionar nada
|
||||
CSVExportPanel.but.Selectall = Seleccionar todo
|
||||
CSVExportPanel.but.Selectnone = No seleccionar nada
|
||||
SimExpPan.checkbox.Incflightevents = Incluir los eventos del vuelo.
|
||||
SimExpPan.checkbox.Includefielddesc = Incluir descripciones del campo.
|
||||
SimExpPan.checkbox.Includesimudesc = Incluir descripci\u00f3n de la simulaci\u00f3n.
|
||||
|
@ -959,11 +959,11 @@ ShockCordCfg.lbl.plus = plus
|
||||
ShockCordCfg.tab.General = G\u00E9n\u00E9ral
|
||||
ShockCordCfg.tab.ttip.General = Propri\u00E9t\u00E9s g\u00E9n\u00E9rales
|
||||
|
||||
SimExpPan.Col.Unit = Unit\u00E9
|
||||
SimExpPan.Col.Variable = Variable
|
||||
SimExpPan.ExportingVar.desc1 = Exporter 1 variable sur un total de
|
||||
SimExpPan.ExportingVar.desc2 = Exportation
|
||||
SimExpPan.ExportingVar.desc3 = variable sur un total de
|
||||
CSVExportPanel.lbl.Unit = Unit\u00E9
|
||||
CSVExportPanel.lbl.Variable = Variable
|
||||
CSVExportPanel.ExportingVar.desc1 = Exporter 1 variable sur un total de
|
||||
CSVExportPanel.ExportingVar.desc2 = Exportation
|
||||
CSVExportPanel.ExportingVar.desc3 = variable sur un total de
|
||||
SimExpPan.Fileexists.desc1 = Le fichier "
|
||||
SimExpPan.Fileexists.desc2 = " existe d\u00E9j\u00E0. Ecraser?
|
||||
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.Vartoexport = Variables \u00E0 exporter
|
||||
SimExpPan.but.Exporttofile = Exporter dans un fichier...
|
||||
SimExpPan.but.Selectall = Tout s\u00E9lectionner
|
||||
SimExpPan.but.Selectnone = Ne rien s\u00E9lectionner
|
||||
CSVExportPanel.but.Selectall = Tout s\u00E9lectionner
|
||||
CSVExportPanel.but.Selectnone = Ne rien s\u00E9lectionner
|
||||
SimExpPan.checkbox.Incflightevents = Inclure les \u00E9v\u00E9nements de vol
|
||||
SimExpPan.checkbox.Includefielddesc = Inclure les descriptions des champs
|
||||
SimExpPan.checkbox.Includesimudesc = Inclure la description de la simulation
|
||||
|
@ -417,8 +417,8 @@ RK4SimulationStepper.error.valuesTooLarge = I valori di simulazione anno eccedut
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = Variabili da esportare
|
||||
SimExpPan.but.Selectall = Seleziona tutto
|
||||
SimExpPan.but.Selectnone = Deseleziona tutto
|
||||
CSVExportPanel.but.Selectall = Seleziona tutto
|
||||
CSVExportPanel.but.Selectnone = Deseleziona tutto
|
||||
SimExpPan.border.Fieldsep = 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>
|
||||
@ -436,11 +436,11 @@ SimExpPan.but.Exporttofile = Esporta nel file...
|
||||
SimExpPan.Fileexists.desc1 = Il file \"
|
||||
SimExpPan.Fileexists.desc2 = \" esiste. Sovrascrivo?
|
||||
SimExpPan.Fileexists.title = Il file esiste
|
||||
SimExpPan.ExportingVar.desc1 = Sto esportando 1 variabile su
|
||||
SimExpPan.ExportingVar.desc2 = Sto esportando
|
||||
SimExpPan.ExportingVar.desc3 = variabili su
|
||||
SimExpPan.Col.Variable = Variabile
|
||||
SimExpPan.Col.Unit = Unita'
|
||||
CSVExportPanel.ExportingVar.desc1 = Sto esportando 1 variabile su
|
||||
CSVExportPanel.ExportingVar.desc2 = Sto esportando
|
||||
CSVExportPanel.ExportingVar.desc3 = variabili su
|
||||
CSVExportPanel.lbl.Variable = Variabile
|
||||
CSVExportPanel.lbl.Unit = Unita'
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = SPAZIO
|
||||
|
@ -422,8 +422,8 @@ SimulationModifierTree.OptimizationParameters = \u6700\u9069\u5316\u30D1\u30E9\
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u5909\u6570
|
||||
SimExpPan.but.Selectall = \u5168\u3066\u9078\u629E
|
||||
SimExpPan.but.Selectnone = \u5168\u3066\u975E\u9078\u629E
|
||||
CSVExportPanel.but.Selectall = \u5168\u3066\u9078\u629E
|
||||
CSVExportPanel.but.Selectnone = \u5168\u3066\u975E\u9078\u629E
|
||||
SimExpPan.border.Fieldsep = \u533A\u5207\u308A\u6587\u5B57
|
||||
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>
|
||||
@ -441,11 +441,11 @@ SimExpPan.but.Exporttofile = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
||||
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.title = \u30D5\u30A1\u30A4\u30EB\u306E\u4E0A\u66F8\u304D
|
||||
SimExpPan.ExportingVar.desc1 = Exporting 1 variable out of
|
||||
SimExpPan.ExportingVar.desc2 = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
||||
SimExpPan.ExportingVar.desc3 = \u5909\u6570\u3001\u5168\u4F53\u306E\u5909\u6570
|
||||
SimExpPan.Col.Variable = \u5909\u6570
|
||||
SimExpPan.Col.Unit = \u5358\u4F4D
|
||||
CSVExportPanel.ExportingVar.desc1 = Exporting 1 variable out of
|
||||
CSVExportPanel.ExportingVar.desc2 = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
|
||||
CSVExportPanel.ExportingVar.desc3 = \u5909\u6570\u3001\u5168\u4F53\u306E\u5909\u6570
|
||||
CSVExportPanel.lbl.Variable = \u5909\u6570
|
||||
CSVExportPanel.lbl.Unit = \u5358\u4F4D
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = SPACE
|
||||
|
@ -541,8 +541,8 @@ SimulationModifierTree.OptimizationParameters = Optimalisatieparameters
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = Variabelen om te exporteren
|
||||
SimExpPan.border.Stage = Trap om te exporteren
|
||||
SimExpPan.but.Selectall = Selecteer alles
|
||||
SimExpPan.but.Selectnone = Selecteer niets
|
||||
CSVExportPanel.but.Selectall = Selecteer alles
|
||||
CSVExportPanel.but.Selectnone = Selecteer niets
|
||||
SimExpPan.border.Fieldsep = Veldscheider
|
||||
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>
|
||||
@ -559,11 +559,11 @@ SimExpPan.lbl.ttip.Commentchar = Het teken of de tekens die een opmerkingregel m
|
||||
SimExpPan.Fileexists.desc1 = Bestand \"
|
||||
SimExpPan.Fileexists.desc2 = \" bestaat reeds. Overschrijven?
|
||||
SimExpPan.Fileexists.title = Bestand bestaat reeds
|
||||
SimExpPan.ExportingVar.desc1 = Exporteren van 1 variabele uit
|
||||
SimExpPan.ExportingVar.desc2 = Exporteren
|
||||
SimExpPan.ExportingVar.desc3 = variabelen uit
|
||||
SimExpPan.Col.Variable = Variabele
|
||||
SimExpPan.Col.Unit = Eenheid
|
||||
CSVExportPanel.ExportingVar.desc1 = Exporteren van 1 variabele uit
|
||||
CSVExportPanel.ExportingVar.desc2 = Exporteren
|
||||
CSVExportPanel.ExportingVar.desc3 = variabelen uit
|
||||
CSVExportPanel.lbl.Variable = Variabele
|
||||
CSVExportPanel.lbl.Unit = Eenheid
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = SPACE
|
||||
|
@ -414,8 +414,8 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.border.Vartoexport = Zmienne do wyeksportowania
|
||||
SimExpPan.but.Selectall = Wybierz wszystko
|
||||
SimExpPan.but.Selectnone = Odznacz wszystko
|
||||
CSVExportPanel.but.Selectall = Wybierz wszystko
|
||||
CSVExportPanel.but.Selectnone = Odznacz wszystko
|
||||
SimExpPan.border.Fieldsep = 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>
|
||||
@ -433,11 +433,11 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
|
||||
SimExpPan.Fileexists.desc1 = Plik \"
|
||||
SimExpPan.Fileexists.desc2 = \" istnieje. Nadpisa\u0107?
|
||||
SimExpPan.Fileexists.title = Plik ju\u017C istnieje
|
||||
SimExpPan.ExportingVar.desc1 = Eksportuj\u0119 1 zmienn\u0105 z
|
||||
SimExpPan.ExportingVar.desc2 = Eksportuj\u0119
|
||||
SimExpPan.ExportingVar.desc3 = zmienne z
|
||||
SimExpPan.Col.Variable = Zmienna
|
||||
SimExpPan.Col.Unit = Jednostka
|
||||
CSVExportPanel.ExportingVar.desc1 = Eksportuj\u0119 1 zmienn\u0105 z
|
||||
CSVExportPanel.ExportingVar.desc2 = Eksportuj\u0119
|
||||
CSVExportPanel.ExportingVar.desc3 = zmienne z
|
||||
CSVExportPanel.lbl.Variable = Zmienna
|
||||
CSVExportPanel.lbl.Unit = Jednostka
|
||||
|
||||
|
||||
CsvOptionPanel.separator.space = SPACJA
|
||||
|
@ -944,11 +944,11 @@ ShockCordCfg.lbl.plus = mais
|
||||
ShockCordCfg.tab.General = Geral
|
||||
ShockCordCfg.tab.ttip.General = Propriedades gerais
|
||||
|
||||
SimExpPan.Col.Unit = Unidade
|
||||
SimExpPan.Col.Variable = Vari\u00e1vel
|
||||
SimExpPan.ExportingVar.desc1 = Exportando uma vari\u00e1vel de
|
||||
SimExpPan.ExportingVar.desc2 = Exportando
|
||||
SimExpPan.ExportingVar.desc3 = vari\u00e1veis fora de
|
||||
CSVExportPanel.lbl.Unit = Unidade
|
||||
CSVExportPanel.lbl.Variable = Vari\u00e1vel
|
||||
CSVExportPanel.ExportingVar.desc1 = Exportando uma vari\u00e1vel de
|
||||
CSVExportPanel.ExportingVar.desc2 = Exportando
|
||||
CSVExportPanel.ExportingVar.desc3 = vari\u00e1veis fora de
|
||||
SimExpPan.Fileexists.desc1 = Arquivo "
|
||||
SimExpPan.Fileexists.desc2 = " existe. Sobreescrever?
|
||||
SimExpPan.Fileexists.title = Arquivo existe
|
||||
@ -956,8 +956,8 @@ SimExpPan.border.Comments = Coment\u00e1rios
|
||||
SimExpPan.border.Fieldsep = Separador de campo
|
||||
SimExpPan.border.Vartoexport = Vari\u00e1veis para exportar
|
||||
SimExpPan.but.Exporttofile = Exportar para arquivo...
|
||||
SimExpPan.but.Selectall = Selecionar todos
|
||||
SimExpPan.but.Selectnone = Limpar sele\u00e7\u00e3o
|
||||
CSVExportPanel.but.Selectall = Selecionar todos
|
||||
CSVExportPanel.but.Selectnone = Limpar sele\u00e7\u00e3o
|
||||
SimExpPan.checkbox.Incflightevents = Incluir eventos de voo
|
||||
SimExpPan.checkbox.Includefielddesc = Incluir descri\u00e7\u00f5es de campo
|
||||
SimExpPan.checkbox.Includesimudesc = Incluir a descri\u00e7\u00e3o de simula\u00e7\u00e3o
|
||||
|
@ -555,8 +555,8 @@ SimulationModifierTree.OptimizationParameters = \u041E\u043F\u0442\u0438\u043C\u
|
||||
! 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.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
|
||||
SimExpPan.but.Selectnone = \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0432\u044B\u0431\u043E\u0440
|
||||
CSVExportPanel.but.Selectall = \u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435
|
||||
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.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>
|
||||
@ -577,11 +577,11 @@ SimExpPan.lbl.ttip.Commentchar = \u0421\u0438\u043C\u0432\u043E\u043B(\u044B), \
|
||||
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.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
|
||||
SimExpPan.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
|
||||
SimExpPan.Col.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.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.desc2 = \u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044F
|
||||
CSVExportPanel.ExportingVar.desc3 = \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445 \u0438\u0437
|
||||
CSVExportPanel.lbl.Variable = \u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\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
|
||||
|
@ -682,8 +682,8 @@ SimulationStepper.error.totalMassZero = \u0417\u0430\u0433\u0430\u043b\u044c\u04
|
||||
! SimulationExportPanel
|
||||
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.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.Selectall = \u0412\u0438\u0431\u0440\u0430\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.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>
|
||||
@ -704,11 +704,11 @@ SimExpPan.lbl.ttip.Commentchar = \u0421\u0438\u043c\u0432\u043e\u043b(\u0438), \
|
||||
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.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
|
||||
SimExpPan.ExportingVar.desc2 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442
|
||||
SimExpPan.ExportingVar.desc3 = \u0437\u043c\u0456\u043d\u043d\u0438\u0445 \u0437
|
||||
SimExpPan.Col.Variable = \u0417\u043c\u0456\u043d\u043d\u0430
|
||||
SimExpPan.Col.Unit = \u041e\u0434\u0438\u043d\u0438\u0446\u044f
|
||||
CSVExportPanel.ExportingVar.desc1 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0437\u043c\u0456\u043d\u043d\u043e\u0457 1 \u0437
|
||||
CSVExportPanel.ExportingVar.desc2 = \u0415\u043a\u0441\u043f\u043e\u0440\u0442
|
||||
CSVExportPanel.ExportingVar.desc3 = \u0437\u043c\u0456\u043d\u043d\u0438\u0445 \u0437
|
||||
CSVExportPanel.lbl.Variable = \u0417\u043c\u0456\u043d\u043d\u0430
|
||||
CSVExportPanel.lbl.Unit = \u041e\u0434\u0438\u043d\u0438\u0446\u044f
|
||||
|
||||
CsvOptionPanel.separator.space = \u041f\u0420\u041e\u0411\u0406\u041b
|
||||
CsvOptionPanel.separator.tab = \u0412\u041a\u041b\u0410\u0414\u041a\u0410
|
||||
|
@ -1026,11 +1026,11 @@ ShockCordCfg.lbl.plus = \u52A0
|
||||
ShockCordCfg.tab.General = \u5E38\u89C4
|
||||
ShockCordCfg.tab.ttip.General = \u5E38\u89C4\u5C5E\u6027
|
||||
|
||||
SimExpPan.Col.Unit = \u5355\u4F4D
|
||||
SimExpPan.Col.Variable = \u53D8\u91CF
|
||||
SimExpPan.ExportingVar.desc1 = \u8F93\u51FA1\u4E2A\u53D8\u91CF\uFF0C\u5171\u8BA1
|
||||
SimExpPan.ExportingVar.desc2 = \u8F93\u51FA
|
||||
SimExpPan.ExportingVar.desc3 = \u4E2A\u53D8\u91CF, \u5171\u8BA1
|
||||
CSVExportPanel.lbl.Unit = \u5355\u4F4D
|
||||
CSVExportPanel.lbl.Variable = \u53D8\u91CF
|
||||
CSVExportPanel.ExportingVar.desc1 = \u8F93\u51FA1\u4E2A\u53D8\u91CF\uFF0C\u5171\u8BA1
|
||||
CSVExportPanel.ExportingVar.desc2 = \u8F93\u51FA
|
||||
CSVExportPanel.ExportingVar.desc3 = \u4E2A\u53D8\u91CF, \u5171\u8BA1
|
||||
SimExpPan.Fileexists.desc1 = \u6587\u4EF6 "
|
||||
SimExpPan.Fileexists.desc2 = " \u5DF2\u5B58\u5728. \u8986\u76D6?
|
||||
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.Stage = \u5BFC\u51FA\u706B\u7BAD\u7EA7
|
||||
SimExpPan.border.Vartoexport = \u5BFC\u51FA\u53D8\u91CF
|
||||
SimExpPan.but.Selectall = \u5168\u9009
|
||||
SimExpPan.but.Selectnone = \u53D6\u6D88\u5168\u9009
|
||||
CSVExportPanel.but.Selectall = \u5168\u9009
|
||||
CSVExportPanel.but.Selectnone = \u53D6\u6D88\u5168\u9009
|
||||
SimExpPan.checkbox.Incflightevents = \u98DE\u884C\u4E8B\u4EF6
|
||||
SimExpPan.checkbox.Includefielddesc = \u6570\u636E\u57DF\u63CF\u8FF0
|
||||
SimExpPan.checkbox.Includesimudesc = \u4EFF\u771F\u63CF\u8FF0
|
||||
|
@ -2,7 +2,6 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
|
||||
|
||||
import info.openrocket.core.componentanalysis.CADataBranch;
|
||||
import info.openrocket.core.componentanalysis.CADataType;
|
||||
import info.openrocket.core.l10n.Translator;
|
||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||
import info.openrocket.core.startup.Application;
|
||||
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.widgets.CSVExportPanel;
|
||||
import info.openrocket.swing.gui.widgets.SaveFileChooser;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.AbstractCellEditor;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultCellEditor;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import java.awt.Color;
|
||||
import javax.swing.UIManager;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
private static final long serialVersionUID = 4423905472892675964L;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final int FIXED_COMPONENT_COLUMN_WIDTH = 500;
|
||||
private static final SwingPreferences prefs = (SwingPreferences) Application.getPreferences();
|
||||
|
||||
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_FIELD_DESCRIPTIONS = 1;
|
||||
|
||||
private final List<Map<RocketComponent, Boolean>> selectedComponents;
|
||||
private final ComponentAnalysisPlotExportPanel parent;
|
||||
|
||||
private CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types,
|
||||
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
|
||||
super(types, selected, csvOptions, true, extraComponents);
|
||||
public CAExportPanel(ComponentAnalysisPlotExportPanel parent, CADataType[] types, boolean[] selected) {
|
||||
super(types, selected,
|
||||
new CsvOptionPanel(CAExportPanel.class, true,
|
||||
trans.get("CAExportPanel.checkbox.Includecadesc"),
|
||||
trans.get("CAExportPanel.checkbox.ttip.Includecadesc"),
|
||||
trans.get("SimExpPan.checkbox.Includefielddesc"),
|
||||
trans.get("SimExpPan.checkbox.ttip.Includefielddesc")),
|
||||
false);
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
selectedComponents = new ArrayList<>(types.length);
|
||||
Map<RocketComponent, Boolean> componentSelectedMap;
|
||||
List<RocketComponent> components;
|
||||
for (CADataType type : types) {
|
||||
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);
|
||||
// Initialize selected components map
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
updateSelectedComponents(types[i], new ArrayList<>(), parent.getComponentsForType(types[i]),
|
||||
selectedComponentsLabels.get(i), selectedComponentsScrollPanes.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// Set row heights dynamically
|
||||
for (int row = 0; row < table.getRowCount(); row++) {
|
||||
int numComponents = ((Map<?, ?>) table.getValueAt(row, 3)).size();
|
||||
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
|
||||
int rowHeight = Math.max(table.getRowHeight(), (int) height);
|
||||
table.setRowHeight(row, rowHeight);
|
||||
}
|
||||
@Override
|
||||
protected Component createExtraComponent(CADataType type, int index) {
|
||||
JPanel panel = new JPanel(new MigLayout("ins 0, fill", "[grow]", "[][]"));
|
||||
|
||||
// Label for displaying selected components
|
||||
JTextArea 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));
|
||||
|
||||
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) {
|
||||
@ -90,39 +136,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
selected[i] = ((SwingPreferences) Application.getPreferences()).isComponentAnalysisDataTypeExportSelected(types[i]);
|
||||
}
|
||||
|
||||
CsvOptionPanel csvOptions = new CsvOptionPanel(CAExportPanel.class, false,
|
||||
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);
|
||||
return new CAExportPanel(parent, types, selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -133,7 +147,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
List<CADataType> typesWithNoComponents = new ArrayList<>();
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
if (selected[i]) {
|
||||
boolean hasSelectedComponent = selectedComponents.get(i).values().stream().anyMatch(v -> v);
|
||||
boolean hasSelectedComponent = !selectedComponents.get(i).isEmpty();
|
||||
if (!hasSelectedComponent) {
|
||||
typesWithNoComponents.add(types[i]);
|
||||
}
|
||||
@ -188,12 +202,9 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
csvOptions.storePreferences();
|
||||
|
||||
// Store preferences and export
|
||||
int n = 0;
|
||||
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
((SwingPreferences) Application.getPreferences()).setComponentAnalysisExportSelected(types[i], selected[i]);
|
||||
if (selected[i])
|
||||
n++;
|
||||
}
|
||||
|
||||
List<CADataType> fieldTypes = new ArrayList<>();
|
||||
@ -203,12 +214,7 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
// Iterate through the table to get selected items
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
if (selected[i]) {
|
||||
List<RocketComponent> selectedComponentsList = new ArrayList<>();
|
||||
for (Map.Entry<RocketComponent, Boolean> entry : selectedComponents.get(i).entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
selectedComponentsList.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
List<RocketComponent> selectedComponentsList = new ArrayList<>(selectedComponents.get(i));
|
||||
if (!selectedComponentsList.isEmpty()) {
|
||||
fieldTypes.add(types[i]);
|
||||
fieldUnits.add(units[i]);
|
||||
@ -232,315 +238,4 @@ public class CAExportPanel extends CSVExportPanel<CADataType> {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,12 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
|
||||
|
||||
import info.openrocket.core.componentanalysis.CADataBranch;
|
||||
import info.openrocket.core.componentanalysis.CADataType;
|
||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||
import info.openrocket.core.unit.Unit;
|
||||
import info.openrocket.swing.gui.plot.Plot;
|
||||
import org.jfree.data.xy.XYSeries;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration> {
|
||||
@ -18,12 +19,27 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
|
||||
@Override
|
||||
protected List<XYSeries> createSeriesForType(int dataIndex, int startIndex, CADataType type, Unit unit,
|
||||
CADataBranch branch, int branchIdx, String branchName, String baseName) {
|
||||
// Default implementation for regular DataBranch
|
||||
MetadataXYSeries series = new MetadataXYSeries(startIndex, false, true, branchIdx, unit.getUnit(),
|
||||
branchName, baseName);
|
||||
// Get the component info
|
||||
List<RocketComponent> components = filledConfig.getComponents(dataIndex);
|
||||
List<String> componentNames = filledConfig.getComponentNames(dataIndex);
|
||||
|
||||
// Get the component name
|
||||
String componentName = filledConfig.getComponentName(dataIndex);
|
||||
// Create the series for each component
|
||||
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
|
||||
String newBaseName = baseName;
|
||||
@ -34,7 +50,7 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
|
||||
series.updateDescription();
|
||||
|
||||
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();
|
||||
for (int j = 0; j < pointCount; j++) {
|
||||
@ -43,6 +59,6 @@ public class CAPlot extends Plot<CADataType, CADataBranch, CAPlotConfiguration>
|
||||
series.add(x, y);
|
||||
}
|
||||
|
||||
return Collections.singletonList(series);
|
||||
return series;
|
||||
}
|
||||
}
|
||||
|
@ -7,21 +7,21 @@ import info.openrocket.core.l10n.Translator;
|
||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||
import info.openrocket.core.startup.Application;
|
||||
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.PlotConfiguration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBranch> {
|
||||
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;
|
||||
static {
|
||||
ArrayList<CAPlotConfiguration> configs = new ArrayList<>();
|
||||
List<CAPlotConfiguration> configs = new ArrayList<>();
|
||||
CAPlotConfiguration config;
|
||||
|
||||
//// Total CD vs Mach
|
||||
@ -53,17 +53,21 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
|
||||
plotDataComponents.add(null);
|
||||
}
|
||||
|
||||
public RocketComponent getComponent(int index) {
|
||||
public List<RocketComponent> getComponents(int index) {
|
||||
return plotDataComponents.get(index);
|
||||
}
|
||||
|
||||
public void setPlotDataComponent(int index, RocketComponent component) {
|
||||
plotDataComponents.set(index, component);
|
||||
public void setPlotDataComponents(int index, List<RocketComponent> components) {
|
||||
plotDataComponents.set(index, components);
|
||||
}
|
||||
|
||||
public String getComponentName(int dataIndex) {
|
||||
RocketComponent component = getComponent(dataIndex);
|
||||
return component != null ? component.getName() : "";
|
||||
public List<String> getComponentNames(int dataIndex) {
|
||||
List<RocketComponent> components = getComponents(dataIndex);
|
||||
List<String> names = new ArrayList<>(components.size());
|
||||
for (RocketComponent c : components) {
|
||||
names.add(c != null ? c.getName() : "");
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,8 +82,12 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
|
||||
}
|
||||
Axis axis = allAxes.get(index);
|
||||
|
||||
double min = unit.toUnit(data.get(0).getMinimum(type, getComponent(i)));
|
||||
double max = unit.toUnit(data.get(0).getMaximum(type, getComponent(i)));
|
||||
double min = Double.MAX_VALUE;
|
||||
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++) {
|
||||
// Ignore empty data
|
||||
@ -98,7 +106,10 @@ public class CAPlotConfiguration extends PlotConfiguration<CADataType, CADataBra
|
||||
@SuppressWarnings("unchecked")
|
||||
public CAPlotConfiguration 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;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import info.openrocket.core.componentanalysis.CADataBranch;
|
||||
import info.openrocket.core.componentanalysis.CADataType;
|
||||
import info.openrocket.core.componentanalysis.CADataTypeGroup;
|
||||
import info.openrocket.core.componentanalysis.CADomainDataType;
|
||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||
import info.openrocket.core.unit.Unit;
|
||||
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;
|
||||
}
|
||||
|
||||
private CAPlotPanel(ComponentAnalysisPlotExportPanel parent,
|
||||
CADomainDataType[] typesX, CADataType[] typesY) {
|
||||
private CAPlotPanel(ComponentAnalysisPlotExportPanel parent, CADomainDataType[] typesX, CADataType[] typesY) {
|
||||
super(typesX, typesY, CUSTOM_CONFIGURATION, PRESET_ARRAY, DEFAULT_CONFIGURATION, null, null);
|
||||
|
||||
this.parent = parent;
|
||||
@ -63,15 +61,14 @@ public class CAPlotPanel extends PlotPanel<CADataType, CADataBranch, CADataTypeG
|
||||
|
||||
selector.addComponentSelectionListener(e -> {
|
||||
if (modifying > 0) return;
|
||||
RocketComponent component = selector.getSelectedComponent();
|
||||
configuration.setPlotDataComponent(idx, component);
|
||||
configuration.setPlotDataComponents(idx, selector.getSelectedComponents());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CAPlotTypeSelector createSelector(int i, CADataType type, Unit unit, int axis) {
|
||||
return new CAPlotTypeSelector(parent, i, type, unit, axis, List.of(typesY),
|
||||
parent.getComponentsForType(type), configuration, configuration.getComponent(i));
|
||||
return new CAPlotTypeSelector(parent, parent.getDocument(), i, type, unit, axis, List.of(typesY),
|
||||
parent.getComponentsForType(type), configuration, configuration.getComponents(i));
|
||||
}
|
||||
|
||||
public void setXAxis(CADomainDataType type) {
|
||||
|
@ -2,39 +2,79 @@ package info.openrocket.swing.gui.dialogs.componentanalysis;
|
||||
|
||||
import info.openrocket.core.componentanalysis.CADataType;
|
||||
import info.openrocket.core.componentanalysis.CADataTypeGroup;
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.rocketcomponent.RocketComponent;
|
||||
import info.openrocket.core.startup.Application;
|
||||
import info.openrocket.core.unit.Unit;
|
||||
import info.openrocket.core.util.StringUtils;
|
||||
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.JLabel;
|
||||
import javax.swing.JButton;
|
||||
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.ActionListener;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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,
|
||||
CADataType type, Unit unit, int position, List<CADataType> availableTypes,
|
||||
private final JTextArea selectedComponentsLabel;
|
||||
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,
|
||||
RocketComponent selectedComponent) {
|
||||
List<RocketComponent> initialSelectedComponents) {
|
||||
super(plotIndex, type, unit, position, availableTypes, false);
|
||||
|
||||
if (componentsForType.isEmpty()) {
|
||||
throw new IllegalArgumentException("No components for type " + type);
|
||||
}
|
||||
// Selected components label
|
||||
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
|
||||
selectedComponent = selectedComponent != null ? selectedComponent : componentsForType.get(0);
|
||||
this.add(new JLabel(trans.get("CAPlotTypeSelector.lbl.component")));
|
||||
componentSelector = new JComboBox<>(componentsForType.toArray(new RocketComponent[0]));
|
||||
componentSelector.setSelectedItem(selectedComponent);
|
||||
configuration.setPlotDataComponent(plotIndex, selectedComponent);
|
||||
this.add(componentSelector, "growx, gapright para");
|
||||
final JPanel componentSelectorPanel = new JPanel(new MigLayout("ins 0"));
|
||||
JButton selectComponentButton = new JButton(trans.get("CAPlotTypeSelector.btn.SelectComponents"));
|
||||
selectComponentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
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();
|
||||
|
||||
typeSelector.addActionListener(new ActionListener() {
|
||||
@ -42,32 +82,65 @@ public class CAPlotTypeSelector extends PlotTypeSelector<CADataType, CADataTypeG
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CADataType type = (CADataType) typeSelector.getSelectedItem();
|
||||
List<RocketComponent> componentsForType = parent.getComponentsForType(type);
|
||||
componentSelector.removeAllItems();
|
||||
for (RocketComponent component : componentsForType) {
|
||||
componentSelector.addItem(component);
|
||||
}
|
||||
componentSelector.setSelectedIndex(0);
|
||||
configuration.setPlotDataComponent(plotIndex, (RocketComponent) componentSelector.getSelectedItem());
|
||||
setComponentsForType(type, componentsForType);
|
||||
updateSelectedComponents(null, componentsForType, configuration, plotIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CAPlotTypeSelector(final ComponentAnalysisPlotExportPanel parent, int plotIndex,
|
||||
CADataType type, Unit unit, int position, List<CADataType> availableTypes,
|
||||
List<RocketComponent> componentsForType, CAPlotConfiguration configuration) {
|
||||
this(parent, plotIndex, type, unit, position, availableTypes, componentsForType, configuration, null);
|
||||
private void setComponentsForType(CADataType type, List<RocketComponent> componentsForType) {
|
||||
if (componentsForType.isEmpty()) {
|
||||
throw new IllegalArgumentException("No components for type " + type);
|
||||
}
|
||||
this.componentsForType = componentsForType;
|
||||
}
|
||||
|
||||
public void addComponentSelectionListener(ItemListener listener) {
|
||||
componentSelector.addItemListener(listener);
|
||||
private void updateSelectedComponents(List<RocketComponent> components, List<RocketComponent> componentsForType,
|
||||
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() {
|
||||
return (RocketComponent) componentSelector.getSelectedItem();
|
||||
private void updateSelectedComponentsLabel(List<RocketComponent> components) {
|
||||
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
|
||||
protected String getDisplayString(CADataType item) {
|
||||
return StringUtils.removeHTMLTags(item.getName());
|
||||
}
|
||||
|
||||
public interface ComponentSelectionListener {
|
||||
void componentsSelected(List<RocketComponent> selectedComponents);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package info.openrocket.swing.gui.dialogs.componentanalysis;
|
||||
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.l10n.Translator;
|
||||
import info.openrocket.core.startup.Application;
|
||||
|
||||
@ -28,7 +29,7 @@ public class ComponentAnalysisDialog extends JDialog {
|
||||
|
||||
private JButton okButton;
|
||||
|
||||
public ComponentAnalysisDialog(RocketPanel rocketPanel) {
|
||||
public ComponentAnalysisDialog(OpenRocketDocument document, RocketPanel rocketPanel) {
|
||||
//// Component analysis
|
||||
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);
|
||||
|
||||
// Plot export tab
|
||||
ComponentAnalysisPlotExportPanel plotExportTab = new ComponentAnalysisPlotExportPanel(this, generalTab.getParameters(),
|
||||
generalTab.getAerodynamicCalculator(), generalTab.getRocket());
|
||||
ComponentAnalysisPlotExportPanel plotExportTab = new ComponentAnalysisPlotExportPanel(this, document,
|
||||
generalTab.getParameters(), generalTab.getAerodynamicCalculator(), generalTab.getRocket());
|
||||
tabbedPane.addTab(trans.get("ComponentAnalysisDialog.tab.PlotExport"), plotExportTab);
|
||||
|
||||
panel.add(tabbedPane, "span, pushy, grow, wrap");
|
||||
@ -94,10 +95,10 @@ public class ComponentAnalysisDialog extends JDialog {
|
||||
|
||||
///////// Singleton implementation
|
||||
|
||||
public static void showDialog(RocketPanel rocketpanel) {
|
||||
public static void showDialog(OpenRocketDocument document, RocketPanel rocketpanel) {
|
||||
if (singletonDialog != null)
|
||||
singletonDialog.dispose();
|
||||
singletonDialog = new ComponentAnalysisDialog(rocketpanel);
|
||||
singletonDialog = new ComponentAnalysisDialog(document, rocketpanel);
|
||||
singletonDialog.setVisible(true);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import info.openrocket.core.componentanalysis.CADataType;
|
||||
import info.openrocket.core.componentanalysis.CADomainDataType;
|
||||
import info.openrocket.core.componentanalysis.CAParameterSweep;
|
||||
import info.openrocket.core.componentanalysis.CAParameters;
|
||||
import info.openrocket.core.document.OpenRocketDocument;
|
||||
import info.openrocket.core.l10n.Translator;
|
||||
import info.openrocket.core.rocketcomponent.Rocket;
|
||||
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 final Window parent;
|
||||
private final OpenRocketDocument document;
|
||||
private final JTabbedPane tabbedPane;
|
||||
JComboBox<CADomainDataType> parameterSelector;
|
||||
private JButton okButton;
|
||||
@ -62,11 +64,13 @@ public class ComponentAnalysisPlotExportPanel extends JPanel implements PlotPane
|
||||
private final Map<CADataType, List<RocketComponent>> componentCache;
|
||||
private boolean isCacheValid;
|
||||
|
||||
public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, CAParameters parameters,
|
||||
AerodynamicCalculator aerodynamicCalculator, Rocket rocket) {
|
||||
public ComponentAnalysisPlotExportPanel(ComponentAnalysisDialog parent, OpenRocketDocument document,
|
||||
CAParameters parameters, AerodynamicCalculator aerodynamicCalculator,
|
||||
Rocket rocket) {
|
||||
super(new MigLayout("fill, height 700px!", "[]", "[grow]"));
|
||||
|
||||
this.parent = parent;
|
||||
this.document = document;
|
||||
this.parameters = parameters;
|
||||
this.parameterSweep = new CAParameterSweep(parameters, aerodynamicCalculator, rocket);
|
||||
this.componentCache = new HashMap<>();
|
||||
@ -216,6 +220,10 @@ public class ComponentAnalysisPlotExportPanel extends JPanel implements PlotPane
|
||||
});
|
||||
}
|
||||
|
||||
public OpenRocketDocument getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
public CADomainDataType getSelectedParameter() {
|
||||
return (CADomainDataType) parameterSelector.getSelectedItem();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -663,7 +663,7 @@ public class BasicFrame extends JFrame {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "Component analysis selected");
|
||||
ComponentAnalysisDialog.showDialog(rocketpanel);
|
||||
ComponentAnalysisDialog.showDialog(document, rocketpanel);
|
||||
}
|
||||
});
|
||||
toolsMenu.add(item);
|
||||
|
@ -35,10 +35,6 @@ public class ComponentTreeRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
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 Icon massOverrideSubcomponentIcon;
|
||||
private static Icon massOverrideIcon;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -52,19 +52,19 @@ public class PlotTypeSelector<T extends Groupable<G> & UnitValue, G extends Grou
|
||||
}
|
||||
};
|
||||
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());
|
||||
if (unit != null) {
|
||||
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.setSelectedIndex(position + 1);
|
||||
this.add(axisSelector);
|
||||
this.add(axisSelector, "top");
|
||||
|
||||
removeButton = new JButton(Icons.EDIT_DELETE);
|
||||
removeButton.setToolTipText("Remove this plot");
|
||||
@ -79,7 +79,7 @@ public class PlotTypeSelector<T extends Groupable<G> & UnitValue, G extends Grou
|
||||
}
|
||||
|
||||
protected void addRemoveButton() {
|
||||
this.add(removeButton, "gapright 0");
|
||||
this.add(removeButton, "gapright 0, top");
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
|
@ -44,7 +44,7 @@ public class SimulationExportPanel extends CSVExportPanel<FlightDataType> {
|
||||
|
||||
private SimulationExportPanel(Simulation simulation, FlightDataBranch branch, FlightDataType[] types,
|
||||
boolean[] selected, CsvOptionPanel csvOptions, Component... extraComponents) {
|
||||
super(types, selected, csvOptions, extraComponents);
|
||||
super(types, selected, csvOptions, false, extraComponents);
|
||||
this.simulation = simulation;
|
||||
this.branch = branch;
|
||||
}
|
||||
@ -165,4 +165,9 @@ public class SimulationExportPanel extends CSVExportPanel<FlightDataType> {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayName(FlightDataType type) {
|
||||
return type.getName();
|
||||
}
|
||||
}
|
||||
|
@ -1041,7 +1041,7 @@ public class UITheme {
|
||||
|
||||
@Override
|
||||
public Color getDisabledTextColor() {
|
||||
return new Color(128, 128, 128);
|
||||
return new Color(128, 128, 128, 223);
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,11 +7,13 @@ import info.openrocket.core.startup.Application;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.GrayFilter;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -3,334 +3,240 @@ package info.openrocket.swing.gui.widgets;
|
||||
import info.openrocket.core.l10n.Translator;
|
||||
import info.openrocket.core.startup.Application;
|
||||
import info.openrocket.core.unit.Unit;
|
||||
import info.openrocket.core.unit.UnitGroup;
|
||||
import info.openrocket.core.util.UnitValue;
|
||||
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 net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import javax.swing.UIManager;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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 TAB = "TAB";
|
||||
private static Color ALTERNATE_ROW_COLOR;
|
||||
|
||||
protected final JTable table;
|
||||
protected final SelectionTableModel tableModel;
|
||||
private final JLabel selectedCountLabel;
|
||||
|
||||
protected final boolean[] selected;
|
||||
protected final T[] types;
|
||||
protected final Unit[] units;
|
||||
|
||||
protected final List<DataTypeRow> dataTypeRows = new ArrayList<>();
|
||||
protected final CsvOptionPanel csvOptions;
|
||||
protected final JLabel selectedCountLabel;
|
||||
|
||||
public CSVExportPanel(T[] types, boolean[] selected, CsvOptionPanel csvOptions, boolean separateRowForTable, Component... extraComponents) {
|
||||
super(new MigLayout("fill, flowy"));
|
||||
protected final T[] types;
|
||||
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.selected = selected;
|
||||
this.csvOptions = csvOptions;
|
||||
|
||||
this.units = new Unit[types.length];
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
units[i] = types[i].getUnitGroup().getDefaultUnit();
|
||||
}
|
||||
|
||||
//// Create the panel
|
||||
JPanel panel;
|
||||
JButton button;
|
||||
JPanel exportPanel = new JPanel(new MigLayout("ins 0, fill"));
|
||||
|
||||
// Set up the variable selection table
|
||||
tableModel = createTableModel();
|
||||
table = new JTable(tableModel);
|
||||
initializeTable(types);
|
||||
boolean addExtras = createExtraComponent(types[0], 0) != null;
|
||||
JPanel contentPanel = new JPanel(new GridBagLayout());
|
||||
contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.insets = new Insets(0, 0, 0, 0); // No padding
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
|
||||
// Add table
|
||||
panel = new JPanel(new MigLayout("fill"));
|
||||
panel.setBorder(BorderFactory.createTitledBorder(trans.get("SimExpPan.border.Vartoexport")));
|
||||
// Header
|
||||
c.gridy = 0;
|
||||
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
|
||||
button = new JButton(trans.get("SimExpPan.but.Selectall"));
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tableModel.selectAll();
|
||||
}
|
||||
});
|
||||
panel.add(button, "split 2, growx 1, sizegroup selectbutton");
|
||||
JPanel buttonPanel = new JPanel(new MigLayout("insets 0"));
|
||||
JButton selectAllButton = new JButton(trans.get("CSVExportPanel.but.Selectall"));
|
||||
selectAllButton.addActionListener(e -> selectAll());
|
||||
buttonPanel.add(selectAllButton, "split 2, growx");
|
||||
|
||||
button = new JButton(trans.get("SimExpPan.but.Selectnone"));
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tableModel.selectNone();
|
||||
}
|
||||
});
|
||||
panel.add(button, "growx 1, sizegroup selectbutton, wrap");
|
||||
JButton selectNoneButton = new JButton(trans.get("CSVExportPanel.but.Selectnone"));
|
||||
selectNoneButton.addActionListener(e -> selectNone());
|
||||
buttonPanel.add(selectNoneButton, "growx");
|
||||
|
||||
exportPanel.add(buttonPanel, "growx, wrap");
|
||||
|
||||
// Exporting xx variables out of yy
|
||||
// Selected count label
|
||||
selectedCountLabel = new JLabel();
|
||||
updateSelectedCount();
|
||||
panel.add(selectedCountLabel);
|
||||
exportPanel.add(selectedCountLabel, "growx");
|
||||
add(exportPanel, "grow, gapright para" + (separateRowForOptions ? ", spanx, wrap" : ""));
|
||||
|
||||
if (separateRowForTable) {
|
||||
this.add(panel, "spanx, grow 100, wrap");
|
||||
} else {
|
||||
this.add(panel, "grow 100, wrap");
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
||||
// CSV options and extra components
|
||||
if (separateRowForOptions) {
|
||||
add(csvOptions, "growx");
|
||||
for (Component comp : extraComponents) {
|
||||
add(comp, "growx, top");
|
||||
}
|
||||
}
|
||||
|
||||
// Space-filling panel
|
||||
if (!separateRowForTable) {
|
||||
panel = new JPanel();
|
||||
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();
|
||||
} else {
|
||||
JPanel optionsPanel = new JPanel(new MigLayout("insets 0"));
|
||||
optionsPanel.add(csvOptions, "growx");
|
||||
for (Component comp : extraComponents) {
|
||||
optionsPanel.add(comp, "growx");
|
||||
}
|
||||
});
|
||||
|
||||
// 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));
|
||||
add(optionsPanel, "growx, top");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean doExport() {
|
||||
throw new RuntimeException("Not implemented");
|
||||
private static void initColors() {
|
||||
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 n = 0;
|
||||
String str;
|
||||
|
||||
for (boolean b : selected) {
|
||||
if (b)
|
||||
n++;
|
||||
if (b) n++;
|
||||
}
|
||||
|
||||
String str;
|
||||
if (n == 1) {
|
||||
//// Exporting 1 variable out of
|
||||
str = trans.get("SimExpPan.ExportingVar.desc1") + " " + total + ".";
|
||||
str = trans.get("CSVExportPanel.ExportingVar.desc1") + " " + total + ".";
|
||||
} else {
|
||||
//// Exporting
|
||||
//// variables out of
|
||||
str = trans.get("SimExpPan.ExportingVar.desc2") + " " + n + " " +
|
||||
trans.get("SimExpPan.ExportingVar.desc3") + " " + total + ".";
|
||||
str = trans.get("CSVExportPanel.ExportingVar.desc2") + " " + n + " " +
|
||||
trans.get("CSVExportPanel.ExportingVar.desc3") + " " + total + ".";
|
||||
}
|
||||
|
||||
selectedCountLabel.setText(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* The table model for the variable selection.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
public boolean doExport() {
|
||||
throw new UnsupportedOperationException("Export not implemented in base class");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user