Merge branch 'unstable' into 3D-export

# Conflicts:
#	README.md
#	swing/src/net/sf/openrocket/gui/dialogs/AboutDialog.java
This commit is contained in:
SiboVG 2023-08-09 02:29:14 +02:00
commit 6d6f5287f3
124 changed files with 2149 additions and 1074 deletions

View File

@ -53,7 +53,7 @@ OpenRocket needs help to become even better. Implementing features, writing docu
- Daniel Williams, pod support, maintainer
- Joe Pfeiffer (maintainer)
- Billy Olsen (maintainer)
- Sibo Van Gool (3D OBJ export, maintainer)
- Sibo Van Gool (RASAero file format, 3D OBJ export, dark theme, maintainer)
- Neil Weinstock (tester, icons, forum support)
- H. Craig Miller (tester)

View File

@ -16,23 +16,18 @@
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Do not ask me again
RocketActions.lbl.Youcanchangedefop = You can change the default operation in the preferences.
RocketActions.showConfirmDialog.lbl1 = Delete the selected simulations?
RocketActions.showConfirmDialog.lbl2 = <html><i>This operation cannot be undone.</i>
RocketActions.showConfirmDialog.title = Delete simulations
RocketActions.DelCompAct.Delete = Delete
RocketActions.DelCompAct.ttip.Delete = Delete the selected component.
RocketActions.DelCompAct.ttip.Delete = Delete the selected components.
RocketActions.DelSimuAct.Delete = Delete
RocketActions.DelSimuAct.ttip.Delete = Delete the selected simulation.
RocketActions.DelSimuAct.ttip.Delete = Delete the selected simulations.
RocketActions.DelAct.Delete = Delete
RocketActions.DelAct.ttip.Delete = Delete the selected component or simulation.
RocketActions.DelAct.ttip.Delete = Delete the selected components or simulations.
RocketActions.CutAction.Cut = Cut
RocketActions.CutAction.ttip.Cut = Cut this component or simulation to the clipboard and delete from this design
RocketActions.CutAction.ttip.Cut = Cut these components or simulations to the clipboard and delete from this design
RocketActions.CopyAct.Copy = Copy
RocketActions.CopyAct.ttip.Copy = Copy this component (and subcomponents) to the clipboard.
RocketActions.CopyAct.ttip.Copy = Copy these components (and subcomponents) to the clipboard.
RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
RocketActions.PasteAct.ttip.Paste = Paste the components or simulations on the clipboard to the design.
RocketActions.PasteAct.invalidPosition.msg = Invalid paste position for object '%s', ignoring pasting.
RocketActions.PasteAct.invalidPosition.title = Could not paste
RocketActions.DuplicateAct.Duplicate = Duplicate
@ -385,15 +380,15 @@ pref.dlg.PrefBooleanSelector2 = Confirm
pref.dlg.Add = Add
pref.dlg.DescriptionArea.Adddirectories = Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
PreferencesDialog.lbl.language = Interface language:
PreferencesDialog.languages.default = System default
PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket.
PreferencesDialog.CancelOperation.title = Discard Preference Changes
PreferencesDialog.CancelOperation.msg.discardChanges = <html>Are you sure you want to <b>discard the preference changes</b>?</html>
generalprefs.lbl.language = Interface language
generalprefs.languages.default = System default
generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket.
generalprefs.lbl.UITheme = UI Theme
generalprefs.lbl.FontSize = UI Font Size
generalprefs.lbl.themeRestartOR = You must restart OpenRocket for the UI changes to take effect.
generalprefs.ImportWarning.title = Reload OpenRocket
generalprefs.ImportWarning.msg = You may need to restart OpenRocket for some of the changes to take effect.
@ -407,6 +402,10 @@ PreferencesOptionPanel.checkbox.userDirectories.ttip = If unchecked, user direct
PreferencesOptionPanel.checkbox.windowInfo = Export window information (position, size\u2026)
PreferencesOptionPanel.checkbox.windowInfo.ttip = If unchecked, window information (position, size\u2026) will not be exported.
! UI Themes
UITheme.Light = Light (Default)
UITheme.Dark = Dark
! Welcome dialog
welcome.dlg.title = Welcome to OpenRocket
welcome.dlg.lbl.thankYou = Thank you for downloading OpenRocket
@ -581,12 +580,23 @@ simpanel.but.ttip.editsim = Edit the selected simulation
simpanel.but.ttip.runsimu = Re-run the selected simulations
simpanel.but.ttip.deletesim = Delete the selected simulations
simpanel.pop.edit = Edit
simpanel.pop.edit.ttip= Edit the selected simulation(s)
simpanel.pop.cut= Cut
simpanel.pop.cut.ttip= Copy the selected simulation(s) to the clipboard and delete from this design
simpanel.pop.copy= Copy
simpanel.pop.copy.ttip= Copy the selected simulation(s) to the clipboard
simpanel.pop.paste= Paste
simpanel.pop.paste.ttip= Paste the simulation(s) on the clipboard to the design.
simpanel.pop.plot = Plot / Export
simpanel.pop.plot.ttip= Plot or Export the selected simulation(s)
simpanel.pop.run = Run
simpanel.pop.run.ttip= Run the selected simulation(s)
simpanel.pop.delete = Delete
simpanel.pop.delete.ttip= Delete the selected simulation(s)
simpanel.pop.duplicate = Duplicate
simpanel.pop.duplicate.ttip= Duplicate the selected simulation(s)
simpanel.pop.exportSimTableToCSV = Export simulation table as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulations as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulation(s) as CSV file
simpanel.pop.exportToCSV.save.dialog.title = Save as CSV file
simpanel.dlg.no.simulation.table.rows = Simulation table has no entries\u2026 Please run a simulation first.
simpanel.checkbox.donotask = Do not ask me again
@ -594,6 +604,7 @@ simpanel.lbl.defpref = You can change the default operation in the preferences.
simpanel.dlg.lbl.DeleteSim1 = Delete the selected simulations?
simpanel.dlg.lbl.DeleteSim2 = <html><i>This operation cannot be undone.</i>
simpanel.dlg.lbl.DeleteSim3 = Delete simulations
simpanel.col.Status = Status
simpanel.col.Name = Name
simpanel.col.Motors = Motors
simpanel.col.Configuration = Configuration
@ -615,6 +626,7 @@ simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulat
simpanel.ttip.noData = No simulation data available.
simpanel.ttip.noWarnings = <font color=\"gray\">No warnings.</font>
simpanel.ttip.warnings = <font color=\"red\">Warnings:</font>
simpanel.msg.invalidCopySelection = Invalid copy selection
! SimulationRunDialog
SimuRunDlg.title.RunSim = Running simulations\u2026
@ -1192,6 +1204,7 @@ InnerTubeCfg.tab.ttip.Radialpos = Radial position
InnerTubeCfg.lbl.Selectclustercfg = Select cluster configuration:
InnerTubeCfg.lbl.TubeSep = Tube separation:
InnerTubeCfg.lbl.ttip.TubeSep = The separation of the tubes, 1.0 = touching each other
InnerTubeCfg.lbl.ttip.TubeSepAbs = The separation of the tubes, 0 = touching each other
InnerTubeCfg.lbl.Rotation = Rotation:
InnerTubeCfg.lbl.ttip.Rotation = Rotation angle of the cluster configuration
InnerTubeCfg.lbl.Rotangle = Rotation angle of the cluster configuration
@ -1200,6 +1213,10 @@ InnerTubeCfg.lbl.longA1 = <html>Split the cluster into separate components.<br>
InnerTubeCfg.lbl.longA2 = This also duplicates all components attached to this inner tube.
InnerTubeCfg.but.Resetsettings = Reset settings
InnerTubeCfg.but.ttip.Resetsettings = Reset the separation and rotation to the default values
InnerTubeCfg.radioBut.Relative = Relative
InnerTubeCfg.radioBut.Relative.ttip = The separation is measured relative to the outer diameter of the inner tube
InnerTubeCfg.radioBut.Absolute = Absolute
InnerTubeCfg.radioBut.Absolute.ttip = The separation is measured in length units
! LaunchLugConfig
LaunchLugCfg.lbl.Length = Length:
@ -2025,6 +2042,7 @@ Warning.TUBE_SEPARATION = Space between tube fins may not simulate accurately.
Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
Warning.EMPTY_BRANCH = Simulation branch contains no data
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
Warning.EARLY_SEPARATION = Stages separated before clearing launch rod/rail
! Scale dialog
ScaleDialog.lbl.scaleRocket = Entire rocket
@ -2319,7 +2337,7 @@ ComponentPresetChooserDialog.menu.units = Units
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database
ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog<br>Directly apply a preset by double-clicking it or by selecting it and closing this window.
ComponentPresetChooserDialog.checkbox.alwaysOpenPreset = Always open this dialog when creating a new %s
table.column.Favorite = Favorite
table.column.Favorite = \u2026 Favorite
table.column.Legacy = Legacy
table.column.Manufacturer = Manufacturer
table.column.PartNo = Part Number

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_ar.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = لا تسألني مجددا
RocketActions.lbl.Youcanchangedefop = يمكنك تغيير العملية الافتراضية في التفضيلات.
RocketActions.showConfirmDialog.lbl1 = إحذف المحاكاة المختارة؟
RocketActions.showConfirmDialog.lbl2 = <html><i>لا يمكنك التراجع عن هذه العملية.</i>
RocketActions.showConfirmDialog.title = إحذف كل المحاكاة
RocketActions.DelCompAct.Delete = إحذف
RocketActions.DelCompAct.ttip.Delete = إحذف القطعة المختارة
RocketActions.DelSimuAct.Delete = إحذف
@ -348,9 +343,6 @@ pref.dlg.PrefBooleanSelector2 = تأكيد
pref.dlg.Add = أضف
pref.dlg.DescriptionArea.Adddirectories =.ملفات محرك روكسيم أو أرشيفات زيب مفصولة بفاصلة منقوطة لتحميل منحنيات الدفع الخارجية. ستدخل التغييرات حيز التنفيذ في المرة التالية التي تفتح فيها أوبنروكت (* .rse)أو RASP ملفات محرك (* .eng), أضف الدلائل
PreferencesDialog.lbl.language = :لغة الواجهة
PreferencesDialog.languages.default = النظام الافتراضي
PreferencesDialog.lbl.languageEffect = .ستتغير اللغة في المرة التالية التي تعيد تشغيل أوبنروكت
generalprefs.lbl.language = :لغة الواجهة
generalprefs.languages.default = النظام الافتراضي
generalprefs.lbl.languageEffect = .ستتغير اللغة في المرة التالية التي تعيد تشغيل أوبنروكت

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_cs.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Prí\u0161te se me neptejte
RocketActions.lbl.Youcanchangedefop = Mu\u017Eete zmenit výchozí operaci v nastavení.
RocketActions.showConfirmDialog.lbl1 = Chcete smazat oznacenou simulaci?
RocketActions.showConfirmDialog.lbl2 = <html><i>Tuto operaci nelze vzít zpet.</i>
RocketActions.showConfirmDialog.title = Sma\u017E simulace
RocketActions.DelCompAct.Delete = Sma\u017E
RocketActions.DelCompAct.ttip.Delete = Sma\u017E oznacenou komponentu.
RocketActions.DelSimuAct.Delete = Sma\u017E
@ -269,9 +264,9 @@ pref.dlg.PrefBooleanSelector2 = Potvrd
pref.dlg.Add = Pridej
pref.dlg.DescriptionArea.Adddirectories = Pridej adresáre, soubory RASP motor (*.eng), RockSim engine soubory (*.rse) nebo ZIP archiv oddelený oddelovacem (;) k nahrání externích výkonových prubehu. Zmeny se projeví po restaru programu OpenRocket.
PreferencesDialog.lbl.language = Jazyk rohranní:
PreferencesDialog.languages.default = Výchozí
PreferencesDialog.lbl.languageEffect = Jazyk se zmení pri dal\u0161ím spu\u0161tení programu OpenRocket.
generalprefs.lbl.language = Jazyk rohranní:
generalprefs.languages.default = Výchozí
generalprefs.lbl.languageEffect = Jazyk se zmení pri dal\u0161ím spu\u0161tení programu OpenRocket.
! Software update checker
update.dlg.error.title = Nemohu získat informace o aktualizacích

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_de.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Nicht wieder fragen
RocketActions.lbl.Youcanchangedefop = Die Standardaktion kann in den Einstellungen geändert werden.
RocketActions.showConfirmDialog.lbl1 = Simulationen löschen?
RocketActions.showConfirmDialog.lbl2 = <html><i>Diese Aktion kann nicht rückgängig gemacht werden.</i>
RocketActions.showConfirmDialog.title = Simulationen löschen
RocketActions.DelCompAct.Delete = Löschen
RocketActions.DelCompAct.ttip.Delete = Die ausgewählte Komponente löschen.
RocketActions.DelSimuAct.Delete = Löschen
@ -271,9 +266,9 @@ pref.dlg.PrefBooleanSelector2 = Best
pref.dlg.Add = Hinzufügen
pref.dlg.DescriptionArea.Adddirectories = Um eigene Schubkurven zu laden, Verzeichnisse, RASP-Motordateien (*.eng), RockSim-Motordateien (*.rse) oder ZIP-Archive mit Semikolon getrennt eingeben. Änderungen werden beim nächsten Neustart von OpenRocket übernommen.
PreferencesDialog.lbl.language = Sprache:
PreferencesDialog.languages.default = Systemeinstellung
PreferencesDialog.lbl.languageEffect = Die Sprache wird beim nächsten Neustart von OpenRocket geändert.
generalprefs.lbl.language = Sprache:
generalprefs.languages.default = Systemeinstellung
generalprefs.lbl.languageEffect = Die Sprache wird beim nächsten Neustart von OpenRocket geändert.
! Software update checker
update.dlg.error.title = Es konnten keine Informationen über Programmaktualisierungen empfangen werden.

View File

@ -733,9 +733,9 @@ PlotDialog.title.Flightdataplot = Representaci\u00f3n de los datos de vuelo
ComponentTreeRenderer.total = total
PreferencesDialog.languages.default = Idioma por defecto
PreferencesDialog.lbl.language = Idioma de la interfaz:
PreferencesDialog.lbl.languageEffect = El idioma cambiar\u00e1 la pr\u00f3xima vez que abra OpenRocket.
generalprefs.languages.default = Idioma por defecto
generalprefs.lbl.language = Idioma de la interfaz:
generalprefs.lbl.languageEffect = El idioma cambiar\u00e1 la pr\u00f3xima vez que abra OpenRocket.
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de piezas
@ -811,12 +811,6 @@ RocketActions.NewStageAct.Newstage = Nueva etapa
RocketActions.NewStageAct.ttip.Newstage = A\u00f1adir una nueva etapa al dise\u00f1o del cohete
RocketActions.PasteAct.Paste = Pegar
RocketActions.PasteAct.ttip.Paste = Pegar al portapapeles
! RocketActions
RocketActions.checkbox.Donotaskmeagain = No volver a preguntarme
RocketActions.lbl.Youcanchangedefop = Puede modificar la operaci\u00f3n por defecto con sus preferencias
RocketActions.showConfirmDialog.lbl1 = \u00bfBorrar las simulaciones seleccionadas?
RocketActions.showConfirmDialog.lbl2 = <html><i>Esta operaci\u00f3n no puede deshacerse.</i>
RocketActions.showConfirmDialog.title = Borrar simulaciones
RocketCfg.lbl.Comments = Comentarios:
RocketCfg.lbl.Designer = Dise\u00f1ador:

View File

@ -725,9 +725,9 @@ PlotDialog.title.Flightdataplot = Trac\u00E9 du vol
ComponentTreeRenderer.total = total
PreferencesDialog.languages.default = Valeur syst\u00E8me par d\u00E9faut
PreferencesDialog.lbl.language = Langue du programme:
PreferencesDialog.lbl.languageEffect = La langue sera chang\u00E9e apr\u00E8s avoir red\u00E9marr\u00E9 OpenRocket.
generalprefs.languages.default = Valeur syst\u00E8me par d\u00E9faut
generalprefs.lbl.language = Langue du programme:
generalprefs.lbl.languageEffect = La langue sera chang\u00E9e apr\u00E8s avoir red\u00E9marr\u00E9 OpenRocket.
PresetModel.lbl.custompreset = Personnalisé
PresetModel.lbl.partsLib = Biblioth\u00E8que de pi\u00E8ces
@ -802,12 +802,6 @@ RocketActions.NewStageAct.Newstage = Nouvel \u00E9tage
RocketActions.NewStageAct.ttip.Newstage = Ajouter un nouvel \u00E9tage au projet.
RocketActions.PasteAct.Paste = Coller
RocketActions.PasteAct.ttip.Paste = Coller la pi\u00E8ce ou simulation pr\u00E9sente dans le presse papier dans le projet.
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Ne plus me demander
RocketActions.lbl.Youcanchangedefop = Vous pouvez changer le mode op\u00E9ratoire par d\u00E9faut dans les pr\u00E9ferences.
RocketActions.showConfirmDialog.lbl1 = Supprimer les simulations s\u00E9lectionn\u00E9es?
RocketActions.showConfirmDialog.lbl2 = <html><i>Cette op\u00E9ration n'est pas r\u00E9versible.</i>
RocketActions.showConfirmDialog.title = Effacer les simulations
RocketCfg.lbl.Comments = Commentaires:
RocketCfg.lbl.Designer = Concepteur:

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_it.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Non chiedermelo piu'
RocketActions.lbl.Youcanchangedefop = Puoi cambiare le operazioni prestabilite in PREFERENZE.
RocketActions.showConfirmDialog.lbl1 = Cancello le simulazioni selezionate?
RocketActions.showConfirmDialog.lbl2 = <html><i>Questa operazione non puo' essere annullata.</i>
RocketActions.showConfirmDialog.title = Cancello Simulazioni
RocketActions.DelCompAct.Delete = Cancella
RocketActions.DelCompAct.ttip.Delete = Cancello il componente selezionato.
RocketActions.DelSimuAct.Delete = Cancella
@ -273,9 +268,9 @@ pref.dlg.PrefBooleanSelector2 = Conferma
pref.dlg.Add = Aggiungi
pref.dlg.DescriptionArea.Adddirectories = Aggiungi cartelle, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separate da puntoevirgola (;) per caricare curve di spinta esterne. I cambiamenti avranno effetto la prossima volta che avvierai OpenRocket.
PreferencesDialog.lbl.language = Lingua dell'interfaccia:
PreferencesDialog.languages.default = Predefinita di sistema
PreferencesDialog.lbl.languageEffect = La lingua sara' cambiata la prossima volta che avvierai OpenRocket.
generalprefs.lbl.language = Lingua dell'interfaccia:
generalprefs.languages.default = Predefinita di sistema
generalprefs.lbl.languageEffect = La lingua sara' cambiata la prossima volta che avvierai OpenRocket.
! Software update checker
update.dlg.error.title = Non sono in grado di recuperare informazioni sugli aggiornamenti

View File

@ -12,11 +12,6 @@
debug.currentFile = messages_ja.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u6B21\u56DE\u304B\u3089\u8868\u793A\u3057\u306A\u3044
RocketActions.lbl.Youcanchangedefop = \u8A2D\u5B9A\u306E\u4E2D\u3067\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u5909\u66F4\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059
RocketActions.showConfirmDialog.lbl1 = \u9078\u629E\u3057\u305F\u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3\u3092\u6D88\u53BB\u3057\u307E\u3059\u304B\uFF1F
RocketActions.showConfirmDialog.lbl2 = <html><i>\u6D88\u53BB\u3057\u305F\u3089\u5FA9\u5143\u3067\u304D\u307E\u305B\u3093</i>
RocketActions.showConfirmDialog.title = \u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3\u306E\u524A\u9664
RocketActions.DelCompAct.Delete = \u524A\u9664
RocketActions.DelCompAct.ttip.Delete = \u9078\u629E\u3057\u305F\u90E8\u54C1\u306E\u524A\u9664
RocketActions.DelSimuAct.Delete = \u524A\u9664
@ -270,9 +265,9 @@ pref.dlg.PrefBooleanSelector2 = \u78BA\u8A8D
pref.dlg.Add = \u8FFD\u52A0
pref.dlg.DescriptionArea.Adddirectories = \u30D5\u30A9\u30EB\u30C0, RASP motor files (*.eng), RockSim engine files (*.rse) \u3082\u3057\u304F\u306F ZIP archives \u3092\u30BB\u30DF\u30B3\u30ED\u30F3(;)\u306B\u3088\u3063\u3066\u5206\u3051\u3089\u308C\u305F\u5F62\u3067\u8FFD\u52A0\u306E\u63A8\u529B\u5C65\u6B74\u3068\u3057\u3066\u8FFD\u52A0\u3067\u304D\u307E\u3059\u3002\u3053\u306E\u5909\u66F4\u306FOpenRocket\u306E\u518D\u8D77\u52D5\u6642\u306B\u6709\u52B9\u306B\u306A\u308A\u307E\u3059
PreferencesDialog.lbl.language = \u8A00\u8A9E\uFF1A
PreferencesDialog.languages.default = \u30B7\u30B9\u30C6\u30E0\u8A00\u8A9E
PreferencesDialog.lbl.languageEffect = \u8A00\u8A9E\u306F\u518D\u8D77\u52D5\u6642\u306B\u5909\u66F4\u3055\u308C\u307E\u3059
generalprefs.lbl.language = \u8A00\u8A9E\uFF1A
generalprefs.languages.default = \u30B7\u30B9\u30C6\u30E0\u8A00\u8A9E
generalprefs.lbl.languageEffect = \u8A00\u8A9E\u306F\u518D\u8D77\u52D5\u6642\u306B\u5909\u66F4\u3055\u308C\u307E\u3059
! Software update checker
update.dlg.error.title = \u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u60C5\u5831\u306E\u8AAD\u307F\u51FA\u3057\u304C\u3067\u304D\u307E\u305B\u3093

View File

@ -18,11 +18,6 @@
debug.currentFile = messages_nl.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Niet opnieuw vragen
RocketActions.lbl.Youcanchangedefop = U kan de standaardbewerking veranderen in de voorkeuren.
RocketActions.showConfirmDialog.lbl1 = Geselecteerde simulatie verwijderen?
RocketActions.showConfirmDialog.lbl2 = <html><i>Deze bewerking kan niet ongedaan worden.</i>
RocketActions.showConfirmDialog.title = Verwijder simulaties
RocketActions.DelCompAct.Delete = Verwijder
RocketActions.DelCompAct.ttip.Delete = Verwijder het geselecteerde onderdeel.
RocketActions.DelSimuAct.Delete = Verwijder
@ -350,10 +345,6 @@ pref.dlg.PrefBooleanSelector2 = Bevestig
pref.dlg.Add = Voeg toe
pref.dlg.DescriptionArea.Adddirectories = Voeg folders, RASP motorbestanden (*.eng), RockSim motorbestanden (*.rse) of ZIP-archieven gescheiden door een puntkomma (;) om externe stuwkrachtcurves te laden. Wijzigingen zullen van kracht gaan de volgende keer dat u OpenRocket start.
PreferencesDialog.lbl.language = Interface taal:
PreferencesDialog.languages.default = Systeemstandaard
PreferencesDialog.lbl.languageEffect = De taal zal veranderen de volgende keer dat u OpenRocket start.
generalprefs.lbl.language = Interface taal
generalprefs.languages.default = Systeemstandaard
generalprefs.lbl.languageEffect = De taal zal veranderen de volgende keer dat u OpenRocket start.

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_pl.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Nie pytaj ponownie
RocketActions.lbl.Youcanchangedefop = Domy\u015Bln\u0105 operacj\u0119 mo\u017Cna zmieni\u0107 w ustawieniach.
RocketActions.showConfirmDialog.lbl1 = Usun\u0105\u0107 zaznaczone symulacje?
RocketActions.showConfirmDialog.lbl2 = <html><i>Tej operacji nie mo\u017Cna cofn\u0105\u0107.</i>
RocketActions.showConfirmDialog.title = Usu\u0144 symulacje
RocketActions.DelCompAct.Delete = Usu\u0144
RocketActions.DelCompAct.ttip.Delete = Usu\u0144 wybran\u0105 cz\u0119\u015B\u0107
RocketActions.DelSimuAct.Delete = Usu\u0144
@ -270,10 +265,10 @@
pref.dlg.PrefBooleanSelector2 = Potwierd\u017A
pref.dlg.Add = Dodaj
pref.dlg.DescriptionArea.Adddirectories = Dodaj katalogi, pliki silnikowe RASP (*.eng), Pliki silnikowe RockSim (*.rse) albo archiwa ZIP rozdzielone \u015Brednikiem (;) by za\u0142adowa\u0107 zewn\u0119trzne krzywe si\u0142y ci\u0105gu. Zmiany zostan\u0105 wprowadzone przy kolejnym uruchomieniu OpenRocket.
PreferencesDialog.lbl.language = J\u0119zyk programu:
PreferencesDialog.languages.default = Domy\u015Blny j\u0119zyk systemu
PreferencesDialog.lbl.languageEffect = Nowy j\u0119zyk zostanie ustawiony przy kolejnym uruchomieniu OpenRocket.
generalprefs.lbl.language = J\u0119zyk programu:
generalprefs.languages.default = Domy\u015Blny j\u0119zyk systemu
generalprefs.lbl.languageEffect = Nowy j\u0119zyk zostanie ustawiony przy kolejnym uruchomieniu OpenRocket.
! Software update checker
update.dlg.error.title = Nie mo\u017Cna uzyska\u0107 informacji o aktualizacji

View File

@ -709,9 +709,9 @@ PlotDialog.lbl.Chart = Clique e arraste para baixo+direita para am
# PlotDialog
PlotDialog.title.Flightdataplot = Plotagem dos dados de voo
PreferencesDialog.languages.default = Padr\u00e3o do sistema
PreferencesDialog.lbl.language = Idioma da interface:
PreferencesDialog.lbl.languageEffect = A linguagem vai mudar na pr\u00f3xima vez que voc\u00ea iniciar o OpenRocket.
generalprefs.languages.default = Padr\u00e3o do sistema
generalprefs.lbl.language = Idioma da interface:
generalprefs.lbl.languageEffect = A linguagem vai mudar na pr\u00f3xima vez que voc\u00ea iniciar o OpenRocket.
PresetModel.lbl.custompreset = Personalizado
PresetModel.lbl.partsLib = Biblioteca de pe\u00e7as
@ -786,12 +786,6 @@ RocketActions.NewStageAct.Newstage = Novo est\u00e1gio
RocketActions.NewStageAct.ttip.Newstage = Adicionar um novo est\u00e1gio ao projeto do foguete.
RocketActions.PasteAct.Paste = Colar
RocketActions.PasteAct.ttip.Paste = Cole o componente ou simula\u00e7\u00e3o na \u00e1rea da transfer\u00eancia para o projeto.
# RocketActions
RocketActions.checkbox.Donotaskmeagain = N\u00e3o me pergunte novamente
RocketActions.lbl.Youcanchangedefop = Voc\u00ea pode alterar a opera\u00e7\u00e3o padr\u00e3o em Prefer\u00eancias.
RocketActions.showConfirmDialog.lbl1 = Excluir as simula\u00e7\u00f5es selecionadas?
RocketActions.showConfirmDialog.lbl2 = <html><i>Esta opera\u00e7\u00e3o n\u00e3o poder\u00e1 ser desfeita.</i>
RocketActions.showConfirmDialog.title = Excluir simula\u00e7\u00f5es
RocketCfg.lbl.Comments = Coment\u00e1rios:
RocketCfg.lbl.Designer = Projetista:

View File

@ -16,11 +16,6 @@
debug.currentFile = messages_ru.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C
RocketActions.lbl.Youcanchangedefop = \u0412\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445.
RocketActions.showConfirmDialog.lbl1 = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u042D\u0442\u0443 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u043D\u0435\u043B\u044C\u0437\u044F \u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C.</i>
RocketActions.showConfirmDialog.title = \u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432
RocketActions.DelCompAct.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C
RocketActions.DelCompAct.ttip.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442.
RocketActions.DelSimuAct.Delete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C
@ -346,10 +341,6 @@ pref.dlg.PrefBooleanSelector2 = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434
pref.dlg.Add = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C
pref.dlg.DescriptionArea.Adddirectories = \u0414\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0432\u043E\u0438\u0445 \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 \u0434\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0438, \u0444\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RASP (*.eng), \u0444\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RockSim (*.rse) \u0438\u043B\u0438 ZIP-\u0430\u0440\u0445\u0438\u0432\u044B, \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435 \u0442\u043E\u0447\u043A\u043E\u0439 \u0441 \u0437\u0430\u043F\u044F\u0442\u043E\u0439 (;). \u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u044F\u0442 \u0432 \u0441\u0438\u043B\u0443 \u043F\u0440\u0438 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.
PreferencesDialog.lbl.language = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:
PreferencesDialog.languages.default = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439
PreferencesDialog.lbl.languageEffect = \u042F\u0437\u044B\u043A \u0441\u043C\u0435\u043D\u0438\u0442\u0441\u044F \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.
generalprefs.lbl.language = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
generalprefs.languages.default = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439
generalprefs.lbl.languageEffect = \u042F\u0437\u044B\u043A \u0441\u043C\u0435\u043D\u0438\u0442\u0441\u044F \u043F\u0440\u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket.

View File

@ -17,12 +17,6 @@ purposes)
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = Yeniden Tekrarlama
RocketActions.lbl.Youcanchangedefop = Hatal\u0131 \u00c7al\u0131\u015fmay\u0131 De\u011fi\u015ftirebilirsin
in the preferences.
RocketActions.showConfirmDialog.lbl1 = Se\u00e7ili sim\u00fclasyonlar\u0131 silmek ister misiniz?
RocketActions.showConfirmDialog.lbl2 = <html><i>Bu \u00e7al\u0131\u015fma tamamlanmad\u0131.</i>
RocketActions.showConfirmDialog.title = Sim\u00fclasyonlar\u0131 Sil
RocketActions.DelCompAct.Delete = Sil
RocketActions.DelCompAct.ttip.Delete = Se\u00e7ili par\u00e7ay\u0131 sil.
RocketActions.DelSimuAct.Delete = Sil

View File

@ -18,11 +18,6 @@
debug.currentFile = messages.properties
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u0411\u0456\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0438\u0442\u0430\u0442\u0438
RocketActions.lbl.Youcanchangedefop = \u0412\u0438 \u043C\u043E\u0436\u0435\u0442\u0435 \u0437\u043C\u0456\u043D\u0438\u0442\u0438 \u0442\u0438\u043F\u043E\u0432\u0443 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u0432 \u043E\u043F\u0446\u0438\u044F\u0445.
RocketActions.showConfirmDialog.lbl1 = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0443 \u0441\u0438\u043C\u0443\u043B\u044F\u0446\u0456\u044E?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u0426\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0456\u044F \u043D\u0435 \u043C\u043E\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0456\u0434\u043C\u0456\u043D\u0435\u043D\u0430.</i>
RocketActions.showConfirmDialog.title = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0441\u0438\u043C\u0443\u043B\u044F\u0446\u0456\u044E
RocketActions.DelCompAct.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438
RocketActions.DelCompAct.ttip.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043D\u0443 \u0447\u0430\u0441\u0442\u0438\u043D\u0443.
RocketActions.DelSimuAct.Delete = \u0412\u0434\u0430\u043B\u0438\u0442\u0438
@ -309,9 +304,9 @@ pref.dlg.PrefBooleanSelector2 = Confirm
pref.dlg.Add = Add
pref.dlg.DescriptionArea.Adddirectories = Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
PreferencesDialog.lbl.language = Interface language:
PreferencesDialog.languages.default = System default
PreferencesDialog.lbl.languageEffect = The language will change the next time you start OpenRocket.
generalprefs.lbl.language = Interface language:
generalprefs.languages.default = System default
generalprefs.lbl.languageEffect = The language will change the next time you start OpenRocket.
! Software update checker
update.dlg.error.title = Unable to retrieve update information

View File

@ -797,9 +797,9 @@ PlotConfiguration.Verticalmotion = \u5782\u76F4\u8FD0\u52A8 vs. \u65F6\u95F
PlotDialog.CheckBox.Showdatapoints = \u663E\u793A\u6570\u636E\u70B9
PlotDialog.lbl.Chart = \u5DE6\u952E\u62D6\u62FD\u79FB\u52A8\u6570\u636E\u533A. \u6EDA\u8F6E\u7F29\u653E. ctrl-\u6EDA\u8F6E\u4EC5\u7F29\u653EX\u8F74. ctrl-\u5DE6\u952E\u62D6\u62FD\u79FB\u52A8\u89C6\u56FE. \u53F3\u952E\u8FC7\u62FD\u8C03\u6574\u663E\u793A\u5927\u5C0F.
PreferencesDialog.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
PreferencesDialog.lbl.language = \u754C\u9762\u8BED\u8A00:
PreferencesDialog.lbl.languageEffect = \u8BED\u8A00\u8BBE\u7F6E\u5C06\u5728OpenRocket\u91CD\u542F\u540E\u751F\u6548
generalprefs.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
generalprefs.lbl.language = \u754C\u9762\u8BED\u8A00:
generalprefs.lbl.languageEffect = \u8BED\u8A00\u8BBE\u7F6E\u5C06\u5728OpenRocket\u91CD\u542F\u540E\u751F\u6548
PresetModel.lbl.custompreset = \u5b9a\u5236
PresetModel.lbl.partsLib = \u96f6\u4ef6\u5e93
@ -875,12 +875,6 @@ RocketActions.NewStageAct.Newstage = \u65B0\u5EFA\u4E00\u7EA7
RocketActions.NewStageAct.ttip.Newstage = \u5728\u8BBE\u8BA1\u4E2D\u65B0\u5EFA\u4E00\u7EA7
RocketActions.PasteAct.Paste = \u7C98\u8D34
RocketActions.PasteAct.ttip.Paste = \u5C06\u526A\u8D34\u677F\u91CC\u7684\u90E8\u4EF6\u6216\u4EFF\u771F\u7C98\u8D34\u5230\u8BE5\u8BBE\u8BA1\u4E2D
! RocketActions
RocketActions.checkbox.Donotaskmeagain = \u4E0D\u518D\u63D0\u793A
RocketActions.lbl.Youcanchangedefop = \u4F60\u53EF\u4EE5\u4FEE\u6539\u7F3A\u7701\u8BBE\u7F6E
RocketActions.showConfirmDialog.lbl1 = \u5220\u9664\u9009\u5B9A\u4EFF\u771F?
RocketActions.showConfirmDialog.lbl2 = <html><i>\u8BE5\u64CD\u4F5C\u65E0\u6CD5\u64A4\u9500</i>
RocketActions.showConfirmDialog.title = \u5220\u9664\u4EFF\u771F
RocketCfg.lbl.Comments = \u6CE8\u91CA:
RocketCfg.lbl.Designer = \u8BBE\u8BA1\u4EBA:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 405 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -383,12 +383,7 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
* @param simulation the simulation to be added
*/
public void addSimulation(Simulation simulation) {
simulations.add(simulation);
FlightConfigurationId simId = simulation.getId();
if( !rocket.containsFlightConfigurationID( simId )){
rocket.createFlightConfiguration(simId);
}
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
addSimulation(simulation, simulations.size());
}
/**
@ -399,6 +394,10 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL
*/
public void addSimulation(Simulation simulation, int n) {
simulations.add(n, simulation);
FlightConfigurationId simId = simulation.getId();
if( !rocket.containsFlightConfigurationID( simId )){
rocket.createFlightConfiguration(simId);
}
fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
}

View File

@ -386,7 +386,11 @@ public abstract class Warning extends Message {
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
/** A <code>Warning</code> that stage separation occurred at other than the last stage */
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
/** A <code>Warning</code> that stage separation occurred before the rocket cleared the launch rod or rail */
public static final Warning EARLY_SEPARATION = new Other(trans.get("Warning.EARLY_SEPARATION"));
public static final Warning EMPTY_BRANCH = new Other(trans.get("Warning.EMPTY_BRANCH"));
}

View File

@ -170,14 +170,14 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
* @return the previous stage in the rocket
*/
public AxialStage getUpperStage() {
if( null == this.parent ) {
if (this.parent == null) {
return null;
}else if(Rocket.class.isAssignableFrom(this.parent.getClass()) ){
final int thisIndex = getStageNumber();
if( 0 < thisIndex ){
return (AxialStage)parent.getChild(thisIndex-1);
} else if (Rocket.class.isAssignableFrom(this.parent.getClass())) {
final int thisIndex = parent.getChildPosition(this);
if (thisIndex > 0) {
return (AxialStage) parent.getChild(thisIndex-1);
}
}else {
} else {
return this.parent.getStage();
}
return null;

View File

@ -170,6 +170,11 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
" Please set setClusterConfiguration(ClusterConfiguration) instead.",
new UnsupportedOperationException("InnerTube.setInstanceCount(..) on an"+this.getClass().getSimpleName()));
}
@Override
public boolean isAfter(){
return false;
}
/**
* Get the cluster scaling. A value of 1.0 indicates that the tubes are packed
@ -177,14 +182,10 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
* pack inside each other.
*/
public double getClusterScale() {
mutex.verify();
return clusterScale;
}
@Override
public boolean isAfter(){
return false;
}
/**
* Set the cluster scaling.
* @see #getClusterScale()
@ -203,6 +204,23 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
clusterScale = scale;
fireComponentChangeEvent(new ComponentChangeEvent(this, ComponentChangeEvent.MASS_CHANGE));
}
/**
* Get the cluster scaling as an absolute distance measurement. A value of 0 indicates that the tubes are packed
* touching each other, larger values separate the tubes and smaller values pack inside each other.
*/
public double getClusterScaleAbsolute() {
return (getClusterScale() - 1) * getOuterRadius() * 2;
}
/**
* Set the absolute cluster scaling (in terms of distance).
* @see #getClusterScaleAbsolute()
*/
public void setClusterScaleAbsolute(double scale) {
double scaleRel = scale / (getOuterRadius() * 2) + 1;
setClusterScale(scaleRel);
}
@ -242,27 +260,21 @@ public class InnerTube extends ThicknessRingComponent implements AxialPositionab
}
public List<Coordinate> getClusterPoints() {
List<Coordinate> list = new ArrayList<Coordinate>(getInstanceCount());
List<Coordinate> list = new ArrayList<>(getInstanceCount());
List<Double> points = cluster.getPoints(clusterRotation - getRadialDirection());
double separation = getClusterSeparation();
double yOffset = this.radialPosition * Math.cos(this.radialDirection);
double zOffset = this.radialPosition * Math.sin(this.radialDirection);
for (int i = 0; i < points.size() / 2; i++) {
list.add(new Coordinate(0, points.get(2 * i) * separation, points.get(2 * i + 1) * separation));
list.add(new Coordinate(0, points.get(2 * i) * separation + yOffset, points.get(2 * i + 1) * separation + zOffset));
}
return list;
}
@Override
public Coordinate[] getInstanceOffsets(){
if ( 1 == getInstanceCount()) {
double yOffset = this.radialPosition * Math.cos(this.radialDirection);
double zOffset = this.radialPosition * Math.sin(this.radialDirection);
return new Coordinate[] { Coordinate.ZERO.add(0.0, yOffset, zOffset) };
}
List<Coordinate> points = getClusterPoints();
return points.toArray( new Coordinate[ points.size() ]);
return points.toArray(new Coordinate[0]);
}
// @Override

View File

@ -849,12 +849,20 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
// have a radial offset of 0 from their centerline, we are in line.
if ((this.parent instanceof RingInstanceable) &&
(!MathUtil.equals(this.parent.getRadiusMethod().getRadius(this.parent.parent, this, this.parent.getRadiusOffset()), 0)))
(!MathUtil.equals(this.parent.getRadiusMethod().getRadius(
this.parent.parent, this, this.parent.getRadiusOffset()), 0)))
return false;
if ((candidate.parent instanceof RingInstanceable) &&
(!MathUtil.equals(candidate.parent.getRadiusMethod().getRadius(candidate.parent.parent, candidate, candidate.parent.getRadiusOffset()), 0)))
return false;
if (candidate.parent instanceof RingInstanceable) {
// We need to check if the grandparent of the candidate is a body tube and if the outer radius is automatic.
// If so, then this would cause an infinite loop when checking the radius of the radiusMethod.
if (candidate.parent.parent == this && (this.isAftRadiusAutomatic() || this.isForeRadiusAutomatic())) {
return false;
} else {
return MathUtil.equals(candidate.parent.getRadiusMethod().getRadius(
candidate.parent.parent, candidate, candidate.parent.getRadiusOffset()), 0);
}
}
return true;
}

View File

@ -118,6 +118,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
setForeShoulderRadius(getForeShoulderRadius());
}
public void setForeRadius(double radius) {
@ -207,6 +209,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
setAftShoulderRadius(getAftShoulderRadius());
}
public void setAftRadius(double radius) {
@ -398,6 +402,7 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
((Transition) listener).setForeShoulderRadius(foreShoulderRadius);
}
}
foreShoulderRadius = Math.min(foreShoulderRadius, getForeRadius());
if (MathUtil.equals(this.foreShoulderRadius, foreShoulderRadius))
return;
@ -471,6 +476,8 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
}
}
aftShoulderRadius = Math.min(aftShoulderRadius, getAftRadius());
if (MathUtil.equals(this.aftShoulderRadius, aftShoulderRadius))
return;
this.aftShoulderRadius = aftShoulderRadius;

View File

@ -485,6 +485,11 @@ public class BasicEventSimulationEngine implements SimulationEngine {
currentStatus.getWarnings().add(Warning.SEPARATION_ORDER);
}
// If I haven't cleared the rail yet, flag a warning
if (!currentStatus.isLaunchRodCleared()) {
currentStatus.getWarnings().add(Warning.EARLY_SEPARATION);
}
// Create a new simulation branch for the booster
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);

View File

@ -118,6 +118,8 @@ public abstract class Preferences implements ChangeSource {
public static final String LAUNCH_USE_ISA = "LaunchUseISA";
public static final String SIMULATION_TIME_STEP = "SimulationTimeStep";
public static final String GEODETIC_COMPUTATION = "GeodeticComputationStrategy";
public static final String UI_THEME = "UITheme";
private static final AtmosphericModel ISA_ATMOSPHERIC_MODEL = new ExtendedISAModel();
@ -549,11 +551,6 @@ public abstract class Preferences implements ChangeSource {
fireChangeEvent();
}
public final float getRocketInfoFontSize() {
return (float) (11.0 + 3 * Application.getPreferences().getChoice(Preferences.ROCKET_INFO_FONT_SIZE, 2, 0));
}
/**
* Enable/Disable the auto-opening of the last edited design file on startup.
*/
@ -820,25 +817,6 @@ public abstract class Preferences implements ChangeSource {
}
}
public Color getDefaultColor(Class<? extends RocketComponent> c) {
String color = get("componentColors", c, StaticFieldHolder.DEFAULT_COLORS);
if (color == null)
return Color.BLACK;
Color clr = parseColor(color);
if (clr != null) {
return clr;
} else {
return Color.BLACK;
}
}
public final void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
if (color == null)
return;
putString("componentColors", c.getSimpleName(), stringifyColor(color));
}
/**
* Retrieve a Line style for the given component.
@ -1014,6 +992,29 @@ public abstract class Preferences implements ChangeSource {
public abstract void setComponentFavorite(ComponentPreset preset, ComponentPreset.Type type, boolean favorite);
public abstract Set<String> getComponentFavorites(ComponentPreset.Type type);
/*
NOTE: It is unusual for the UI Theme to be stored in the preferences instead of SwingPreferences. In fact, this code
is not pretty. Sometimes I just really hate Java and circular dependencies...
But the reason why this is implemented is because it would otherwise be an even bigger nightmare to fix unit tests
that use their own preferences... Also wasn't a fan of always casting the preferences to SwingPreferences.
*/
/**
* Get the current theme used for the UI.
* @return the current theme
*/
public Object getUITheme() {
return null;
}
/**
* Set the theme used for the UI.
* @param theme the theme to set
*/
public void setUITheme(Object theme) {}
/*
* Within a holder class so they will load only when needed.
@ -1032,19 +1033,6 @@ public abstract class Preferences implements ChangeSource {
DEFAULT_LINE_STYLES.put(RocketComponent.class, LineStyle.SOLID.name());
DEFAULT_LINE_STYLES.put(MassObject.class, LineStyle.DASHED.name());
}
private static final HashMap<Class<?>, String> DEFAULT_COLORS = new HashMap<Class<?>, String>();
static {
DEFAULT_COLORS.put(BodyComponent.class, "0,0,240");
DEFAULT_COLORS.put(TubeFinSet.class, "0,0,200");
DEFAULT_COLORS.put(FinSet.class, "0,0,200");
DEFAULT_COLORS.put(LaunchLug.class, "0,0,180");
DEFAULT_COLORS.put(RailButton.class, "0,0,180");
DEFAULT_COLORS.put(InternalComponent.class, "170,0,100");
DEFAULT_COLORS.put(MassObject.class, "0,0,0");
DEFAULT_COLORS.put(RecoveryDevice.class, "255,0,0");
}
}
private final List<EventListener> listeners = new ArrayList<EventListener>();

View File

@ -66,6 +66,10 @@ public class Color {
return new java.awt.Color(red, green, blue, alpha);
}
public static Color fromAWTColor(java.awt.Color AWTColor) {
return new Color(AWTColor.getRed(), AWTColor.getGreen(), AWTColor.getBlue(), AWTColor.getAlpha());
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {

View File

@ -1049,7 +1049,7 @@ public class TestRockets {
boosterCone.setThickness(0.002);
//payloadFairingNoseCone.setLength(0.118);
//payloadFairingNoseCone.setAftRadius(0.052);
boosterCone.setAftShoulderRadius( 0.051 );
boosterCone.setAftShoulderRadius( 0.0375 );
boosterCone.setAftShoulderLength( 0.02 );
boosterCone.setAftShoulderThickness( 0.001 );
boosterCone.setAftShoulderCapped( false );

View File

@ -498,7 +498,7 @@ public class MassCalculatorTest extends BaseTestCase {
// ====== ====== ======
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
expMass = 0.0222459863653;
expMass = 0.0210923935430;
// think of the casts as an assert that ( child instanceof NoseCone) == true
NoseCone nose = (NoseCone) boosters.getChild(0);
compMass = nose.getComponentMass();
@ -582,7 +582,7 @@ public class MassCalculatorTest extends BaseTestCase {
// ====== ====== ======
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
expCMx = 0.055710581052;
expCMx = 0.053835211739;
// think of the casts as an assert that ( child instanceof NoseCone) == true
NoseCone nose = (NoseCone) boosters.getChild(0);
actCMx = nose.getComponentCG().x;
@ -692,10 +692,10 @@ public class MassCalculatorTest extends BaseTestCase {
ParallelStage boosters = (ParallelStage) coreStage.getChild(0).getChild(0);
{
final NoseCone boosterNose = (NoseCone) boosters.getChild(0);
expInertia = 1.82665797857e-5;
expInertia = 1.73189409900e-5;
compInertia = boosterNose.getRotationalInertia();
assertEquals(boosterNose.getName() + " Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
expInertia = 1.96501191666e-7;
expInertia = 4.51796586171e-6;
compInertia = boosterNose.getLongitudinalInertia();
assertEquals(boosterNose.getName() + " Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
@ -832,8 +832,8 @@ public class MassCalculatorTest extends BaseTestCase {
final RigidBody actualData = MassCalculator.calculateStructure(config);
final Coordinate actualCM = actualData.getCM();
double expMass = 0.608663395;
double expCMx = 1.073157592;
double expMass = 0.6063562096;
double expCMx = 1.075056887;
assertEquals("Heavy Booster Mass is incorrect: ", expMass, actualCM.weight, EPSILON);
assertEquals("Heavy Booster CM.x is incorrect: ", expCMx, actualCM.x, EPSILON);
@ -852,11 +852,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody actualBoosterLaunchData = MassCalculator.calculateLaunch(config);
double actualMass = actualBoosterLaunchData.getMass();
double expectedMass = 1.592663395;
double expectedMass = 1.5903562096;
assertEquals(" Booster Launch Mass is incorrect: ", expectedMass, actualMass, EPSILON);
final Coordinate actualCM = actualBoosterLaunchData.getCM();
double expectedCMx = 1.22216804;
double expectedCMx = 1.22310836;
Coordinate expCM = new Coordinate(expectedCMx, 0, 0, expectedMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, actualCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, actualCM.y, EPSILON);
@ -876,8 +876,8 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody spentData = MassCalculator.calculateBurnout(config);
Coordinate spentCM = spentData.getCM();
double expSpentMass = 1.12066339;
double expSpentCMx = 1.18334714;
double expSpentMass = 1.11835621;
double expSpentCMx = 1.18460423;
Coordinate expLaunchCM = new Coordinate(expSpentCMx, 0, 0, expSpentMass);
assertEquals(" Booster Launch Mass is incorrect: ", expLaunchCM.weight, spentCM.weight, EPSILON);
assertEquals(" Booster Launch CM.x is incorrect: ", expLaunchCM.x, spentCM.x, EPSILON);
@ -942,11 +942,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody spent = MassCalculator.calculateBurnout(config);
double expMOIRotational = 0.009205665421431532;
double expMOIRotational = 0.00919009169;
double boosterMOIRotational = spent.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOIRotational, boosterMOIRotational, EPSILON);
double expMOI_tr = 0.0582250994240395;
double expMOI_tr = 0.0573781722;
double boosterMOI_tr = spent.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -962,9 +962,9 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody launchData = MassCalculator.calculateLaunch(config);
final double expIxx = 0.01226617242143153;
final double expIxx = 0.0122505987;
final double actIxx = launchData.getRotationalInertia();
final double expIyy = 0.06455356411879717;
final double expIyy = 0.0635943662;
final double actIyy = launchData.getLongitudinalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expIxx, actIxx, EPSILON);
@ -1006,11 +1006,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterSetCM);
// Validate MOI
double expMOI_axial = 0.005885793421431532;
double expMOI_axial = 0.00587021969016;
double boosterMOI_xx = burnout.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 17.86133586701;
double expMOI_tr = 17.78076176335;
double boosterMOI_tr = burnout.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -1052,7 +1052,7 @@ public class MassCalculatorTest extends BaseTestCase {
double expTotalMass = 3.3565872;
assertEquals(" Booster Launch Mass is incorrect: ", expTotalMass, boosterData.getMass(), EPSILON);
double expCMx = 0.2835089882645608;
double expCMx = 0.2827156156318;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expTotalMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, boosterCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, boosterCM.y, EPSILON);
@ -1064,7 +1064,7 @@ public class MassCalculatorTest extends BaseTestCase {
double boosterMOI_xx = boosterData.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 0.34567788938578525;
double expMOI_tr = 0.347611843243;
double boosterMOI_tr = boosterData.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -1095,11 +1095,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody structure = MassCalculator.calculateStructure(config);
final double expMass = 0.6086633952494;
final double expMass = 0.6063562096046;
double calcTotalMass = structure.getMass();
assertEquals(" Booster Launch Mass is incorrect: ", expMass, calcTotalMass, EPSILON);
final double expCMx = 0.5551303646438673;
final double expCMx = 0.55670993586431;
Coordinate expCM = new Coordinate(expCMx, 0, 0, expMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, structure.getCM().x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, structure.getCM().y, EPSILON);
@ -1107,11 +1107,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, structure.getCM());
// Validate MOI
final double expMOI_axial = 0.005885793421;
final double expMOI_axial = 0.005870219690;
double boosterMOI_xx = structure.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
final double expMOI_tr = 0.040989095911;
final double expMOI_tr = 0.040598624476;
double boosterMOI_tr = structure.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}

View File

@ -117,7 +117,7 @@ public class FlightEventsTest extends BaseTestCase {
new FlightEvent(FlightEvent.Type.IGNITION, 0.0, coreBody),
new FlightEvent(FlightEvent.Type.LIFTOFF, 0.1225, null),
new FlightEvent(FlightEvent.Type.LAUNCHROD, 0.125, null),
new FlightEvent(FlightEvent.Type.APOGEE, 1.86, rocket),
new FlightEvent(FlightEvent.Type.APOGEE, 1.867, rocket),
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, boosterMotorTubes),
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
@ -147,7 +147,7 @@ public class FlightEventsTest extends BaseTestCase {
new FlightEvent(FlightEvent.Type.BURNOUT, 2.0, boosterMotorTubes),
new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.STAGE_SEPARATION, 2.0, boosterStage),
new FlightEvent(FlightEvent.Type.TUMBLE, 3.551, null),
new FlightEvent(FlightEvent.Type.TUMBLE, 3.428, null),
new FlightEvent(FlightEvent.Type.GROUND_HIT, 1200, null),
new FlightEvent(FlightEvent.Type.SIMULATION_END, 1200, null)
};

View File

@ -48,6 +48,7 @@
</launcher>
</launchers>
<installerGui>
<laf type="native" />
<applications>
<application id="installer" beanClass="com.install4j.runtime.beans.applications.InstallerApplication" customIcnsFile="../../core/resources/pix/icon/icon-macos.icns" customIcoFile="../../core/resources/pix/icon/icon-windows.ico">
<serializedBean>

View File

@ -11,6 +11,7 @@
<classpathentry kind="lib" path="lib/iText-5.0.2.jar"/>
<classpathentry kind="lib" path="lib/jcommon-1.0.18.jar"/>
<classpathentry kind="lib" path="lib/jfreechart-1.0.15.jar"/>
<classpathentry kind="lib" path="lib/darklaf/*.jar"/>
<classpathentry kind="lib" path="lib/jogl/gluegen-rt.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/OpenRocket Core"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/slf4j-api-1.7.30.jar"/>

View File

@ -5,6 +5,7 @@
<libelement value="jar://$MODULE_DIR$/lib/iText-5.0.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jcommon-1.0.18.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jfreechart-1.0.15.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/darklaf/*.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/OrangeExtensions-1.2.jar!/" />
<libelement value="jar://$MODULE_DIR$/lib/jogl/gluegen-rt.jar!/" />
<libelement value="jar://$MODULE_DIR$/../core/lib/slf4j-api-1.7.5.jar!/" />
@ -107,6 +108,39 @@
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="flatlaf-3.1.1.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/flatlaf-3.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="darklaf-3.0.2.jar">
<CLASSES>""
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-core-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-theme-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-theme-spec-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-utils-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-property-loader-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-base-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-decorations-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-platform-preferences-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-iconset-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-compatibility-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-macos-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-native-utils-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/darklaf-windows-3.0.3-SNAPSHOT.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/jsvg-0.0.9.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/swing-extensions-laf-support-0.1.3.jar!/" />
<root url="jar://$MODULE_DIR$/lib/darklaf/swing-extensions-visual-padding-0.1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="aopalliance.jar">
<CLASSES>

View File

@ -74,7 +74,7 @@
<echo level="info">Java/JVM detail version: ${java.version}</echo>
<mkdir dir="${classes.dir}"/>
<echo level="info">Compiling main classes</echo>
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false" source="1.8" target="1.8"/>
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false" source="17" target="17"/>
</target>
<!-- Executible Eclipse-Jar-In-Jar style JAR -->
@ -116,6 +116,22 @@
<zipfileset src="${core.dir}/lib/jaxb-runtime.2.3.1.jar"/>
<zipfileset src="${lib.dir}/jcommon-1.0.18.jar"/>
<zipfileset src="${lib.dir}/jfreechart-1.0.15.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-compatibility-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-core-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-iconset-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-macos-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-native-utils-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-base-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-decorations-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-platform-preferences-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-property-loader-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-theme-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-theme-spec-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-utils-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/darklaf-windows-3.0.3-SNAPSHOT.jar"/>
<zipfileset src="${lib.dir}/darklaf/jsvg-0.0.9.jar"/>
<zipfileset src="${lib.dir}/darklaf/swing-extensions-laf-support-0.1.3.jar"/>
<zipfileset src="${lib.dir}/darklaf/swing-extensions-visual-padding-0.1.3.jar"/>
<zipfileset src="${core.dir}/lib/opencsv-5.7.1.jar"/>
<zipfileset src="${core.dir}/lib/annotation-detector-3.0.5.jar"/>
<zipfileset src="${core.dir}/lib/slf4j-api-1.7.30.jar"/>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,12 +2,10 @@ package net.sf.openrocket.communication;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BuildProperties;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* This class handles assets extracted from a GitHub release page.

View File

@ -3,9 +3,7 @@ package net.sf.openrocket.database;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Collection;
import java.util.List;
import net.sf.openrocket.file.iterator.DirectoryIterator;
import net.sf.openrocket.file.iterator.FileIterator;
@ -14,7 +12,6 @@ import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.xml.OpenRocketComponentLoader;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Pair;
import org.slf4j.Logger;

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.gui.components;
import net.sf.openrocket.gui.util.GUIUtil;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
@ -14,7 +16,6 @@ import javax.swing.tree.TreePath;
@SuppressWarnings("serial")
public class BasicTree extends JTree {
public BasicTree() {
super();
setDefaultOptions();
@ -36,7 +37,7 @@ public class BasicTree extends JTree {
plainUI.setLeftChildIndent(15);
this.setBackground(Color.WHITE);
this.setBackground(GUIUtil.getUITheme().getBackgroundColor());
this.setShowsRootHandles(false);
}

View File

@ -1,9 +1,9 @@
package net.sf.openrocket.gui.components;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.URLUtil;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
@ -31,6 +31,8 @@ import javax.swing.SwingUtilities;
public class DescriptionArea extends JScrollPane {
private final JEditorPane editorPane;
private final float size;
/**
@ -86,15 +88,14 @@ public class DescriptionArea extends JScrollPane {
public DescriptionArea(String text, int rows, float size, boolean opaque) {
super(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
this.size = size;
editorPane = new JEditorPane("text/html", "");
Font font = editorPane.getFont();
editorPane.setFont(font.deriveFont(font.getSize2D() + size));
editorPane.setEditable(false);
editorPane.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
URI uri = null;
URI uri;
try {
uri = e.getURL().toURI();
}
@ -125,8 +126,8 @@ public class DescriptionArea extends JScrollPane {
// create temporary file and copy resource to it
File of = null;
BufferedOutputStream os = null;
File of;
BufferedOutputStream os;
try {
of = File.createTempFile(prefix, suffix);
os = new BufferedOutputStream(new FileOutputStream(of));
@ -163,11 +164,11 @@ public class DescriptionArea extends JScrollPane {
}
// Calculate correct height
editorPane.setText("abc");
this.setText("abc");
Dimension oneline = editorPane.getPreferredSize();
editorPane.setText("abc<br>def");
this.setText("abc<br>def");
Dimension twolines = editorPane.getPreferredSize();
editorPane.setText("");
this.setText("");
int lineheight = twolines.height - oneline.height;
int extraheight = oneline.height - lineheight;
@ -175,13 +176,20 @@ public class DescriptionArea extends JScrollPane {
Dimension dim = editorPane.getPreferredSize();
dim.height = lineheight * rows + extraheight + 2;
this.setPreferredSize(dim);
editorPane.setBorder(GUIUtil.getUITheme().getBorder());
this.setViewportView(editorPane);
this.setText(text);
}
public void setText(String txt) {
editorPane.setText(txt);
// Set the font size (we can't simply set the font to change the font size, because we're using text/html)
Font defaultFont = editorPane.getFont();
String fontName = defaultFont.getFontName();
float fontSize = defaultFont.getSize2D() + size;
editorPane.setText("<html><body style='font-family:" + fontName + ";font-size:" + fontSize + "pt;'>" + txt + "</body></html>");
editorPane.revalidate();
SwingUtilities.invokeLater(new Runnable() {

View File

@ -1,23 +1,18 @@
package net.sf.openrocket.gui.components;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.URLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.util.BugException;
/**
* A label of a URL that is clickable. Clicking the URL will launch the URL in
* the default browser if the Desktop class is supported.
@ -26,7 +21,7 @@ import net.sf.openrocket.util.BugException;
*/
public class URLLabel extends SelectableLabel {
private static final Logger log = LoggerFactory.getLogger(URLLabel.class);
/**
* Create a label showing the url it will direct to.
*
@ -53,7 +48,7 @@ public class URLLabel extends SelectableLabel {
Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
this.setFont(this.getFont().deriveFont(map));
this.setForeground(Color.BLUE);
this.setForeground(GUIUtil.getUITheme().getURLColor());
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

View File

@ -22,7 +22,7 @@ public class Tester {
BasicApplication baseApp = new BasicApplication();
baseApp.initializeApplication();
GUIUtil.setBestLAF();
GUIUtil.applyLAF();
SwingUtilities.invokeAndWait(new Runnable() {
@Override

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.gui.configdialog;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
@ -170,6 +169,7 @@ public class AppearancePanel extends JPanel {
Color awtColor = ColorConversion.toAwtColor(c);
colorChooser.setColor(awtColor);
colorChooser.updateUI(); // Needed for darklaf color chooser to update
// Bind a change of color selection to a change in the components color
ColorSelectionModel model = colorChooser.getSelectionModel();
@ -183,7 +183,8 @@ public class AppearancePanel extends JPanel {
JDialog d = JColorChooser.createDialog(AppearancePanel.this,
trans.get("RocketCompCfg.lbl.Choosecolor"), true,
colorChooser, new ActionListener() {
colorChooser,
new ActionListener() {
@Override
public void actionPerformed(ActionEvent okEvent) {
changeComponentColor(colorChooser.getColor());
@ -262,8 +263,7 @@ public class AppearancePanel extends JPanel {
net.sf.openrocket.util.Color figureColor = c.getColor();
if (figureColor == null) {
figureColor = Application.getPreferences().getDefaultColor(
c.getClass());
figureColor = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
}
final JButton figureColorButton = new SelectColorButton(
new ColorIcon(figureColor));
@ -278,8 +278,7 @@ public class AppearancePanel extends JPanel {
public void stateChanged(EventObject e) {
net.sf.openrocket.util.Color col = c.getColor();
if (col == null) {
col = Application.getPreferences().getDefaultColor(
c.getClass());
col = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
}
figureColorButton.setIcon(new ColorIcon(col));
}

View File

@ -9,6 +9,8 @@ import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
@ -17,12 +19,14 @@ import java.util.EventObject;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
@ -36,6 +40,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.DescriptionArea;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.widgets.SelectColorButton;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material;
@ -46,6 +51,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -55,6 +61,9 @@ import net.sf.openrocket.util.StateChangeListener;
public class InnerTubeConfig extends RocketComponentConfig {
private static final long serialVersionUID = 7900041420864324470L;
private static final Translator trans = Application.getTranslator();
private static final Preferences prefs = Application.getPreferences();
private static final String PREF_SEPARATION_RELATIVE = "InnerTubeSeparationRelative";
public InnerTubeConfig(OpenRocketDocument d, RocketComponent c, JDialog parent) {
@ -279,29 +288,88 @@ public class InnerTubeConfig extends RocketComponentConfig {
//// The separation of the tubes, 1.0 = touching each other
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(l);
DoubleModel dm = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
JSpinner spin = new JSpinner(dm.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
//// The separation of the tubes, 1.0 = touching each other
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(spin, "growx");
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
//// Models
final boolean useRelativeSeparation = prefs.getBoolean(PREF_SEPARATION_RELATIVE, true);
final DoubleModel clusterScaleModelRel = new DoubleModel(component, "ClusterScale", 1, UnitGroup.UNITS_NONE, 0);
final DoubleModel clusterScaleModelAbs = new DoubleModel(component, "ClusterScaleAbsolute", 1, UnitGroup.UNITS_LENGTH);
final DoubleModel clusterScaleModel = useRelativeSeparation ? clusterScaleModelRel : clusterScaleModelAbs;
BasicSlider bs = new BasicSlider(dm.getSliderModel(0, 1, 4));
//// The separation of the tubes, 1.0 = touching each other
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.TubeSep"));
subPanel.add(bs, "skip,w 100lp, wrap");
final String clusterScaleTtipRel = trans.get("InnerTubeCfg.lbl.ttip.TubeSep");
final String clusterScaleTtipAbs = trans.get("InnerTubeCfg.lbl.ttip.TubeSepAbs");
final String clusterScaleTtip = useRelativeSeparation ? clusterScaleTtipRel : clusterScaleTtipAbs;
JSpinner clusterScaleSpin = new JSpinner(clusterScaleModel.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleSpin.setToolTipText(clusterScaleTtip);
subPanel.add(clusterScaleSpin, "growx");
order.add(((SpinnerEditor) clusterScaleSpin.getEditor()).getTextField());
UnitSelector clusterScaleUnit = new UnitSelector(clusterScaleModel);
subPanel.add(clusterScaleUnit, "growx");
BasicSlider clusterScaleBs = new BasicSlider(clusterScaleModel.getSliderModel(0, 1, 4));
subPanel.add(clusterScaleBs, "w 100lp, wrap");
// Relative/absolute separation
JRadioButton rbRel = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Relative"));
JRadioButton rbAbs = new JRadioButton(trans.get("InnerTubeCfg.radioBut.Absolute"));
rbRel.setToolTipText(trans.get("InnerTubeCfg.radioBut.Relative.ttip"));
rbAbs.setToolTipText(trans.get("InnerTubeCfg.radioBut.Absolute.ttip"));
ButtonGroup bg = new ButtonGroup();
bg.add(rbRel);
bg.add(rbAbs);
subPanel.add(rbRel, "skip, spanx, split 2");
subPanel.add(rbAbs, "wrap");
rbRel.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED)
return;
clusterScaleSpin.setModel(clusterScaleModelRel.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleUnit.setModel(clusterScaleModelRel);
clusterScaleBs.setModel(clusterScaleModelRel.getSliderModel(0, 1, 4));
clusterScaleSpin.setToolTipText(clusterScaleTtipRel);
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
}
});
rbAbs.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.DESELECTED)
return;
DoubleModel radiusModelMin = new DoubleModel(component, "OuterRadius", -2, UnitGroup.UNITS_LENGTH);
DoubleModel radiusModelMax = new DoubleModel(component, "OuterRadius", 6, UnitGroup.UNITS_LENGTH);
clusterScaleSpin.setModel(clusterScaleModelAbs.getSpinnerModel());
clusterScaleSpin.setEditor(new SpinnerEditor(clusterScaleSpin));
clusterScaleUnit.setModel(clusterScaleModelAbs);
clusterScaleBs.setModel(clusterScaleModelAbs.getSliderModel(radiusModelMin, radiusModelMax));
clusterScaleSpin.setToolTipText(clusterScaleTtipAbs);
prefs.putBoolean(PREF_SEPARATION_RELATIVE, false);
}
});
// Select the button by default
if (prefs.getBoolean(PREF_SEPARATION_RELATIVE, true)) {
rbRel.setSelected(true);
} else {
rbAbs.setSelected(true);
}
// Rotation:
l = new JLabel(trans.get("InnerTubeCfg.lbl.Rotation"));
//// Rotation angle of the cluster configuration
l.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
subPanel.add(l);
dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
DoubleModel dm = new DoubleModel(component, "ClusterRotation", 1, UnitGroup.UNITS_ANGLE,
-Math.PI, Math.PI);
spin = new JSpinner(dm.getSpinnerModel());
JSpinner spin = new JSpinner(dm.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
//// Rotation angle of the cluster configuration
spin.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
@ -309,7 +377,7 @@ public class InnerTubeConfig extends RocketComponentConfig {
order.add(((SpinnerEditor) spin.getEditor()).getTextField());
subPanel.add(new UnitSelector(dm), "growx");
bs = new BasicSlider(dm.getSliderModel());
BasicSlider bs = new BasicSlider(dm.getSliderModel());
//// Rotation angle of the cluster configuration
bs.setToolTipText(trans.get("InnerTubeCfg.lbl.ttip.Rotation"));
subPanel.add(bs, "w 100lp, wrap para");
@ -398,10 +466,17 @@ class ClusterSelectionPanel extends JPanel {
private static final int BUTTON_SIZE = 50;
private static final int MOTOR_DIAMETER = 10;
private static final Color SELECTED_COLOR = Color.RED;
private static final Color UNSELECTED_COLOR = Color.WHITE;
private static final Color MOTOR_FILL_COLOR = Color.GREEN;
private static final Color MOTOR_BORDER_COLOR = Color.BLACK;
private static final Color SELECTED_COLOR;
private static final Color UNSELECTED_COLOR;
private static final Color MOTOR_FILL_COLOR;
private static final Color MOTOR_BORDER_COLOR;
static {
SELECTED_COLOR = Color.RED;
UNSELECTED_COLOR = GUIUtil.getUITheme().getBackgroundColor();
MOTOR_FILL_COLOR = Color.GREEN;
MOTOR_BORDER_COLOR = Color.BLACK;
}
public ClusterSelectionPanel(Clusterable component) {
super(new MigLayout("gap 0 0",
@ -438,6 +513,7 @@ class ClusterSelectionPanel extends JPanel {
setMaximumSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
// setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
setToolTipText(config.getXMLName());
component.addChangeListener(this);
addMouseListener(this);
}

View File

@ -506,7 +506,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelMassOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.MassOverriddenBy"), component.getMassOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelMassOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelMassOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelMassOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.MassOverriddenBy.ttip"), component.getMassOverriddenBy().getName()));
checkboxes.add(labelMassOverriddenBy, "gapleft 25lp, wrap");
@ -569,7 +569,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelCGOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.CGOverriddenBy"), component.getCGOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelCGOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelCGOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelCGOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.CGOverriddenBy.ttip"), component.getCGOverriddenBy().getName()));
checkboxes.add(labelCGOverriddenBy, "gapleft 25lp, wrap");
@ -663,7 +663,7 @@ public class RocketComponentConfig extends JPanel {
StyledLabel labelCDOverriddenBy = new StyledLabel(
String.format(trans.get("RocketCompCfg.lbl.CDOverriddenBy"), component.getCDOverriddenBy().getName()),
0, StyledLabel.Style.BOLD);
labelCDOverriddenBy.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
labelCDOverriddenBy.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
labelCDOverriddenBy.setToolTipText(
String.format(trans.get("RocketCompCfg.lbl.CDOverriddenBy"), component.getCDOverriddenBy().getName()));
checkboxes.add(labelCDOverriddenBy, "gapleft 25lp, wrap");
@ -719,6 +719,7 @@ public class RocketComponentConfig extends JPanel {
commentTextArea.setLineWrap(true);
commentTextArea.setWrapStyleWord(true);
commentTextArea.setEditable(true);
commentTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(commentTextArea);
commentTextArea.addFocusListener(textFieldListener);
commentTextArea.addKeyListener(new TextComponentSelectionKeyListener(commentTextArea));

View File

@ -27,7 +27,7 @@ import net.sf.openrocket.startup.Application;
public class RocketConfig extends RocketComponentConfig {
private static final Translator trans = Application.getTranslator();
private TextFieldListener textFieldListener;
private JTextArea designerTextArea;
@ -55,6 +55,7 @@ public class RocketConfig extends RocketComponentConfig {
designerTextArea.setLineWrap(true);
designerTextArea.setWrapStyleWord(true);
designerTextArea.setEditable(true);
designerTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(designerTextArea);
designerTextArea.addFocusListener(textFieldListener);
this.add(new JScrollPane(designerTextArea), "wmin 400lp, height 60lp:60lp:, grow 30, wrap para");
@ -69,6 +70,7 @@ public class RocketConfig extends RocketComponentConfig {
revisionTextArea.setLineWrap(true);
revisionTextArea.setWrapStyleWord(true);
revisionTextArea.setEditable(true);
revisionTextArea.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.setTabToFocusing(revisionTextArea);
revisionTextArea.addFocusListener(textFieldListener);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.customexpression;
import java.awt.Color;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -18,6 +17,7 @@ import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -39,7 +39,7 @@ public class CustomExpressionPanel extends JPanel {
private static final Logger log = LoggerFactory.getLogger(CustomExpressionPanel.class);
private static final Translator trans = Application.getTranslator();
private JPanel expressionSelectorPanel;
private OpenRocketDocument doc;
@ -51,6 +51,7 @@ public class CustomExpressionPanel extends JPanel {
expressionSelectorPanel.setToolTipText(trans.get("customExpressionPanel.lbl.CalcNote"));
JScrollPane scroll = new JScrollPane(expressionSelectorPanel);
expressionSelectorPanel.setBorder(GUIUtil.getUITheme().getBorder());
//Border bdr = BorderFactory.createTitledBorder(trans.get("customExpressionPanel.lbl.CustomExpressions"));
//scroll.setBorder(bdr);
@ -170,10 +171,10 @@ public class CustomExpressionPanel extends JPanel {
* A JPanel which configures a single expression
*/
private class SingleExpression extends JPanel {
// Convenience method to make the labels consistent
private JLabel setLabelStyle(JLabel l) {
l.setBackground(Color.WHITE);
l.setBackground(GUIUtil.getUITheme().getBackgroundColor());
l.setOpaque(true);
l.setBorder(BorderFactory.createRaisedBevelBorder());
l.setText(" " + l.getText() + " ");
@ -191,13 +192,13 @@ public class CustomExpressionPanel extends JPanel {
JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol") + " :");
JLabel symbol = new JLabel(expression.getSymbol());
symbol = setLabelStyle(symbol);
symbol.setBackground(Color.WHITE);
symbol.setBackground(GUIUtil.getUITheme().getBackgroundColor());
JLabel unitLabel = new JLabel(trans.get("customExpression.Units") + " :");
UnitSelector unitSelector = new UnitSelector(expression.getType().getUnitGroup());
//JLabel unitSelector = new JLabel ( expression.getUnit() );
//unitSelector = setLabelStyle(unitSelector);
//unitSelector.setBackground(Color.WHITE);
//unitSelector.setBackground(GUIUtil.getUITheme().getBackgroundColor());
JButton editButton = new SelectColorButton(Icons.EDIT_EDIT);
editButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Edit"));

View File

@ -43,7 +43,7 @@ public class AboutDialog extends JDialog {
"Daniel Williams (pod support, maintainer)<br>" +
"Joe Pfeiffer (maintainer)<br>" +
"Billy Olsen (maintainer)<br>" +
"Sibo Van Gool (RASAero file format, 3D OBJ export, maintainer)<br>" +
"Sibo Van Gool (RASAero file format, 3D OBJ export, dark theme, maintainer)<br>" +
"Justin Hanney (maintainer)<br>" +
"Neil Weinstock (tester, icons, forum support)<br>" +
"H. Craig Miller (tester)<br><br>" +
@ -60,6 +60,9 @@ public class AboutDialog extends JDialog {
"<br>" +
"See all contributors at <br>" + href("https://github.com/openrocket/openrocket/graphs/contributors", false, false) + "<br>" +
"<br>" +
"<b>Thank you to our financial contributors who have provided us with the necessary resources to continue this project:</b><br>" +
href("https://opencollective.com/openrocket", true, true) + "<br>" +
"<br>" +
"<b>OpenRocket utilizes the following libraries:</b><br>" +
"<br>" +
"MiG Layout" + href("http://www.miglayout.com", true, true) + "<br>" +
@ -72,7 +75,8 @@ public class AboutDialog extends JDialog {
"Simple Logging Facade for Java" + href("http://www.slf4j.org", true, true) + "<br>" +
"Java library for parsing and rendering CommonMark" + href("https://github.com/commonmark/commonmark-java", true, true) + "<br>" +
"RSyntaxTextArea" + href("http://bobbylight.github.io/RSyntaxTextArea", true, true) + "<br>" +
"Obj" + href("https://github.com/javagl/Obj", true, true) + "<br>" +
"Darklaf (dark theme)" + href("https://github.com/weisJ/darklaf", true, true) + "<br>" +
"Obj" + href("https://github.com/javagl/Obj", true, true) + "<br>" +
"<br>" +
"<b>OpenRocket gratefully acknowledges our use of the following databases:</b><br>" +
"<br>" +

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.dialogs;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Window;
@ -177,8 +178,9 @@ public class BugReportDialog extends JDialog {
private static void addBugReportInformation(StringBuilder sb) {
sb.append("<html>---------- Bug report ----------\n");
sb.append('\n');
sb.append("<b style='color:rgb(210, 20, 5)'>Please include a description about what actions you were " +
"performing when the exception occurred:</b>\n");
Color color = GUIUtil.getUITheme().getDarkWarningColor();
sb.append(String.format("<b style='color:rgb(%d, %d, %d)'>Please include a description about what actions you were " +
"performing when the exception occurred:</b>\n", color.getRed(), color.getGreen(), color.getBlue()));
sb.append("<i>(You can edit text directly in this window)</i>\n");
sb.append('\n');
sb.append("1. \n");
@ -204,6 +206,7 @@ public class BugReportDialog extends JDialog {
sbTemp.append("OpenRocket source: " + BuildProperties.getBuildSource() + "\n");
sbTemp.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
sbTemp.append("User-defined thrust curves location: " + preferences.getUserThrustCurveFilesAsString() + "\n");
sbTemp.append("LAF: " + UIManager.getLookAndFeel().getClass().getName() + "\n");
sbTemp.append("JOGL version: " + JoglVersion.getInstance().getImplementationVersion() + "\n");
sbTemp.append("Current default locale: " + Locale.getDefault() + "\n");
sbTemp.append("System properties:\n");

View File

@ -150,6 +150,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
warningList = new JList<>();
JScrollPane scrollPane = new JScrollPane(warningList);
warningList.setBorder(GUIUtil.getUITheme().getBorder());
////Warnings:
scrollPane.setBorder(BorderFactory.createTitledBorder(trans.get("componentanalysisdlg.TitledBorder.warnings")));
panel.add(scrollPane, "gap paragraph, spany 4, w 300lp, grow, height :100lp:, wrap");
@ -646,7 +647,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
}
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBackground(GUIUtil.getUITheme().getBackgroundColor());
label.setHorizontalAlignment(SwingConstants.LEFT);
if ((row < 0) || (row >= data.size()))
@ -693,7 +694,6 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
private class DragCellRenderer extends CustomCellRenderer {
private static final long serialVersionUID = 1L;
public DragCellRenderer() {
super(dragData, 3);
}
@ -712,6 +712,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
float val = 1.0f;
label.setBackground(Color.getHSBColor(hue, sat, val));
label.setForeground(Color.BLACK);
}
if ((row < 0) || (row >= dragData.size()))

View File

@ -67,7 +67,7 @@ public class DebugLogDialog extends JDialog {
private static final int POLL_TIME = 250;
private static final String STACK_TRACE_MARK = "\uFF01";
private static final Translator trans = Application.getTranslator();
private static final EnumMap<LogLevel, Color> backgroundColors = new EnumMap<LogLevel, Color>(LogLevel.class);
static {
for (LogLevel l : LogLevel.values()) {
@ -343,6 +343,7 @@ public class DebugLogDialog extends JDialog {
bottomPanel.add(new JLabel(trans.get("debuglogdlg.lbl.Stacktrace")), "wrap rel");
stackTraceLabel = new JTextArea(8, 80);
stackTraceLabel.setEditable(false);
stackTraceLabel.setBorder(GUIUtil.getUITheme().getBorder());
GUIUtil.changeFontSize(stackTraceLabel, -2);
bottomPanel.add(new JScrollPane(stackTraceLabel), "grow, pushy 200, growprioy 200");
@ -503,7 +504,7 @@ public class DebugLogDialog extends JDialog {
if (STACK_TRACE_MARK.equals(value)) {
fg = Color.RED;
} else {
fg = table1.getForeground();
fg = Color.BLACK;
}
bg = backgroundColors.get(buffer.get(row).getLevel());

View File

@ -3,6 +3,7 @@ package net.sf.openrocket.gui.dialogs;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.util.BetterListCellRenderer;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.logging.Error;
import net.sf.openrocket.logging.ErrorSet;
import net.sf.openrocket.logging.Warning;
@ -15,7 +16,6 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.ListSelectionModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@ -25,11 +25,12 @@ import java.awt.event.MouseEvent;
*/
@SuppressWarnings("serial")
public abstract class ErrorWarningDialog {
public static void showErrorsAndWarnings(Component parent, Object message, String title, ErrorSet errors, WarningSet warnings) {
JPanel content = new JPanel(new MigLayout("ins 0, fillx"));
StyledLabel label = new StyledLabel("Errors");
label.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
label.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
content.add(label, "wrap, gaptop 15lp");
Error[] e = errors.toArray(new Error[0]);
@ -37,6 +38,7 @@ public abstract class ErrorWarningDialog {
errorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
errorList.setCellRenderer(new ErrorListCellRenderer());
JScrollPane errorPane = new JScrollPane(errorList);
errorList.setBorder(GUIUtil.getUITheme().getBorder());
content.add(errorPane, "wrap, growx");
// Deselect items if clicked on blank region
@ -58,6 +60,7 @@ public abstract class ErrorWarningDialog {
final JList<Warning> warningList = new JList<>(w);
warningList.setCellRenderer(new BetterListCellRenderer());
JScrollPane warningPane = new JScrollPane(warningList);
warningList.setBorder(GUIUtil.getUITheme().getBorder());
content.add(warningPane, "wrap, growx");
// Deselect items if clicked on blank region
@ -84,9 +87,9 @@ public abstract class ErrorWarningDialog {
// Text color
if (isSelected) {
label.setForeground(Color.WHITE);
label.setForeground(GUIUtil.getUITheme().getTextSelectionForegroundColor());
} else {
label.setForeground(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
label.setForeground(GUIUtil.getUITheme().getDarkWarningColor());
}
return label;

View File

@ -1,16 +1,15 @@
package net.sf.openrocket.gui.dialogs;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
@ -75,6 +74,7 @@ public class UpdateInfoDialog extends JDialog {
// Release information box
final JTextPane textPane = new JTextPane();
textPane.setBorder(BorderFactory.createLineBorder(GUIUtil.getUITheme().getTextColor()));
textPane.setEditable(false);
textPane.setContentType("text/html");
textPane.setMargin(new Insets(10, 10, 40, 10));

View File

@ -2,23 +2,25 @@ package net.sf.openrocket.gui.dialogs;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import net.sf.openrocket.gui.util.BetterListCellRenderer;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.logging.Warning;
import net.sf.openrocket.logging.WarningSet;
@SuppressWarnings("serial")
public abstract class WarningDialog {
public static void showWarnings(Component parent, Object message, String title, WarningSet warnings) {
Warning[] w = warnings.toArray(new Warning[0]);
final JList<Warning> list = new JList<Warning>(w);
list.setCellRenderer(new BetterListCellRenderer());
JScrollPane pane = new JScrollPane(list);
pane.setBorder(GUIUtil.getUITheme().getBorder());
JOptionPane.showMessageDialog(parent, new Object[] { message, pane },
title, JOptionPane.WARNING_MESSAGE);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.dialogs.flightconfiguration;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Window;
import java.awt.event.ActionEvent;
@ -25,7 +24,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
public class RenameConfigDialog extends JDialog {
private static final long serialVersionUID = -5423008694485357248L;
private static final Translator trans = Application.getTranslator();
public RenameConfigDialog(final Window parent, final Rocket rocket, final FlightConfigurationId fcid) {
super(parent, trans.get("RenameConfigDialog.title"), Dialog.ModalityType.APPLICATION_MODAL);
@ -47,7 +46,7 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(okButton);
panel.add(okButton, "growx");
JButton renameToDefaultButton = new SelectColorButton(trans.get("RenameConfigDialog.but.reset"));
renameToDefaultButton.addActionListener(new ActionListener() {
@ -57,7 +56,7 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(renameToDefaultButton);
panel.add(renameToDefaultButton, "growx");
JButton cancel = new SelectColorButton(trans.get("button.cancel"));
cancel.addActionListener(new ActionListener() {
@ -66,14 +65,14 @@ public class RenameConfigDialog extends JDialog {
RenameConfigDialog.this.setVisible(false);
}
});
panel.add(cancel, "wrap para");
panel.add(cancel, "growx, wrap para");
// {motors} & {manufacturers} info
String text = "<html>" + CommonStrings.dagger + " " + trans.get("RenameConfigDialog.lbl.infoMotors")
+ trans.get("RenameConfigDialog.lbl.infoManufacturers")
+ trans.get("RenameConfigDialog.lbl.infoCombination");
StyledLabel info = new StyledLabel(text, -2);
info.setFontColor(Color.DARK_GRAY);
info.setFontColor(GUIUtil.getUITheme().getDimTextColor());
panel.add(info, "spanx, growx, wrap");
this.add(panel);

View File

@ -37,14 +37,13 @@ import net.sf.openrocket.unit.UnitGroup;
@SuppressWarnings("serial")
class MotorInformationPanel extends JPanel {
private static final Translator trans = Application.getTranslator();
private static final int ZOOM_ICON_POSITION_NEGATIVE_X = 50;
private static final int ZOOM_ICON_POSITION_POSITIVE_Y = 12;
private static final Color NO_COMMENT_COLOR = Color.GRAY;
private static final Color WITH_COMMENT_COLOR = Color.BLACK;
private static final Translator trans = Application.getTranslator();
private static final Color NO_COMMENT_COLOR = GUIUtil.getUITheme().getDimTextColor();
private static final Color WITH_COMMENT_COLOR = GUIUtil.getUITheme().getTextColor();
// Motors in set
private List<ThrustCurveMotor> selectedMotorSet;
@ -190,7 +189,9 @@ class MotorInformationPanel extends JPanel {
changeLabelFont(plot.getDomainAxis(), -2);
//// Thrust curve:
chart.setTitle(new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont()));
TextTitle title = new TextTitle(trans.get("TCMotorSelPan.title.Thrustcurve"), this.getFont());
title.setPaint(GUIUtil.getUITheme().getTextColor());
chart.setTitle(title);
chart.setBackgroundPaint(this.getBackground());
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.gui.dialogs.optimization;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Enumeration;
@ -17,6 +16,7 @@ import javax.swing.tree.TreePath;
import net.sf.openrocket.gui.components.BasicTree;
import net.sf.openrocket.gui.main.ComponentIcons;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
import net.sf.openrocket.rocketcomponent.Rocket;
@ -37,7 +37,7 @@ public class SimulationModifierTree extends BasicTree {
private final List<SimulationModifier> selectedModifiers;
private static final Translator trans = Application.getTranslator();
/**
* Sole constructor.
*
@ -151,11 +151,13 @@ public class SimulationModifierTree extends BasicTree {
// Set icon (for rocket components, null for others)
setIcon(ComponentIcons.getSmallIcon(object.getClass()));
// By default, set background to transparent
setOpaque(false);
// Set text color/style
if (object instanceof RocketComponent) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(componentFont);
// Set tooltip
@ -169,21 +171,24 @@ public class SimulationModifierTree extends BasicTree {
this.setToolTipText(null);
}
} else if (object instanceof String) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(stringFont);
} else if (object instanceof SimulationModifier) {
if (selectedModifiers.contains(object)) {
setForeground(Color.GRAY);
setForeground(GUIUtil.getUITheme().getDimTextColor());
setFont(stringFont);
} else {
if (tree.getSelectionRows() != null &&
IntStream.of(tree.getSelectionRows()).anyMatch(r -> r == row)) {
setForeground(Color.WHITE);
setForeground(GUIUtil.getUITheme().getTextSelectionForegroundColor());
setBackground(GUIUtil.getUITheme().getTextSelectionBackgroundColor());
setOpaque(true);
} else {
setForeground(Color.BLACK);
setForeground(GUIUtil.getUITheme().getTextColor());
}
setFont(modifierFont);
}
setFont(modifierFont);
setText(((SimulationModifier) object).getName());
setToolTipText(((SimulationModifier) object).getDescription());
}

View File

@ -20,9 +20,12 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
@ -31,6 +34,8 @@ import net.sf.openrocket.communication.ReleaseInfo;
import net.sf.openrocket.communication.UpdateInfo;
import net.sf.openrocket.communication.UpdateInfoRetriever;
import net.sf.openrocket.communication.UpdateInfoRetriever.ReleaseStatus;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.IntegerModel;
import net.sf.openrocket.gui.components.DescriptionArea;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style;
@ -40,6 +45,7 @@ import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.gui.util.PreferencesExporter;
import net.sf.openrocket.gui.util.PreferencesImporter;
import net.sf.openrocket.gui.util.UITheme;
import net.sf.openrocket.l10n.L10N;
import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.startup.Preferences;
@ -50,13 +56,17 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
@SuppressWarnings("serial")
public class GeneralPreferencesPanel extends PreferencesPanel {
private final UITheme.Theme currentTheme;
private final int currentFontSize;
public GeneralPreferencesPanel(PreferencesDialog parent) {
super(parent, new MigLayout("fillx, ins 30lp n n n"));
this.currentTheme = GUIUtil.getUITheme();
this.currentFontSize = preferences.getUIFontSize();
//// Language selector
Locale userLocale = null;
Locale userLocale;
{
String locale = preferences.getString("locale", null);
userLocale = L10N.toLocale(locale);
@ -79,6 +89,7 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
Named<Locale> selection = (Named<Locale>) languageCombo.getSelectedItem();
if (selection == null) return;
Locale l = selection.get();
preferences.putString(Preferences.USER_LOCAL, l == null ? null : l.toString());
}
@ -86,8 +97,64 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
this.add(new JLabel(trans.get("generalprefs.lbl.language")), "gapright para");
this.add(languageCombo, "wrap rel, growx, sg combos");
this.add(new StyledLabel(trans.get("generalprefs.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap para*2");
this.add(new StyledLabel(trans.get("generalprefs.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap rel");
//// UI Theme
UITheme.Theme currentTheme = GUIUtil.getUITheme();
List<Named<UITheme.Theme>> themes = new ArrayList<>();
for (UITheme.Theme t : UITheme.Themes.values()) {
themes.add(new Named<>(t, t.getDisplayName()));
}
Collections.sort(themes);
final JComboBox<?> themesCombo = new JComboBox<>(themes.toArray());
for (int i = 0; i < themes.size(); i++) {
if (Utils.equals(currentTheme, themes.get(i).get())) {
themesCombo.setSelectedIndex(i);
}
}
this.add(new JLabel(trans.get("generalprefs.lbl.UITheme")), "gapright para");
this.add(themesCombo, "wrap, growx, sg combos");
//// Font size
this.add(new JLabel(trans.get("generalprefs.lbl.FontSize")), "gapright para");
final IntegerModel fontSizeModel = new IntegerModel(preferences, "UIFontSize", 5, 25);
final JSpinner fontSizeSpinner = new JSpinner(fontSizeModel.getSpinnerModel());
fontSizeSpinner.setEditor(new SpinnerEditor(fontSizeSpinner));
this.add(fontSizeSpinner, "growx, wrap");
//// You need to restart OpenRocket for the theme change to take effect.
final JLabel lblRestartORTheme = new JLabel();
lblRestartORTheme.setForeground(GUIUtil.getUITheme().getDarkWarningColor());
this.add(lblRestartORTheme, "spanx, wrap para*2, growx");
fontSizeSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (fontSizeModel.getValue() == currentFontSize) {
lblRestartORTheme.setText("");
return;
}
lblRestartORTheme.setText(trans.get("generalprefs.lbl.themeRestartOR"));
}
});
themesCombo.addActionListener(new ActionListener() {
@Override
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
Named<UITheme.Theme> selection = (Named<UITheme.Theme>) themesCombo.getSelectedItem();
if (selection == null) return;
UITheme.Theme t = selection.get();
if (t == currentTheme) {
lblRestartORTheme.setText("");
return;
}
preferences.setUITheme(t);
lblRestartORTheme.setText(trans.get("generalprefs.lbl.themeRestartOR"));
}
});
//// User-defined thrust curves:
this.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap");
final JTextField field = new JTextField();
@ -180,8 +247,9 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
this.add(button, "wrap");
//// Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves. Changes will take effect the next time you start OpenRocket.
DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -3, false);
desc.setBackground(getBackground());
DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -1.5f, false);
desc.setBackground(GUIUtil.getUITheme().getBackgroundColor());
desc.setForeground(GUIUtil.getUITheme().getTextColor());
this.add(desc, "spanx, growx, wrap 40lp");

View File

@ -23,6 +23,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.models.atmosphere.ExtendedISAModel;
import net.sf.openrocket.simulation.SimulationOptions;
import net.sf.openrocket.unit.UnitGroup;
@ -43,7 +44,7 @@ public class LaunchPreferencesPanel extends PreferencesPanel {
StyledLabel warning = new StyledLabel(String.format(
"<html>%s</html>", trans.get("pref.dlg.lbl.launchWarning")),
0.5f, StyledLabel.Style.BOLD);
warning.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
warning.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
warning.setToolTipText(trans.get("pref.dlg.lbl.launchWarning.ttip"));
add(warning, "spanx, growx 0, gapbottom para, wrap");

View File

@ -17,6 +17,7 @@ import net.sf.openrocket.gui.adaptors.EnumModel;
import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.simulation.RK4SimulationStepper;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.GeodeticComputationStrategy;
@ -24,7 +25,7 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
public class SimulationPreferencesPanel extends PreferencesPanel {
private static final long serialVersionUID = 7983195730016979888L;
/*
* private GeodeticComputationStrategy geodeticComputation =
* GeodeticComputationStrategy.SPHERICAL;
@ -41,7 +42,7 @@ public class SimulationPreferencesPanel extends PreferencesPanel {
confirmDelete.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoRunSimulations(confirmDelete.isSelected());
preferences.setConfirmSimDeletion(confirmDelete.isSelected());
}
});
this.add(confirmDelete, "wrap, growx, sg combos ");
@ -84,7 +85,7 @@ public class SimulationPreferencesPanel extends PreferencesPanel {
StyledLabel warning = new StyledLabel(String.format(
"<html>%s</html>", trans.get("pref.dlg.lbl.launchWarning")),
0, StyledLabel.Style.BOLD);
warning.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
warning.setFontColor(GUIUtil.getUITheme().getDarkWarningColor());
warning.setToolTipText(trans.get("pref.dlg.lbl.launchWarning.ttip"));
subsub.add(warning, "spanx, wrap para");

View File

@ -10,6 +10,7 @@ import com.jogamp.opengl.fixedfunc.GLLightingFunc;
import net.sf.openrocket.gui.figure3d.geometry.Geometry;
import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
@ -80,7 +81,7 @@ public class FigureRenderer extends RocketRenderer {
if (defaultColorCache.containsKey(c.getClass())) {
figureColor = defaultColorCache.get(c.getClass());
} else {
figureColor = Application.getPreferences().getDefaultColor(c.getClass());
figureColor = ((SwingPreferences) Application.getPreferences()).getDefaultColor(c.getClass());
defaultColorCache.put(c.getClass(), figureColor);
}
}

View File

@ -42,9 +42,9 @@ public class RealisticRenderer extends RocketRenderer {
gl.glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT, new float[] { 0, 0, 0 }, 0);
float amb = 0.3f;
float dif = 1.0f - amb;
float spc = 1.0f;
float amb = 0.4f;
float dif = 0.65f;
float spc = 0.65f;
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, new float[] { amb, amb, amb, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_DIFFUSE, new float[] { dif, dif, dif, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, new float[] { spc, spc, spc, 1 }, 0);

View File

@ -34,6 +34,7 @@ import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputAdapter;
import net.sf.openrocket.gui.util.GUIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -64,7 +65,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(RocketFigure3d.class);
static {
//this allows the GL canvas and things like the motor selection
//drop down to z-order themselves.
@ -288,7 +289,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glClearColor(1, 1, 1, 1);
Color backgroundColor = GUIUtil.getUITheme().getBackgroundColor();
gl.glClearColor(backgroundColor.getRed()/255f, backgroundColor.getGreen()/255f,
backgroundColor.getBlue()/255f, backgroundColor.getAlpha()/255f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
setupView(gl, glu);
@ -315,8 +318,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
}
pickPoint = null;
gl.glClearColor(1, 1, 1, 1);
gl.glClearColor(backgroundColor.getRed()/255f, backgroundColor.getGreen()/255f,
backgroundColor.getBlue()/255f, backgroundColor.getAlpha()/255f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL.GL_MULTISAMPLE);

View File

@ -16,6 +16,8 @@ import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.gui.figure3d.geometry.Geometry.Surface;
import java.util.Collections;
public class FinRenderer {
private GLUtessellator tess = GLU.gluNewTess();
@ -96,12 +98,11 @@ public class FinRenderer {
GLU.gluTessBeginPolygon(tess, null);
GLU.gluTessBeginContour(tess);
gl.glNormal3f(0, 0, 1);
for (int i = tabPoints.length - 1; i >= 0; i--) {
Coordinate c = tabPoints[i];
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z + finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
}
for (Coordinate c : tabPoints) {
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z + finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
}
GLU.gluTessEndContour(tess);
GLU.gluTessEndPolygon(tess);
}
@ -125,7 +126,8 @@ public class FinRenderer {
GLU.gluTessBeginPolygon(tess, null);
GLU.gluTessBeginContour(tess);
gl.glNormal3f(0, 0, -1);
for (Coordinate c : tabPoints) {
for (int i = tabPoints.length - 1; i >= 0; i--) {
Coordinate c = tabPoints[i];
double[] p = new double[]{c.x, c.y + finSet.getBodyRadius(),
c.z - finSet.getThickness() / 2.0};
GLU.gluTessVertex(tess, p, 0, p);
@ -163,7 +165,7 @@ public class FinRenderer {
if (!(finSet instanceof EllipticalFinSet))
gl.glShadeModel(GLLightingFunc.GL_FLAT);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
for (int i = 0; i <= tabPoints.length; i++) {
for (int i = tabPoints.length; i >= 0; i--) {
Coordinate c = tabPoints[i % tabPoints.length];
// if ( i > 1 ){
Coordinate c2 = tabPoints[(i - 1 + tabPoints.length)

View File

@ -123,7 +123,7 @@ final class TransitionRenderer {
private TransitionRenderer() {
}
static final void drawTransition(final GL2 gl, final Transition tr,
static void drawTransition(final GL2 gl, final Transition tr,
final int slices, final int stacks, final double offsetRadius) {
double da, r, dzBase;
@ -131,14 +131,16 @@ final class TransitionRenderer {
int i;
da = 2.0f * Math.PI / slices;
dzBase = (double) tr.getLength() / stacks;
dzBase = tr.getLength() / stacks;
double ds = 1.0f / slices;
z = 0.0f;
r = (double) tr.getForeRadius();
while (z < tr.getLength()) {
double t = z / tr.getLength();
if (tr.getForeRadius() > tr.getAftRadius()) {
t = 1 - t;
}
double dz = t < 0.025 ? dzBase / 8.0 : dzBase;
double zNext = Math.min(z + dz, tr.getLength());

View File

@ -371,9 +371,9 @@ public class PhotoFrame extends JFrame {
guiModule.startLoader();
// Set the best available look-and-feel
log.info("Setting best LAF");
GUIUtil.setBestLAF();
// Set the look-and-feel
log.info("Setting LAF");
GUIUtil.applyLAF();
// Load defaults
((SwingPreferences) Application.getPreferences()).loadDefaultUnits();

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.gui.figureelements;
import net.sf.openrocket.gui.util.GUIUtil;
import java.awt.Color;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
@ -16,7 +18,7 @@ public class CGCaret extends Caret {
private static final float RADIUS = 7;
private static Area caret = null;
/**
* Create a new CGCaret at the specified coordinates.
*/
@ -56,7 +58,7 @@ public class CGCaret extends Caret {
*/
@Override
protected Color getColor() {
return Color.BLUE;
return GUIUtil.getUITheme().getCGColor();
}
}

View File

@ -1,5 +1,7 @@
package net.sf.openrocket.gui.figureelements;
import net.sf.openrocket.gui.util.GUIUtil;
import java.awt.Color;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
@ -15,7 +17,7 @@ public class CPCaret extends Caret {
private static final float RADIUS = 7;
private static Area caret = null;
/**
* Create a new CPCaret at the specified coordinates.
*/
@ -51,6 +53,6 @@ public class CPCaret extends Caret {
*/
@Override
protected Color getColor() {
return Color.RED;
return GUIUtil.getUITheme().getCPColor();
}
}

View File

@ -3,7 +3,6 @@ package net.sf.openrocket.gui.figureelements;
import static net.sf.openrocket.util.Chars.ALPHA;
import static net.sf.openrocket.util.Chars.THETA;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
@ -11,6 +10,7 @@ import java.awt.Rectangle;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.logging.Warning;
import net.sf.openrocket.logging.WarningSet;
@ -176,7 +176,7 @@ public class RocketInfo implements FigureElement {
GlyphVector massLineWithoutMotors = createText(massTextWithoutMotors);
g2.setColor(Color.BLACK);
g2.setColor(GUIUtil.getUITheme().getTextColor());
g2.drawGlyphVector(name, x1, y1);
g2.drawGlyphVector(lengthLine, x1, y1+line);
@ -234,7 +234,7 @@ public class RocketInfo implements FigureElement {
unitWidth = unitWidth + spaceWidth;
stabUnitWidth = stabUnitWidth + spaceWidth;
g2.setColor(Color.BLACK);
g2.setColor(GUIUtil.getUITheme().getTextColor());
// Draw the stability, CG & CP values (and units)
g2.drawGlyphVector(stabValue, (float)(x2-stabRect.getWidth()), y1);
@ -261,7 +261,7 @@ public class RocketInfo implements FigureElement {
atPos = (float)(x2 - atTextRect.getWidth());
}
g2.setColor(Color.GRAY);
g2.setColor(GUIUtil.getUITheme().getDimTextColor());
g2.drawGlyphVector(atText, atPos, y1 + 3*line);
}
@ -411,7 +411,7 @@ public class RocketInfo implements FigureElement {
float y = y2 - line * (texts.length-1);
g2.setColor(Color.RED);
g2.setColor(GUIUtil.getUITheme().getWarningColor());
for (GlyphVector v: texts) {
Rectangle2D rect = v.getVisualBounds();
@ -427,7 +427,7 @@ public class RocketInfo implements FigureElement {
if (calculatingData) {
//// Calculating...
GlyphVector calculating = createText(trans.get("RocketInfo.Calculating"));
g2.setColor(Color.BLACK);
g2.setColor(GUIUtil.getUITheme().getTextColor());
g2.drawGlyphVector(calculating, x1, (float)(y2-height));
}
}
@ -485,11 +485,10 @@ public class RocketInfo implements FigureElement {
width += 5;
if (!calculatingData)
g2.setColor(new Color(0,0,127));
g2.setColor(GUIUtil.getUITheme().getFlightDataTextActiveColor());
else
g2.setColor(new Color(0,0,127,127));
g2.setColor(GUIUtil.getUITheme().getFlightDataTextInactiveColor());
g2.drawGlyphVector(apogee, (float)x1, (float)(y2-2*line));
g2.drawGlyphVector(maxVelocity, (float)x1, (float)(y2-line));
g2.drawGlyphVector(maxAcceleration, (float)x1, (float)(y2));
@ -502,7 +501,7 @@ public class RocketInfo implements FigureElement {
}
private synchronized void updateFontSizes() {
float size = Application.getPreferences().getRocketInfoFontSize();
float size = ((SwingPreferences) Application.getPreferences()).getRocketInfoFontSize();
// No change necessary as the font is the same size, just use the existing version
if (font.getSize2D() == size) {
return;

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.help.tours;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@ -11,6 +12,7 @@ import java.util.Map;
import javax.swing.text.html.StyleSheet;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.util.BugException;
/**
@ -130,6 +132,9 @@ public class SlideSetManager {
try {
StyleSheet ss = new StyleSheet();
Color textColor = GUIUtil.getUITheme().getTextColor();
ss.addRule(String.format("p { color: rgb(%d, %d, %d, %d)",
textColor.getRed(), textColor.getGreen(), textColor.getBlue(), textColor.getAlpha()));
InputStreamReader reader = new InputStreamReader(in, "UTF-8");
ss.loadRules(reader, null);
return ss;

View File

@ -12,6 +12,7 @@ import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import net.sf.openrocket.gui.components.ImageDisplayComponent;
import net.sf.openrocket.gui.util.GUIUtil;
/**
* Component that displays a single slide, with the image on top and
@ -28,7 +29,7 @@ public class SlideShowComponent extends JSplitPane {
private final ImageDisplayComponent imageDisplay;
private final JEditorPane textPane;
public SlideShowComponent() {
super(VERTICAL_SPLIT);
@ -44,6 +45,7 @@ public class SlideShowComponent extends JSplitPane {
textPane.setPreferredSize(new Dimension(WIDTH, HEIGHT_TEXT));
JScrollPane scrollPanel = new JScrollPane(textPane);
textPane.setBorder(GUIUtil.getUITheme().getBorder());
this.setRightComponent(scrollPanel);
this.setResizeWeight(((double) HEIGHT_IMAGE) / (HEIGHT_IMAGE + HEIGHT_TEXT));

View File

@ -579,12 +579,12 @@ public class BasicFrame extends JFrame {
editMenu.addSeparator();
JMenu subMenu = new JMenu(trans.get("RocketActions.Select"));
editMenu.add(subMenu);
JMenu selectSubMenu = new JMenu(trans.get("RocketActions.Select"));
editMenu.add(selectSubMenu);
item = new JMenuItem(actions.getSelectSameColorAction());
subMenu.add(item);
selectSubMenu.add(item);
item = new JMenuItem(actions.getDeselectAllAction());
subMenu.add(item);
selectSubMenu.add(item);
editMenu.addSeparator();

View File

@ -4,6 +4,7 @@ package net.sf.openrocket.gui.main;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@ -209,7 +210,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
for (col = 0; col < buttons[row].length; col++) {
buttons[row][col].setMinimumSize(d);
buttons[row][col].setPreferredSize(d);
buttons[row][col].getComponent(0).validate();
buttons[row][col].validate();
}
}
@ -315,29 +316,32 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
* The label may contain "\n" as a newline.
*/
public ComponentButton(String text, Icon enabled, Icon disabled) {
super();
setLayout(new MigLayout("fill, flowy, insets 0, gap 0", "", ""));
add(new JLabel(), "push, sizegroup spacing");
// Add Icon
if (enabled != null) {
JLabel label = new JLabel(enabled);
if (disabled != null)
label.setDisabledIcon(disabled);
add(label, "growx");
super(text, enabled);
setVerticalTextPosition(SwingConstants.BOTTOM); // this will put the text below the icon
setHorizontalTextPosition(SwingConstants.CENTER); // this will center the text horizontally beneath the icon
//setIconTextGap(0); // this is optional, it sets the gap between the icon and the text
// set the disabled icon if it is not null
if (disabled != null) {
setDisabledIcon(disabled);
}
// Add labels
String[] l = text.split("\n");
for (int i = 0; i < l.length; i++) {
add(new StyledLabel(l[i], SwingConstants.CENTER, -2.0f), "growx");
setHorizontalAlignment(SwingConstants.CENTER); // this will center the button itself in its parent component
// if you have multiline text, you could use html to format it
if (text != null && text.contains("\n")) {
text = "<html>" + text.replace("\n", "<br>") + "</html>";
setText(text);
}
// Initialize enabled status
valueChanged(null);
// Attach a tree selection listener if selection model is not null
if (selectionModel != null) {
selectionModel.addTreeSelectionListener(this);
}
add(new JLabel(), "push, sizegroup spacing");
valueChanged(null); // Update enabled status
selectionModel.addTreeSelectionListener(this);
}

View File

@ -61,13 +61,13 @@ public class DesignPanel extends JSplitPane {
// Remove JTree key events that interfere with menu accelerators
InputMap im = SwingUtilities.getUIInputMap(tree, JComponent.WHEN_FOCUSED);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, SHORTCUT_KEY), null);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY), "none");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_N, SHORTCUT_KEY), "none");
// Highlight all child components of a stage/rocket/podset when it is selected
tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@ -174,6 +174,7 @@ public class DesignPanel extends JSplitPane {
// Place tree inside scroll pane
JScrollPane scroll = new JScrollPane(tree);
tree.setBorder(GUIUtil.getUITheme().getBorder());
panel.add(scroll, "spany, wmin 140px, grow, wrap");

View File

@ -4,6 +4,7 @@ package net.sf.openrocket.gui.main;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.Serial;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -13,15 +14,13 @@ import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
import net.sf.openrocket.gui.dialogs.ScaleDialog;
import net.sf.openrocket.gui.util.Icons;
@ -34,7 +33,6 @@ import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.Color;
import net.sf.openrocket.util.Pair;
import org.slf4j.Logger;
@ -59,6 +57,7 @@ public class RocketActions {
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke EDIT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_E,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke DELETE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
private final OpenRocketDocument document;
private final Rocket rocket;
@ -67,8 +66,6 @@ public class RocketActions {
private final SimulationPanel simulationPanel;
private final RocketAction deleteComponentAction;
private final RocketAction deleteSimulationAction;
private final RocketAction deleteAction;
private final RocketAction cutAction;
private final RocketAction copyAction;
@ -94,8 +91,6 @@ public class RocketActions {
// Add action also to updateActions()
this.deleteAction = new DeleteAction();
this.deleteComponentAction = new DeleteComponentAction();
this.deleteSimulationAction = new DeleteSimulationAction();
this.cutAction = new CutAction();
this.copyAction = new CopyAction();
this.pasteAction = new PasteAction();
@ -107,10 +102,15 @@ public class RocketActions {
this.moveUpAction = new MoveUpAction();
this.moveDownAction = new MoveDownAction();
OpenRocketClipboard.addClipboardListener(this.pasteAction);
OpenRocketClipboard.addClipboardListener(new ClipboardListener() {
@Override
public void clipboardChanged() {
updateActions();
}
});
updateActions();
// Update all actions when tree selection or rocket changes
// Update all actions when tree selection, simulation selection or rocket changes
selectionModel.addDocumentSelectionListener(new DocumentSelectionListener() {
@Override
@ -118,6 +118,12 @@ public class RocketActions {
updateActions();
}
});
simulationPanel.addSimulationTableListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
updateActions();
}
});
document.getRocket().addComponentChangeListener(new ComponentChangeListener() {
@Override
public void componentChanged(ComponentChangeEvent e) {
@ -130,12 +136,13 @@ public class RocketActions {
* Update the state of all of the actions.
*/
private void updateActions() {
deleteAction.clipboardChanged();
simulationPanel.updateActions();
editAction.clipboardChanged();
cutAction.clipboardChanged();
copyAction.clipboardChanged();
pasteAction.clipboardChanged();
deleteAction.clipboardChanged();
duplicateAction.clipboardChanged();
editAction.clipboardChanged();
selectSameColorAction.clipboardChanged();
deselectAllAction.clipboardChanged();
scaleAction.clipboardChanged();
@ -143,16 +150,8 @@ public class RocketActions {
moveDownAction.clipboardChanged();
}
public Action getDeleteComponentAction() {
return deleteAction;
}
public Action getDeleteSimulationAction() {
return deleteAction;
}
public Action getDeleteAction() {
return deleteAction;
@ -313,7 +312,7 @@ public class RocketActions {
}
private boolean isCopyable(List<RocketComponent> components) {
if (components == null || components.size() == 0) return false;
if (components == null || components.isEmpty()) return false;
for (RocketComponent component : components) {
if (!isCopyable(component)) return false;
}
@ -409,43 +408,14 @@ public class RocketActions {
private boolean isSimulationSelected() {
Simulation[] selection = selectionModel.getSelectedSimulations();
return (selection != null && selection.length > 0);
}
private boolean verifyDeleteSimulation() {
boolean verify = Application.getPreferences().getBoolean(Preferences.CONFIRM_DELETE_SIMULATION, true);
if (verify) {
JPanel panel = new JPanel(new MigLayout());
//// Do not ask me again
JCheckBox dontAsk = new JCheckBox(trans.get("RocketActions.checkbox.Donotaskmeagain"));
panel.add(dontAsk,"wrap");
//// You can change the default operation in the preferences.
panel.add(new StyledLabel(trans.get("RocketActions.lbl.Youcanchangedefop"),-2));
int ret = JOptionPane.showConfirmDialog(
parentFrame,
new Object[] {
//// Delete the selected simulations?
trans.get("RocketActions.showConfirmDialog.lbl1"),
//// <html><i>This operation cannot be undone.</i>
trans.get("RocketActions.showConfirmDialog.lbl2"),
"",
panel },
//// Delete simulations
trans.get("RocketActions.showConfirmDialog.title"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (ret != JOptionPane.OK_OPTION)
return false;
if (dontAsk.isSelected()) {
Application.getPreferences().putBoolean(Preferences.CONFIRM_DELETE_SIMULATION, false);
if (selection != null && selection.length > 0) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components != null && !components.isEmpty()) {
throw new IllegalStateException("Both simulation and component selected");
}
return true;
}
return true;
return false;
}
@ -517,130 +487,60 @@ public class RocketActions {
public abstract void clipboardChanged();
}
/**
* Action that deletes the selected component.
* Action to edit the currently selected component.
*/
private class DeleteComponentAction extends RocketAction {
private class EditAction extends RocketAction {
@Serial
private static final long serialVersionUID = 1L;
public DeleteComponentAction() {
//// Delete
this.putValue(NAME, trans.get("RocketActions.DelCompAct.Delete"));
//// Delete the selected component.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelCompAct.ttip.Delete"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = new ArrayList<>(selectionModel.getSelectedComponents());
if (components.size() == 0) return;
components.sort(Comparator.comparing(c -> c.getParent().getChildPosition(c)));
if (components.size() == 1) {
document.addUndoPosition("Delete " + components.get(0).getComponentName());
} else {
document.addUndoPosition("Delete components");
}
for (RocketComponent component : components) {
deleteComponent(component);
}
}
private void deleteComponent(RocketComponent component) {
if (isDeletable(component)) {
ComponentConfigDialog.disposeDialog();
try {
component.getRocket().removeComponentChangeListener(ComponentConfigDialog.getDialog());
delete(component);
} catch (IllegalStateException ignored) { }
}
}
@Override
public void clipboardChanged() {
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()));
}
}
/**
* Action that deletes the selected component.
*/
private class DeleteSimulationAction extends RocketAction {
private static final long serialVersionUID = 1L;
public DeleteSimulationAction() {
//// Delete
this.putValue(NAME, trans.get("RocketActions.DelSimuAct.Delete"));
//// Delete the selected simulation.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelSimuAct.ttip.Delete"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
// this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
Simulation[] sims = selectionModel.getSelectedSimulations();
if (sims.length > 0) {
if (verifyDeleteSimulation()) {
for (Simulation s: sims) {
document.removeSimulation(s);
}
}
}
}
@Override
public void clipboardChanged() {
this.setEnabled(isSimulationSelected());
}
}
/**
* Action that deletes the selected component.
*/
private class DeleteAction extends RocketAction {
private static final long serialVersionUID = 1L;
public DeleteAction() {
//// Delete
this.putValue(NAME, trans.get("RocketActions.DelAct.Delete"));
//// Delete the selected component or simulation.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelAct.ttip.Delete"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
public EditAction() {
//// Edit
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
this.putValue(ACCELERATOR_KEY, EDIT_KEY_STROKE);
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
if (isSimulationSelected()) {
deleteSimulationAction.actionPerformed(e);
simulationPanel.getEditSimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
deleteComponentAction.actionPerformed(e);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
editComponents();
// I wouldn't switch to the design tab here, because the user may be editing in the rocket view window
}
}
private void editComponents() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components == null || components.isEmpty()) {
return;
}
if (ComponentConfigDialog.isDialogVisible())
ComponentConfigDialog.disposeDialog();
RocketComponent component = components.get(0);
component.clearConfigListeners();
if (components.size() > 1) {
for (int i = 1; i < components.size(); i++) {
RocketComponent listener = components.get(i);
listener.clearConfigListeners(); // Make sure all the listeners are cleared (should not be possible, but just in case)
component.addConfigListener(listener);
}
}
ComponentConfigDialog.showDialog(parentFrame, document, component);
}
@Override
public void clipboardChanged() {
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
isSimulationSelected());
List<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled(!components.isEmpty() || simulationPanel.getEditSimulationAction().isEnabled());
}
}
@ -650,14 +550,14 @@ public class RocketActions {
* Action the cuts the selected component (copies to clipboard and deletes).
*/
private class CutAction extends RocketAction {
@Serial
private static final long serialVersionUID = 1L;
public CutAction() {
//// Cut
this.putValue(NAME, trans.get("RocketActions.CutAction.Cut"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_T);
this.putValue(MNEMONIC_KEY, KeyEvent.VK_T); // Use the 't' in Cut as mnemonic
this.putValue(ACCELERATOR_KEY, CUT_KEY_STROKE);
//// Cut this component or simulation to the clipboard and remove from this design
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CutAction.ttip.Cut"));
this.putValue(SMALL_ICON, Icons.EDIT_CUT);
clipboardChanged();
@ -665,49 +565,49 @@ public class RocketActions {
@Override
public void actionPerformed(ActionEvent e) {
if (isSimulationSelected()) {
simulationPanel.getCutSimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
cutComponents();
}
}
private void cutComponents() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components.size() > 0) {
if (!components.isEmpty()) {
components = new ArrayList<>(components);
fillInMissingSelections(components);
components.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
}
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isDeletable(components) && isCopyable(components)) {
ComponentConfigDialog.disposeDialog();
if (components.size() == 1) {
document.addUndoPosition("Cut " + components.get(0).getComponentName());
} else {
document.addUndoPosition("Cut components");
}
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
OpenRocketClipboard.setClipboard(copiedComponents);
delete(components);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
} else if (isSimulationSelected()) {
Simulation[] simsCopy = new Simulation[sims.length];
for (int i=0; i < sims.length; i++) {
simsCopy[i] = sims[i].copy();
}
OpenRocketClipboard.setClipboard(simsCopy);
for (Simulation s: sims) {
document.removeSimulation(s);
}
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
if (!(isDeletable(components) && isCopyable(components))) {
return;
}
ComponentConfigDialog.disposeDialog();
if (components.size() == 1) {
document.addUndoPosition("Cut " + components.get(0).getComponentName());
} else {
document.addUndoPosition("Cut components");
}
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
OpenRocketClipboard.setClipboard(copiedComponents);
delete(components);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
}
@Override
public void clipboardChanged() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled((isDeletable(components) && isCopyable(components)) || isSimulationSelected());
this.setEnabled((isDeletable(components) && isCopyable(components)) ||
simulationPanel.getCutSimulationAction().isEnabled());
}
}
@ -722,46 +622,47 @@ public class RocketActions {
public CopyAction() {
//// Copy
this.putValue(NAME, trans.get("RocketActions.CopyAct.Copy"));
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.ttip.Copy"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
this.putValue(ACCELERATOR_KEY, COPY_KEY_STROKE);
//// Copy this component (and subcomponents) to the clipboard.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.ttip.Copy"));
this.putValue(SMALL_ICON, Icons.EDIT_COPY);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
if (isSimulationSelected()) {
simulationPanel.getCopySimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
copyComponents();
}
}
private void copyComponents() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components.size() > 0) {
if (!components.isEmpty()) {
components = new ArrayList<>(components);
fillInMissingSelections(components);
components.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
}
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isCopyable(components)) {
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
OpenRocketClipboard.setClipboard(copiedComponents);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
} else if (sims != null && sims.length > 0) {
Simulation[] simsCopy = new Simulation[sims.length];
for (int i=0; i < sims.length; i++) {
simsCopy[i] = sims[i].copy();
}
OpenRocketClipboard.setClipboard(simsCopy);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
if (!isCopyable(components)) {
return;
}
List<RocketComponent> copiedComponents = new LinkedList<>(copyComponentsMaintainParent(components));
copiedComponents.sort(Comparator.comparing(c -> c.getParent() != null ? -c.getParent().getChildPosition(c) : 0));
OpenRocketClipboard.setClipboard(copiedComponents);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
}
@Override
public void clipboardChanged() {
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
isSimulationSelected());
simulationPanel.getCopySimulationAction().isEnabled());
}
}
@ -779,9 +680,8 @@ public class RocketActions {
public PasteAction() {
//// Paste
this.putValue(NAME, trans.get("RocketActions.PasteAct.Paste"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_P);
this.putValue(MNEMONIC_KEY, KeyEvent.VK_V);
this.putValue(ACCELERATOR_KEY, PASTE_KEY_STROKE);
//// Paste the component or simulation on the clipboard to the design.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.PasteAct.ttip.Paste"));
this.putValue(SMALL_ICON, Icons.EDIT_PASTE);
clipboardChanged();
@ -789,76 +689,67 @@ public class RocketActions {
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
Simulation[] sims = OpenRocketClipboard.getClipboardSimulations();
if (components.size() > 0) {
ComponentConfigDialog.disposeDialog();
List<RocketComponent> pasted = new LinkedList<>();
for (RocketComponent component : components) {
pasted.add(component.copy());
}
List<Pair<RocketComponent, Integer>> positions = getPastePositions(pasted);
if (pasted.size() == 1) {
document.addUndoPosition("Paste " + pasted.get(0).getComponentName());
} else {
document.addUndoPosition("Paste components");
}
List<RocketComponent> successfullyPasted = new LinkedList<>();
for (int i = 0; i < pasted.size(); i++) {
if (positions.get(i) == null) {
JOptionPane.showMessageDialog(null,
String.format(trans.get("RocketActions.PasteAct.invalidPosition.msg"),
pasted.get(i).getComponentName()),
trans.get("RocketActions.PasteAct.invalidPosition.title"), JOptionPane.WARNING_MESSAGE);
} else {
RocketComponent parent = positions.get(i).getU();
RocketComponent child = pasted.get(i);
if (parent != null && parent.isCompatible(child)) {
parent.addChild(child, positions.get(i).getV());
successfullyPasted.add(pasted.get(i));
} else {
log.warn("Pasted component {} is not compatible with {}", child, parent);
}
}
}
selectionModel.setSelectedComponents(successfullyPasted);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
} else if (sims != null) {
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
for (Simulation s: sims) {
Simulation copy = s.duplicateSimulation(rocket);
String name = copy.getName();
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
copy.setName(document.getNextSimulationName());
}
document.addSimulation(copy);
copySims.add(copy);
}
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
if (isSimulationSelected()) {
simulationPanel.getPasteSimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
pasteComponents();
}
}
private void pasteComponents() {
List<RocketComponent> components = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
if (components.isEmpty()) {
return;
}
ComponentConfigDialog.disposeDialog();
List<RocketComponent> pasted = new LinkedList<>();
for (RocketComponent component : components) {
pasted.add(component.copy());
}
List<Pair<RocketComponent, Integer>> positions = getPastePositions(pasted);
if (pasted.size() == 1) {
document.addUndoPosition("Paste " + pasted.get(0).getComponentName());
} else {
document.addUndoPosition("Paste components");
}
List<RocketComponent> successfullyPasted = new LinkedList<>();
for (int i = 0; i < pasted.size(); i++) {
if (positions.get(i) == null) {
JOptionPane.showMessageDialog(null,
String.format(trans.get("RocketActions.PasteAct.invalidPosition.msg"),
pasted.get(i).getComponentName()),
trans.get("RocketActions.PasteAct.invalidPosition.title"), JOptionPane.WARNING_MESSAGE);
} else {
RocketComponent parent = positions.get(i).getU();
RocketComponent child = pasted.get(i);
if (parent != null && parent.isCompatible(child)) {
parent.addChild(child, positions.get(i).getV());
successfullyPasted.add(pasted.get(i));
} else {
log.warn("Pasted component {} is not compatible with {}", child, parent);
}
}
}
selectionModel.setSelectedComponents(successfullyPasted);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
}
@Override
public void clipboardChanged() {
this.setEnabled(
(getPastePositions(OpenRocketClipboard.getClipboardComponents()).size() > 0) ||
(OpenRocketClipboard.getClipboardSimulations() != null));
this.setEnabled(!getPastePositions(OpenRocketClipboard.getClipboardComponents()).isEmpty() ||
simulationPanel.getPasteSimulationAction().isEnabled());
}
}
/**
* Action that duplicates the selected component.
*/
@ -870,7 +761,6 @@ public class RocketActions {
this.putValue(NAME, trans.get("RocketActions.DuplicateAct.Duplicate"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
this.putValue(ACCELERATOR_KEY, DUPLICATE_KEY_STROKE);
//// Copy this component (and subcomponents) to the clipboard.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DuplicateAct.ttip.Duplicate"));
this.putValue(SMALL_ICON, Icons.EDIT_DUPLICATE);
clipboardChanged();
@ -878,6 +768,15 @@ public class RocketActions {
@Override
public void actionPerformed(ActionEvent e) {
if (isSimulationSelected()) {
simulationPanel.getDuplicateSimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
duplicateComponents();
}
}
private void duplicateComponents() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
List<RocketComponent> topComponents = new LinkedList<>(); // Components without a parent component in <components>
if (components.size() > 0) {
@ -892,136 +791,130 @@ public class RocketActions {
topComponents.add(c);
}
}
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isCopyable(components)) {
if (ComponentConfigDialog.isDialogVisible())
ComponentConfigDialog.disposeDialog();
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
OpenRocketClipboard.setClipboard(copiedComponents);
copiedComponents = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
List<RocketComponent> duplicateComponents = new LinkedList<>();
for (RocketComponent component : copiedComponents) {
duplicateComponents.add(component.copy());
}
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
for (RocketComponent component : duplicateComponents) {
Pair<RocketComponent, Integer> pos;
if (RocketComponent.listContainsParent(duplicateComponents, component)) {
pos = getPastePosition(component, component.getParent());
} else {
int compIdx = duplicateComponents.indexOf(component);
RocketComponent pasteParent = topComponents.get(compIdx).getParent();
pos = getPastePosition(component, pasteParent);
}
positions.add(pos);
}
if (duplicateComponents.size() == 1) {
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
} else {
document.addUndoPosition("Duplicate components");
}
Collections.reverse(duplicateComponents);
Collections.reverse(positions);
for (int i = 0; i < duplicateComponents.size(); i++) {
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
}
selectionModel.setSelectedComponents(duplicateComponents);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
} else if (sims != null && sims.length > 0) {
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
// TODO: the undoing doesn't do anything...
if (sims.length == 1) {
document.addUndoPosition("Duplicate " + sims[0].getName());
} else {
document.addUndoPosition("Duplicate simulations");
}
for (Simulation s: sims) {
Simulation copy = s.duplicateSimulation(rocket);
String name = copy.getName();
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
copy.setName(document.getNextSimulationName());
}
document.addSimulation(copy);
copySims.add(copy);
}
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
if (!isCopyable(components)) {
return;
}
if (ComponentConfigDialog.isDialogVisible())
ComponentConfigDialog.disposeDialog();
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
OpenRocketClipboard.setClipboard(copiedComponents);
copiedComponents = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
List<RocketComponent> duplicateComponents = new LinkedList<>();
for (RocketComponent component : copiedComponents) {
duplicateComponents.add(component.copy());
}
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
for (RocketComponent component : duplicateComponents) {
Pair<RocketComponent, Integer> pos;
if (RocketComponent.listContainsParent(duplicateComponents, component)) {
pos = getPastePosition(component, component.getParent());
} else {
int compIdx = duplicateComponents.indexOf(component);
RocketComponent pasteParent = topComponents.get(compIdx).getParent();
pos = getPastePosition(component, pasteParent);
}
positions.add(pos);
}
if (duplicateComponents.size() == 1) {
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
} else {
document.addUndoPosition("Duplicate components");
}
Collections.reverse(duplicateComponents);
Collections.reverse(positions);
for (int i = 0; i < duplicateComponents.size(); i++) {
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
}
selectionModel.setSelectedComponents(duplicateComponents);
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
}
@Override
public void clipboardChanged() {
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
isSimulationSelected());
simulationPanel.getDuplicateSimulationAction().isEnabled());
}
}
/**
* Action to edit the currently selected component.
* Action that deletes the selected component.
*/
private class EditAction extends RocketAction {
private class DeleteAction extends RocketAction {
private static final long serialVersionUID = 1L;
public EditAction() {
//// Edit
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
this.putValue(ACCELERATOR_KEY, EDIT_KEY_STROKE);
//// Edit the selected component.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
public DeleteAction() {
//// Delete
this.putValue(NAME, trans.get("RocketActions.DelAct.Delete"));
//// Delete the selected component or simulation.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelAct.ttip.Delete"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_DELETE);
this.putValue(ACCELERATOR_KEY, DELETE_KEY_STROKE);
this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isSimulationSelected()) {
simulationPanel.getDeleteSimulationAction().actionPerformed(e);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
} else {
deleteComponents();
}
}
if (components.size() > 0) {
if (ComponentConfigDialog.isDialogVisible())
ComponentConfigDialog.disposeDialog();
private void deleteComponents() {
List<RocketComponent> components = new ArrayList<>(selectionModel.getSelectedComponents());
if (components.size() == 0) return;
components.sort(Comparator.comparing(c -> c.getParent().getChildPosition(c)));
RocketComponent component = components.get(0);
component.clearConfigListeners();
if (components.size() > 1) {
for (int i = 1; i < components.size(); i++) {
RocketComponent listener = components.get(i);
listener.clearConfigListeners(); // Make sure all the listeners are cleared (should not be possible, but just in case)
component.addConfigListener(listener);
}
}
ComponentConfigDialog.showDialog(parentFrame, document, component);
} else if (sims != null && sims.length > 0 && (simulationPanel != null)) {
simulationPanel.editSimulation();
if (components.size() == 1) {
document.addUndoPosition("Delete " + components.get(0).getComponentName());
} else {
document.addUndoPosition("Delete components");
}
for (RocketComponent component : components) {
deleteComponent(component);
}
parentFrame.selectTab(BasicFrame.DESIGN_TAB);
}
private void deleteComponent(RocketComponent component) {
if (isDeletable(component)) {
ComponentConfigDialog.disposeDialog();
try {
component.getRocket().removeComponentChangeListener(ComponentConfigDialog.getDialog());
delete(component);
} catch (IllegalStateException ignored) { }
}
}
@Override
public void clipboardChanged() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled(components.size() > 0 || isSimulationSelected());
this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
simulationPanel.getDeleteSimulationAction().isEnabled());
}
}
/**
* Action to select all components with the same color as the currently selected component.
*/
@ -1038,7 +931,7 @@ public class RocketActions {
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components.size() == 0) {
if (components.isEmpty()) {
return;
}

Some files were not shown because too many files have changed in this diff Show More