Merge branch 'openrocket:unstable' into scripting

This commit is contained in:
thzero 2022-08-02 09:22:08 -05:00 committed by GitHub
commit 3ed19060bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1016 additions and 578 deletions

View File

@ -17,6 +17,7 @@
<classpathentry kind="lib" path="lib/javax.inject.jar"/>
<classpathentry kind="lib" path="lib/javax.json-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/javax.json-api-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/javax.activation-api.2.3.1.jar"/>
<classpathentry kind="lib" path="lib/aopalliance.jar"/>
<classpathentry kind="lib" path="lib/commonmark-0.19.0.jar"/>
<classpathentry kind="lib" path="lib/slf4j-api-1.7.30.jar"/>

View File

@ -1052,7 +1052,10 @@ LaunchLugCfg.tab.Generalprop = General properties
! RailButtonConfig
RailBtnCfg.lbl.OuterDiam = Outer Diameter:
RailBtnCfg.lbl.TotalHeight = Total Height
RailBtnCfg.lbl.InnerDiam = Inner Diameter:
RailBtnCfg.lbl.TotalHeight = Total Height:
RailBtnCfg.lbl.BaseHeight = Base Height:
RailBtnCfg.lbl.FlangeHeight = Flange Height:
RailBtnCfg.lbl.Angle = Rotation:
RailBtnCfg.lbl.PosRelativeTo = Position relative to:
RailBtnCfg.lbl.Plus = plus
@ -2099,7 +2102,7 @@ ComponentPresetChooserDialog.menu.sortDesc = Sort Descending
ComponentPresetChooserDialog.menu.units = Units
ComponentPresetChooserDialog.checkbox.showAllCompatible = Show all compatible
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database
ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog
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.
table.column.Favorite = Favorite
table.column.Legacy = Legacy
table.column.Manufacturer = Manufacturer
@ -2116,19 +2119,23 @@ table.column.AftShoulderDiameter = Aft Shoulder Diameter
table.column.ForeShoulderLength = Fore Shoulder Length
table.column.ForeShoulderDiameter = Fore Shoulder Diameter
table.column.ForeOuterDiameter = Fore Outer Diameter
table.column.StandoffHeight = Standoff Height
table.column.BaseHeight = Base Height
table.column.FlangeHeight = Flange Height
table.column.ScrewHeight = Screw Height
table.column.Shape = Shape
table.column.Material = Material
table.column.Finish = Finish
table.column.Thickness = Thickness
table.column.Filled = Filled
table.column.Mass = Mass
table.column.ScrewMass = Screw Mass
table.column.NutMass = Nut Mass
table.column.Diameter = Diameter
table.column.Sides = Sides
table.column.LineCount = Line Count
table.column.LineLength = Line Length
table.column.LineMaterial = Line Material
table.column.CD = Drag Coefficient
! Edit Decal Dialog
EditDecalDialog.title = Edit decal

View File

@ -2003,7 +2003,7 @@ table.column.AftShoulderDiameter = Achteste Schouderdiameter
table.column.ForeShoulderLength = Voorste Schouderlengte
table.column.ForeShoulderDiameter = Voorste Schouderdiameter
table.column.ForeOuterDiameter = Voorste Buitendiameter
table.column.StandoffHeight = Standoff Hoogte
table.column.BaseHeight = Standoff Hoogte
table.column.FlangeHeight = Flens Hoogte
table.column.Shape = Vorm
table.column.Material = Materiaal

View File

@ -293,8 +293,10 @@ pref.dlg.lbl.launchWarning.ttip = \u0412\u044B \u043D\u0435 \u043F\u0435\u0440\u
pref.dlg.lbl.Positiontoinsert = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432:
pref.dlg.lbl.PositiontoinsertStages = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u0441\u0442\u0443\u043F\u0435\u043D\u0435\u0439:
pref.dlg.lbl.Confirmdeletion = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0447\u0435\u0442\u0430:
pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432.
pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432
pref.dlg.checkbox.Updateestimates = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C\u044B\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u043B\u0435\u0442\u0430 \u0432 \u043E\u043A\u043D\u0435 \u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F
pref.dlg.checkbox.Markers = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B
pref.dlg.checkbox.Markers.ttip = <html>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F, \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B.<br>\u0412 \u043F\u0440\u043E\u0442\u0438\u0432\u043D\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0435 \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0432\u0441\u0435\u0433\u0434\u0430.</html>
pref.dlg.checkbox.AlwaysOpenLeftmost = \u0412\u0441\u0435\u0433\u0434\u0430 \u0432\u044B\u0431\u0438\u0440\u0430\u0442\u044C \u043F\u0435\u0440\u0432\u0443\u044E \u0432\u043A\u043B\u0430\u0434\u043A\u0443 \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u043E\u043A\u043D\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u0435 \u043E\u043A\u043D\u043E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0441 \u043F\u0435\u0440\u0432\u043E\u0439 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0439 \u0432\u043A\u043B\u0430\u0434\u043A\u043E\u0439.<br>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u0430\u044F \u0432\u043A\u043B\u0430\u0434\u043A\u0430.</html>
pref.dlg.lbl.User-definedthrust = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 \u0442\u044F\u0433\u0438:
@ -716,7 +718,7 @@ compaddbuttons.Launchlug = \u041D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044
compaddbuttons.RailButton = \u0417\u0430\u0446\u0435\u043F\n\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0449\u0435\u0439
compaddbuttons.InnerComponent = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0435 \u0434\u0435\u0442\u0430\u043B\u0438
compaddbuttons.Innertube = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F\n\u0442\u0440\u0443\u0431\u0430
compaddbuttons.Coupler = \u041C\u0443\u0444\u0442\u0430
compaddbuttons.Coupler = \u0422\u0440\u0443\u0431\u0447\u0430\u0442\u0430\u044F\n\u043C\u0443\u0444\u0442\u0430
compaddbuttons.Centeringring = \u0426\u0435\u043D\u0442\u0440\u0438\u0440\u0443\u044E\u0449\u0435\u0435\n\u043A\u043E\u043B\u044C\u0446\u043E
compaddbuttons.Bulkhead = \u041F\u0435\u0440\u0435\u0431\u043E\u0440\u043A\u0430
compaddbuttons.Engineblock = \u0423\u043F\u043E\u0440\n\u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F
@ -898,6 +900,7 @@ RocketCompCfg.tab.Figstyleopt = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440
RocketCompCfg.tab.Comment = \u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435
RocketCompCfg.tab.Comment.ttip = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443
RocketCompCfg.tab.Appearance = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434
RocketCompCfg.tab.Appearance.ttip = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430
RocketCompCfg.lbl.Mass = \u041C\u0430\u0441\u0441\u0430:
RocketCompCfg.lbl.Componentmass = \u041C\u0430\u0441\u0441\u0430 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430:
RocketCompCfg.lbl.overriddento = (\u043F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043E \u043D\u0430
@ -2075,8 +2078,10 @@ CustomFinImport.error.badimage = \u041D\u0435\u0432\u043E\u0437\u043C\u043E\u043
CustomFinImport.description = \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E-\u0431\u0435\u043B\u043E\u0435 (\u0433\u0434\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 - \u0446\u0432\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430), \u0442\u0430\u043A \u0447\u0442\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0440\u0438\u0441\u0443\u043D\u043A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0438 \u0431\u0435\u043B\u044B\u0439 \u0438\u043B\u0438 \u0441\u0432\u0435\u0442\u043B\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0444\u043E\u043D\u0430. \u041E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441\u043D\u0438\u0437\u0443 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F.
PresetModel.lbl.custompreset = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439
PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439
PresetModel.combo.ttip = <html>\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u044B\u0445 (\u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0445 \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432)<br>\u0438\u043B\u0438 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0439", \u0435\u0441\u043B\u0438 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0430 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F.</html>
PresetModel.lbl.custompreset = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u0438\u0439
PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u0434\u0435\u0442\u0430\u043B\u0435\u0439
PresetModel.lbl.partsLib.ttip = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0440\u0430\u043A\u0435\u0442\u044B \u0438\u0437 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u0435\u0442\u0430\u043B\u0435\u0439.
DecalModel.lbl.select = <\u043D\u0435\u0442>
DecalModel.lbl.choose = \u0418\u0437 \u0444\u0430\u0439\u043B\u0430...
@ -2098,7 +2103,7 @@ ComponentPresetChooserDialog.menu.sortDesc = \u041F\u043E \u0443\u0431\u044B\u04
ComponentPresetChooserDialog.menu.units = \u0415\u0434\u0438\u043D\u0438\u0446\u044B \u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F
ComponentPresetChooserDialog.checkbox.showAllCompatible = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0441\u0435 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u044B\u0435
ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0431\u0430\u0437\u0443 \u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445
ComponentPresetChooserDialog.lbl.favorites = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0432 \u0432\u044B\u043F\u0430\u0434\u0430\u044E\u0449\u0435\u0435 \u043C\u0435\u043D\u044E
ComponentPresetChooserDialog.lbl.favorites = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A, \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0432 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0435\u0435\u0441\u044F \u043C\u0435\u043D\u044E \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430.
table.column.Favorite = \u0418\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0435
table.column.Legacy = \u0423\u0441\u0442\u0430\u0440\u0435\u043B\u043E
table.column.Manufacturer = \u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C
@ -2115,7 +2120,7 @@ table.column.AftShoulderDiameter = \u0414\u0438\u0430\u043C\u0435\u0442\u0440 \u
table.column.ForeShoulderLength = \u0414\u043B\u0438\u043D\u0430 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.ForeShoulderDiameter = \u0414\u0438\u0430\u043C\u0435\u0442\u0440 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.ForeOuterDiameter = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0434\u0438\u0430\u043C\u0435\u0442\u0440 \u043F\u0435\u0440\u0435\u0434\u043D\u0435\u0439 \u043C\u0443\u0444\u0442\u044B
table.column.StandoffHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0437\u0430\u0437\u043E\u0440\u0430
table.column.BaseHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0437\u0430\u0437\u043E\u0440\u0430
table.column.FlangeHeight = \u0412\u044B\u0441\u043E\u0442\u0430 \u0444\u043B\u0430\u043D\u0446\u0430
table.column.Shape = \u0424\u043E\u0440\u043C\u0430
table.column.Material = \u041C\u0430\u0442\u0435\u0440\u0438\u0430\u043B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 182 B

View File

@ -190,8 +190,15 @@ class DocumentConfig {
setters.put("RailButton:angleoffset", new AnglePositionSetter() );
setters.put("RailButton:height", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setTotalHeight", double.class)));
setters.put("RailButton:baseheight", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setBaseHeight", double.class)));
setters.put("RailButton:flangeheight", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setFlangeHeight", double.class)));
setters.put("RailButton:outerdiameter", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setOuterDiameter", double.class)));
setters.put("RailButton:innerdiameter", new DoubleSetter(
Reflection.findMethod( RailButton.class, "setInnerDiameter", double.class)));
// Transition
setters.put("Transition:shape", new EnumSetter<Transition.Shape>(

View File

@ -26,8 +26,10 @@ public class RailButtonSaver extends ExternalComponentSaver {
RailButton rb = (RailButton) c;
emitDouble( elements, "outerdiameter", rb.getOuterDiameter());
emitDouble( elements, "innerdiameter", rb.getInnerDiameter());
emitDouble( elements, "height", rb.getTotalHeight());
emitDouble( elements, "baseheight", rb.getBaseHeight());
emitDouble( elements, "flangeheight", rb.getFlangeHeight());
}

View File

@ -129,12 +129,16 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
ComponentPreset.MANUFACTURER,
ComponentPreset.PARTNO,
ComponentPreset.DESCRIPTION,
// these are optional / secondary parameters. Probably not necessary to include.
//ComponentPreset.BASE_HEIGHT,
//ComponentPreset.FLANGE_HEIGHT,
//ComponentPreset.INNER_DIAMETER,
ComponentPreset.BASE_HEIGHT,
ComponentPreset.FLANGE_HEIGHT,
//ComponentPreset.SCREW_HEIGHT, // Add this later when we implement screws in the rail button
ComponentPreset.HEIGHT,
ComponentPreset.INNER_DIAMETER,
ComponentPreset.OUTER_DIAMETER,
ComponentPreset.HEIGHT }),
ComponentPreset.MASS,
ComponentPreset.SCREW_MASS,
ComponentPreset.NUT_MASS,
ComponentPreset.CD }),
STREAMER(new TypedKey<?>[] {
ComponentPreset.LEGACY,
@ -160,7 +164,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
ComponentPreset.LINE_COUNT,
ComponentPreset.LINE_LENGTH,
ComponentPreset.LINE_MATERIAL,
ComponentPreset.PARACHUTE_CD,
ComponentPreset.CD,
ComponentPreset.PACKED_DIAMETER,
ComponentPreset.PACKED_LENGTH });
@ -206,6 +210,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
public final static TypedKey<Double> AFT_SHOULDER_LENGTH = new TypedKey<Double>("AftShoulderLength", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> AFT_SHOULDER_DIAMETER = new TypedKey<Double>("AftShoulderDiameter", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> AFT_OUTER_DIAMETER = new TypedKey<Double>("AftOuterDiameter", Double.class, UnitGroup.UNITS_LENGTH);
public static final TypedKey<Double> CD = new TypedKey<Double>("DragCoefficient", Double.class, UnitGroup.UNITS_COEFFICIENT);
public final static TypedKey<Shape> SHAPE = new TypedKey<Shape>("Shape", Shape.class);
public final static TypedKey<Material> MATERIAL = new TypedKey<Material>("Material", Material.class);
public final static TypedKey<Finish> FINISH = new TypedKey<Finish>("Finish", Finish.class);
@ -214,8 +219,13 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
public final static TypedKey<Double> MASS = new TypedKey<Double>("Mass", Double.class, UnitGroup.UNITS_MASS);
public final static TypedKey<Double> DIAMETER = new TypedKey<Double>("Diameter", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<byte[]> IMAGE = new TypedKey<byte[]>("Image", byte[].class);
public final static TypedKey<Double> STANDOFF_HEIGHT = new TypedKey<Double>("StandoffHeight", Double.class, UnitGroup.UNITS_LENGTH);
// RAIL BUTTON SPECIFIC
public final static TypedKey<Double> BASE_HEIGHT = new TypedKey<Double>("BaseHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> FLANGE_HEIGHT = new TypedKey<Double>("FlangeHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SCREW_HEIGHT = new TypedKey<Double>("ScrewHeight", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SCREW_MASS = new TypedKey<Double>("ScrewMass", Double.class, UnitGroup.UNITS_MASS);
public final static TypedKey<Double> NUT_MASS = new TypedKey<Double>("NutMass", Double.class, UnitGroup.UNITS_MASS);
// PARACHUTE SPECIFIC
// Parachute Manufacturer declaration see: MANUFACTURER
@ -225,7 +235,7 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
// Parachute diameter declaration see: DIAMETER
public final static TypedKey<Double> SPILL_DIA = new TypedKey<Double>("SpillDia", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Double> SURFACE_AREA = new TypedKey<Double>("SurfaceArea", Double.class, UnitGroup.UNITS_LENGTH);
public static final TypedKey<Double> PARACHUTE_CD = new TypedKey<Double>("DragCoefficient", Double.class, UnitGroup.UNITS_COEFFICIENT);
// Parachute canopy material declaration see: MATERIAL
public final static TypedKey<Integer> SIDES = new TypedKey<Integer>("Sides", Integer.class);
public final static TypedKey<Integer> LINE_COUNT = new TypedKey<Integer>("LineCount", Integer.class);
@ -251,8 +261,9 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
AFT_SHOULDER_LENGTH,
FORE_SHOULDER_DIAMETER,
FORE_SHOULDER_LENGTH,
STANDOFF_HEIGHT,
BASE_HEIGHT,
FLANGE_HEIGHT,
SCREW_HEIGHT,
SHAPE,
THICKNESS,
FILLED,
@ -262,6 +273,8 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
LINE_LENGTH,
LINE_MATERIAL,
MASS,
SCREW_MASS,
NUT_MASS,
FINISH,
MATERIAL
));
@ -411,6 +424,9 @@ public class ComponentPreset implements Comparable<ComponentPreset>, Serializabl
os.writeDouble(d);
} else if (key.getType() == String.class) {
String s = (String) value;
if (s == null) {
s = "";
}
os.writeBytes(s);
} else if (key.getType() == Manufacturer.class) {
String s = ((Manufacturer) value).getSimpleName();

View File

@ -113,13 +113,13 @@ public abstract class ComponentPresetFactory {
}
private static void makeRailButton(InvalidComponentPresetException exceptions, ComponentPreset preset) throws InvalidComponentPresetException {
private static void makeRailButton(InvalidComponentPresetException exceptions, ComponentPreset preset) {
checkRequiredFields(exceptions, preset, HEIGHT);
checkRequiredFields(exceptions, preset, OUTER_DIAMETER);
checkRequiredFields(exceptions, preset, INNER_DIAMETER);
checkRequiredFields(exceptions, preset, FLANGE_HEIGHT);
checkRequiredFields(exceptions, preset, STANDOFF_HEIGHT);
checkRequiredFields(exceptions, preset, BASE_HEIGHT);
if (preset.has(MASS)) {
double mass = preset.get(MASS);
@ -271,7 +271,6 @@ public abstract class ComponentPresetFactory {
if (hasOd) {
outerRadius = preset.get(OUTER_DIAMETER) / 2.0;
thickness = 0;
if (hasId) {
innerRadius = preset.get(INNER_DIAMETER) / 2.0;
thickness = outerRadius - innerRadius;

View File

@ -13,7 +13,7 @@ public class RailButtonLoader extends BaseComponentLoader {
fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.OUTER_DIAMETER));
fileColumns.add(new DoubleUnitColumnParser("Height","Units",ComponentPreset.HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Flange Height", "Units", ComponentPreset.FLANGE_HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Standoff Height", "Units", ComponentPreset.STANDOFF_HEIGHT));
fileColumns.add(new DoubleUnitColumnParser("Standoff Height", "Units", ComponentPreset.BASE_HEIGHT));
}

View File

@ -34,9 +34,7 @@ public class OpenRocketComponentLoader implements Loader<ComponentPreset> {
presets = (new OpenRocketComponentSaver().unmarshalFromOpenRocketComponent( new InputStreamReader (stream))).asComponentPresets();
log.debug("ComponentPreset file " + filename + " contained " + presets.size() + " presets");
return presets;
} catch (JAXBException e) {
throw new BugException("Unable to parse file: "+ filename, e);
} catch (InvalidComponentPresetException e) {
} catch (JAXBException | InvalidComponentPresetException e) {
throw new BugException("Unable to parse file: "+ filename, e);
}

View File

@ -146,8 +146,8 @@ public class ParachuteDTO extends BaseComponentDTO {
if ( preset.has(ComponentPreset.PACKED_LENGTH)) {
setPackedLength(preset.get(ComponentPreset.PACKED_LENGTH));
}
if ( preset.has(ComponentPreset.PARACHUTE_CD)) {
setDragCoefficient(preset.get(ComponentPreset.PARACHUTE_CD));
if ( preset.has(ComponentPreset.CD)) {
setDragCoefficient(preset.get(ComponentPreset.CD));
}
if ( preset.has(ComponentPreset.LINE_MATERIAL)) {
setLineMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.LINE_MATERIAL)));
@ -174,7 +174,7 @@ public class ParachuteDTO extends BaseComponentDTO {
props.put(ComponentPreset.PACKED_LENGTH, this.getPackedLength());
}
if ( this.dragCoefficient != null ) {
props.put(ComponentPreset.PARACHUTE_CD, this.getDragCoefficient());
props.put(ComponentPreset.CD, this.getDragCoefficient());
}
props.put(ComponentPreset.LINE_COUNT, this.getLineCount());
if ( this.lineLength != null ) {

View File

@ -19,16 +19,22 @@ import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class RailButtonDTO extends BaseComponentDTO {
@XmlElement(name = "InsideDiameter")
private AnnotatedLengthDTO insideDiameter;
@XmlElement(name = "OutsideDiameter")
private AnnotatedLengthDTO outsideDiameter;
@XmlElement(name = "InnerDiameter")
private AnnotatedLengthDTO innerDiameter;
@XmlElement(name = "OuterDiameter")
private AnnotatedLengthDTO outerDiameter;
@XmlElement(name = "Height")
private AnnotatedLengthDTO height;
@XmlElement(name = "StandoffHeight")
private AnnotatedLengthDTO standoffHeight;
@XmlElement(name = "BaseHeight")
private AnnotatedLengthDTO baseHeight;
@XmlElement(name = "FlangeHeight")
private AnnotatedLengthDTO flangeHeight;
@XmlElement(name = "ScrewHeight")
private AnnotatedLengthDTO screwHeight;
@XmlElement(name = "ScrewMass")
private AnnotatedMassDTO screwMass;
@XmlElement(name = "NutMass")
private AnnotatedMassDTO nutMass;
/**
* Default constructor.
@ -48,32 +54,35 @@ public class RailButtonDTO extends BaseComponentDTO {
setInsideDiameter(preset.get(ComponentPreset.INNER_DIAMETER));
setOutsideDiameter(preset.get(ComponentPreset.OUTER_DIAMETER));
setHeight(preset.get(ComponentPreset.HEIGHT));
setStandoffHeight(preset.get(ComponentPreset.STANDOFF_HEIGHT));
setBaseHeight(preset.get(ComponentPreset.BASE_HEIGHT));
setFlangeHeight(preset.get(ComponentPreset.FLANGE_HEIGHT));
setScrewHeight(preset.get(ComponentPreset.SCREW_HEIGHT));
setScrewMass(preset.get(ComponentPreset.SCREW_MASS));
setNutMass(preset.get(ComponentPreset.NUT_MASS));
}
public double getInsideDiameter() {
return insideDiameter.getValue();
public double getInnerDiameter() {
return innerDiameter.getValue();
}
public void setInsideDiameter( final AnnotatedLengthDTO theLength ) {
insideDiameter = theLength;
public void setInnerDiameter(final AnnotatedLengthDTO theLength ) {
innerDiameter = theLength;
}
public void setInsideDiameter(final double theId) {
insideDiameter = new AnnotatedLengthDTO(theId);
innerDiameter = new AnnotatedLengthDTO(theId);
}
public double getOutsideDiameter() {
return outsideDiameter.getValue();
public double getOuterDiameter() {
return outerDiameter.getValue();
}
public void setOutsideDiameter(final AnnotatedLengthDTO theOd) {
outsideDiameter = theOd;
public void setOuterDiameter(final AnnotatedLengthDTO theOd) {
outerDiameter = theOd;
}
public void setOutsideDiameter(final double theOd) {
outsideDiameter = new AnnotatedLengthDTO(theOd);
outerDiameter = new AnnotatedLengthDTO(theOd);
}
public double getHeight() {
@ -88,16 +97,12 @@ public class RailButtonDTO extends BaseComponentDTO {
height = new AnnotatedLengthDTO(theHeight);
}
public double getStandoffHeight() {
return standoffHeight.getValue();
public double getBaseHeight() {
return baseHeight.getValue();
}
public void setStandoffHeight(final AnnotatedLengthDTO theStandoffHeight) {
standoffHeight = theStandoffHeight;
}
public void setStandoffHeight(final double theStandoffHeight) {
standoffHeight = new AnnotatedLengthDTO(theStandoffHeight);
public void setBaseHeight(final double theBaseHeight) {
baseHeight = new AnnotatedLengthDTO(theBaseHeight);
}
public double getFlangeHeight() {
@ -112,6 +117,30 @@ public class RailButtonDTO extends BaseComponentDTO {
flangeHeight = new AnnotatedLengthDTO(theFlangeHeight);
}
public double getScrewHeight() {
return screwHeight.getValue();
}
public void setScrewHeight(final double screwHeight) {
this.screwHeight = new AnnotatedLengthDTO(screwHeight);
}
public double getScrewMass() {
return screwMass.getValue();
}
public void setScrewMass(double screwMass) {
this.screwMass = new AnnotatedMassDTO(screwMass);
}
public double getNutMass() {
return nutMass.getValue();
}
public void setNutMass(double nutMass) {
this.nutMass = new AnnotatedMassDTO(nutMass);
}
@Override
public ComponentPreset asComponentPreset(Boolean legacy, java.util.List<MaterialDTO> materials) throws InvalidComponentPresetException {
return asComponentPreset(legacy, ComponentPreset.Type.RAIL_BUTTON, materials);
@ -121,11 +150,14 @@ public class RailButtonDTO extends BaseComponentDTO {
TypedPropertyMap props = new TypedPropertyMap();
props.put(ComponentPreset.LEGACY, legacy);
addProps(props, materials);
props.put(ComponentPreset.INNER_DIAMETER, this.getInsideDiameter());
props.put(ComponentPreset.OUTER_DIAMETER, this.getOutsideDiameter());
props.put(ComponentPreset.INNER_DIAMETER, this.getInnerDiameter());
props.put(ComponentPreset.OUTER_DIAMETER, this.getOuterDiameter());
props.put(ComponentPreset.HEIGHT, this.getHeight());
props.put(ComponentPreset.STANDOFF_HEIGHT, this.getStandoffHeight());
props.put(ComponentPreset.BASE_HEIGHT, this.getBaseHeight());
props.put(ComponentPreset.FLANGE_HEIGHT, this.getFlangeHeight());
props.put(ComponentPreset.SCREW_HEIGHT, this.getScrewHeight());
props.put(ComponentPreset.SCREW_MASS, this.getScrewMass());
props.put(ComponentPreset.NUT_MASS, this.getNutMass());
props.put(ComponentPreset.TYPE, type);
return ComponentPresetFactory.create(props);

View File

@ -144,7 +144,9 @@ public abstract class ExternalComponent extends RocketComponent {
protected void loadFromPreset(ComponentPreset preset) {
super.loadFromPreset(preset);
// Surface finish is left unchanged
if (preset.has(ComponentPreset.FINISH)) {
setFinish(preset.get(ComponentPreset.FINISH));
}
if (preset.has(ComponentPreset.MATERIAL)) {
Material mat = preset.get(ComponentPreset.MATERIAL);

View File

@ -2,10 +2,7 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPreset.Type;
@ -14,7 +11,6 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener;
public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, LineInstanceable, InsideColorComponent {

View File

@ -178,9 +178,9 @@ public class Parachute extends RecoveryDevice {
this.diameter = DEFAULT_DIAMETER;
}
// // Set preset parachute drag coefficient
if ((preset.has(ComponentPreset.PARACHUTE_CD)) && preset.get(ComponentPreset.PARACHUTE_CD) > 0){
if ((preset.has(ComponentPreset.CD)) && preset.get(ComponentPreset.CD) > 0){
cdAutomatic = false;
cd = preset.get(ComponentPreset.PARACHUTE_CD);
cd = preset.get(ComponentPreset.CD);
} else {
cdAutomatic = true;
cd = Parachute.DEFAULT_CD;

View File

@ -40,19 +40,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
* ^ [[[[[[]]]]]] flangeHeight
* total >||||||<= inner dia ^
* height |||||| v
* v [[[[[[]]]]]] standoff == baseHeight
* v [[[[[[]]]]]] baseHeight / standoff
* ================== ^
* (body)
*
*/
// Note: the reference point for Rail Button Components is in the center bottom of the button.
protected double outerDiameter_m;
protected double totalHeight_m;
protected double innerDiameter_m;
protected double totalHeight_m;
protected double flangeHeight_m;
protected double standoff_m;
protected final static double MINIMUM_STANDOFF= 0.001;
protected double baseHeight_m;
protected double screwHeight_m; // This has no effect at the moment; is for future use.
private double radialDistance_m=0;
protected static final AngleMethod angleMethod = AngleMethod.RELATIVE;
@ -66,7 +66,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
this.totalHeight_m = 0.0097;
this.innerDiameter_m = 0.008;
this.flangeHeight_m = 0.002;
this.setStandoff( 0.002);
this.setBaseHeight(0.002);
this.setInstanceSeparation( this.outerDiameter_m * 6);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
@ -75,19 +75,19 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public RailButton( final double od, final double ht ) {
this();
this.setOuterDiameter( od);
this.setTotalHeight( ht);
this.setOuterDiameter(od);
this.setTotalHeight(ht);
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
super.displayOrder_back = 11; // Order for displaying the component in the 2D back view
}
public RailButton( final double od, final double id, final double ht, final double flangeThickness, final double _standoff ) {
public RailButton( final double od, final double id, final double ht, final double _flangeHeight, final double _baseHeight ) {
super(AxialMethod.MIDDLE);
this.outerDiameter_m = od;
this.totalHeight_m = ht;
this.innerDiameter_m = id;
this.flangeHeight_m = flangeThickness;
this.setStandoff( _standoff);
this.flangeHeight_m = _flangeHeight;
this.setBaseHeight(_baseHeight);
this.setInstanceSeparation( od*2);
this.setMaterial(Databases.findMaterial(Material.Type.BULK, "Delrin"));
super.displayOrder_side = 14; // Order for displaying the component in the 2D side view
@ -121,13 +121,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
return rb1010;
}
public double getStandoff(){
return this.standoff_m;
}
public double getBaseHeight(){
return this.getStandoff();
return this.baseHeight_m;
}
public double getOuterDiameter() {
@ -139,7 +135,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
public double getInnerHeight() {
return (this.totalHeight_m - this.flangeHeight_m - this.standoff_m);
return (this.totalHeight_m - this.flangeHeight_m - this.baseHeight_m);
}
public double getTotalHeight() {
@ -149,16 +145,48 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public double getFlangeHeight() {
return this.flangeHeight_m;
}
public double getScrewHeight() {
return this.screwHeight_m;
}
public void setStandoff(double newStandoff){
public void setBaseHeight(double newBaseHeight){
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setStandoff(newStandoff);
((RailButton) listener).setBaseHeight(newBaseHeight);
}
}
this.standoff_m = Math.max( newStandoff, RailButton.MINIMUM_STANDOFF );
this.baseHeight_m = Math.max(newBaseHeight, 0);
this.baseHeight_m = Math.min(this.baseHeight_m, this.totalHeight_m - this.flangeHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setFlangeHeight(double newFlangeHeight){
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setFlangeHeight(newFlangeHeight);
}
}
this.flangeHeight_m = Math.max(newFlangeHeight, 0);
this.flangeHeight_m = Math.min(this.flangeHeight_m, this.totalHeight_m - this.baseHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setScrewHeight(double height) {
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setScrewHeight(height);
}
}
this.screwHeight_m = Math.max(height, 0);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setInnerDiameter(double newID ){
@ -168,7 +196,8 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
this.innerDiameter_m = newID;
this.innerDiameter_m = Math.min(newID, this.outerDiameter_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@ -181,7 +210,9 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
this.outerDiameter_m = newOD;
setInnerDiameter(this.innerDiameter_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@ -192,22 +223,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
}
}
this.totalHeight_m = newHeight;
this.totalHeight_m = Math.max(newHeight, this.flangeHeight_m + this.baseHeight_m);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public void setThickness(double newThickness ) {
for (RocketComponent listener : configListeners) {
if (listener instanceof RailButton) {
((RailButton) listener).setThickness(newThickness);
}
}
this.flangeHeight_m = newThickness;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public boolean isAerodynamic(){
// TODO: implement aerodynamics
@ -252,15 +273,17 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
super.setAxialMethod(position);
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
@Override
public BoundingBox getInstanceBoundingBox(){
BoundingBox instanceBounds = new BoundingBox();
instanceBounds.update(new Coordinate(0, this.getTotalHeight(), 0));
instanceBounds.update(new Coordinate(0, this.totalHeight_m, 0));
instanceBounds.update(new Coordinate(0, -this.totalHeight_m, 0));
final double r = this.getOuterDiameter();
instanceBounds.update(new Coordinate(r,r,0));
instanceBounds.update(new Coordinate(-r,-r,0));
final double r = this.getOuterDiameter() / 2;
instanceBounds.update(new Coordinate(r, 0, r));
instanceBounds.update(new Coordinate(-r, 0, -r));
return instanceBounds;
}
@ -306,7 +329,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public double getComponentVolume() {
final double volOuter = Math.PI*Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
final double volInner = Math.PI*Math.pow( innerDiameter_m/2, 2)*getInnerHeight();
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)*standoff_m;
final double volStandoff = Math.PI*Math.pow( outerDiameter_m/2, 2)* baseHeight_m;
return (volOuter+
volInner+
volStandoff);
@ -370,12 +393,12 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
@Override
public Coordinate getComponentCG() {
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
final double volumeFlange = Math.pow( outerDiameter_m/2, 2)*flangeHeight_m;
final double volumeInner = Math.pow( innerDiameter_m/2, 2)*(getInnerHeight());
final double volumeStandoff = Math.pow( outerDiameter_m/2, 2)*this.standoff_m;
final double totalVolume = volumeFlange + volumeInner + volumeStandoff;
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.standoff_m + this.getInnerHeight()/2) + volumeStandoff*(this.standoff_m/2))/totalVolume;
// Math.PI and density are assumed constant through calculation, and thus may be factored out.
final double volumeBase = Math.pow(outerDiameter_m / 2, 2) * this.baseHeight_m;
final double volumeFlange = Math.pow(outerDiameter_m / 2, 2)* this.flangeHeight_m;
final double volumeInner = Math.pow(innerDiameter_m / 2, 2)* getInnerHeight();
final double totalVolume = volumeFlange + volumeInner + volumeBase;
final double heightCM = (volumeFlange*( this.totalHeight_m-getFlangeHeight()/2) + volumeInner*( this.baseHeight_m + this.getInnerHeight()/2) + volumeBase*(this.baseHeight_m /2))/totalVolume;
if( heightCM > this.totalHeight_m ){
throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM);
@ -417,4 +440,48 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
return false;
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
super.loadFromPreset(preset);
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
this.outerDiameter_m = preset.get(ComponentPreset.OUTER_DIAMETER);
}
if (preset.has(ComponentPreset.INNER_DIAMETER)) {
this.innerDiameter_m = preset.get(ComponentPreset.INNER_DIAMETER);
}
if (preset.has(ComponentPreset.HEIGHT)) {
this.totalHeight_m = preset.get(ComponentPreset.HEIGHT);
}
if (preset.has(ComponentPreset.FLANGE_HEIGHT)) {
this.flangeHeight_m = preset.get(ComponentPreset.FLANGE_HEIGHT);
}
if (preset.has(ComponentPreset.BASE_HEIGHT)) {
this.baseHeight_m = preset.get(ComponentPreset.BASE_HEIGHT);
}
if (preset.has(ComponentPreset.CD) && preset.get(ComponentPreset.CD) > 0) {
setCDOverridden(true);
setOverrideCD(preset.get(ComponentPreset.CD));
}
double totalMass = 0;
boolean massOverridden = false;
if (preset.has(ComponentPreset.MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.MASS);
}
if (preset.has(ComponentPreset.SCREW_MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.SCREW_MASS);
}
if (preset.has(ComponentPreset.NUT_MASS)) {
massOverridden = true;
totalMass += preset.get(ComponentPreset.NUT_MASS);
}
if (massOverridden) {
setMassOverridden(true);
setOverrideMass(totalMass);
}
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
}

View File

@ -63,6 +63,9 @@ public abstract class Preferences implements ChangeSource {
public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch";
public static final String MOTOR_HIDE_SIMILAR = "MotorHideSimilar";
public static final String MOTOR_HIDE_UNAVAILABLE = "MotorHideUnavailable";
public static final String MATCH_FORE_DIAMETER = "MatchForeDiameter";
public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter";
// Node names
public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors";
@ -490,6 +493,44 @@ public abstract class Preferences implements ChangeSource {
return this.getBoolean(SHOW_MARKERS, false);
}
/**
* Set whether the component preset chooser dialog should filter by fore diameter when the window is opened.
* @param enabled true if the fore diameter filter should be enabled,
* false if it should be disabled.
*/
public final void setMatchForeDiameter(boolean enabled) {
this.putBoolean(MATCH_FORE_DIAMETER, enabled);
}
/**
* Answer if the component preset chooser dialog should filter by fore diameter when the window is opened.
*
* @return true if the fore diameter filter should be enabled,
* false if it should be disabled.
*/
public final boolean isMatchForeDiameter() {
return this.getBoolean(MATCH_FORE_DIAMETER, true);
}
/**
* Set whether the component preset chooser dialog should filter by aft diameter when the window is opened.
* @param enabled true if the aft diameter filter should be enabled,
* false if it should be disabled.
*/
public final void setMatchAftDiameter(boolean enabled) {
this.putBoolean(MATCH_AFT_DIAMETER, enabled);
}
/**
* Answer if the component preset chooser dialog should filter by aft diameter when the window is opened.
*
* @return true if the aft diameter filter should be enabled,
* false if it should be disabled.
*/
public final boolean isMatchAftDiameter() {
return this.getBoolean(MATCH_AFT_DIAMETER, true);
}
/**
* Return the OpenRocket unique ID.
*

View File

@ -19,6 +19,8 @@ import org.junit.Test;
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
*/
public class DisableStageTest extends BaseTestCase {
private final double delta = 0.08; // 8 % error margin (simulations are not exact)
/**
* Tests that the simulation results are correct when a single stage is deactivated and re-activated.
*/
@ -54,7 +56,6 @@ public class DisableStageTest extends BaseTestCase {
simDisabled.getActiveConfiguration().setAllStages(); // Re-enable all stages.
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simOriginal, simDisabled, simulationListener, delta);
}
@ -84,7 +85,6 @@ public class DisableStageTest extends BaseTestCase {
SimulationListener simulationListener = new AbstractSimulationListener();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simRemoved, simDisabled, simulationListener, delta);
//// Test re-enableing the stage.
@ -175,7 +175,6 @@ public class DisableStageTest extends BaseTestCase {
SimulationListener simulationListener = new AbstractSimulationListener();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simRemoved, simDisabled, simulationListener, delta);
//// Test re-enableing the stage.
@ -243,7 +242,6 @@ public class DisableStageTest extends BaseTestCase {
simDisabled.getActiveConfiguration().setAllStages();
double delta = 0.05; // 5 % error margin (simulations are not exact)
compareSims(simOriginal, simDisabled, simulationListener, delta);
}

View File

@ -1,6 +1,6 @@
name: openrocket
adopt-info: openrocket
grade: devel
grade: stable
summary: A free, fully featured model rocket simulator.
description: |
OpenRocket is a free, fully featured model rocket simulator that allows you
@ -77,6 +77,7 @@ parts:
prime:
- -usr/lib/jvm/java-*/lib/security/cacerts
- -usr/lib/jvm/java-*/jre/lib/security/cacerts
- -usr/lib/jvm/java-*/lib/security/blacklisted.certs
launcher:
plugin: dump

View File

@ -19,6 +19,7 @@
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.inject.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-1.1.3.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.json-api-1.1.3.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/lib/javax.activation-api.2.3.1.jar"/>
<classpathentry kind="lib" path="/OpenRocket Core/resources"/>
<classpathentry kind="lib" path="resources"/>
<classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar" sourcepath="reference/miglayout-4.0-sources.jar"/>

@ -1 +1 @@
Subproject commit 860757167c4835a7bb960a4cbb52b06f3309791c
Subproject commit 4c3604313f0cc8f52274c8fa07e4970e6bfaa273

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OpenRocketComponent>
<Version>0.1</Version>
<Materials>
<Material UnitsOfMeasure="kg/m">
<Name>Delrin</Name>
<Density>1420</Density>
<Type>BULK</Type>
</Material>
<Material UnitsOfMeasure="kg/m">
<Name>Nylon</Name>
<Density>1150</Density>
<Type>BULK</Type>
</Material>
</Materials>
<Components>
<RailButton>
<Manufacturer>Binder Design-Rail Button Supply House</Manufacturer>
<PartNumber>Std 1010 RB</PartNumber>
<Description>Standard 1010 Rail Button, Countersunk 8-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.4375</OuterDiameter>
<InnerDiameter Unit="in">0.2285</InnerDiameter>
<Height Unit="in">0.2975</Height>
<BaseHeight Unit="in">0.0730</BaseHeight>
<FlangeHeight Unit="in">0.0730</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.445</Mass>
<ScrewMass Unit="g">1.395</ScrewMass>
<NutMass Unit="g">1.025</NutMass>
</RailButton>
<RailButton>
<Manufacturer>Binder Design-Rail Button Supply House</Manufacturer>
<PartNumber>Std 1515 RB</PartNumber>
<Description>Standard 1515 Rail Button, Countersunk 10-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.6200</OuterDiameter>
<InnerDiameter Unit="in">0.2995</InnerDiameter>
<Height Unit="in">.4495</Height>
<BaseHeight Unit="in">0.125</BaseHeight>
<FlangeHeight Unit="in">0.125</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">1.465</Mass>
<ScrewMass Unit="g">3.365</ScrewMass>
<NutMass Unit="g">2.675</NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB-Micro</PartNumber>
<Description>2 Piece Micro Rail Button with 2-56 Screw (10mm Rail)</Description>
<Material Type="BULK">Nylon</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.1650</OuterDiameter>
<InnerDiameter Unit="in">.1195</InnerDiameter>
<Height Unit="in">0.1595</Height>
<BaseHeight Unit="in">0.041</BaseHeight>
<FlangeHeight Unit="in">0.0000</FlangeHeight>
<ScrewHeight Unit="in">0.0465</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.01</Mass>
<ScrewMass Unit="g">0.04</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>1PMB</PartNumber>
<Description>1 Piece Mini Rail Button with Countersunk 6-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.249</OuterDiameter>
<InnerDiameter Unit="in">.193</InnerDiameter>
<Height Unit="in">0.205</Height>
<BaseHeight Unit="in">0.0380</BaseHeight>
<FlangeHeight Unit="in">0.0380</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.090</Mass>
<ScrewMass Unit="g">0.415</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB-10-D</PartNumber>
<Description>3 Piece 1010 Rail Button with 8-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.278</OuterDiameter>
<InnerDiameter Unit="in">.154</InnerDiameter>
<Height Unit="in">0.270</Height>
<BaseHeight Unit="in">0.060</BaseHeight>
<FlangeHeight Unit="in">0.060</FlangeHeight>
<ScrewHeight Unit="in">0.115</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.305</Mass>
<ScrewMass Unit="g">1.715</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>1P1010DLX</PartNumber>
<Description>1 Piece 1010 Rail Button with Countersunk 8-32 Screw</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">.3725</OuterDiameter>
<InnerDiameter Unit="in">.2480</InnerDiameter>
<Height Unit="in">0.305</Height>
<BaseHeight Unit="in">0.078</BaseHeight>
<FlangeHeight Unit="in">0.078</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">0.320</Mass>
<ScrewMass Unit="g">1.235</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
<RailButton>
<Manufacturer>Rail-Buttons.com</Manufacturer>
<PartNumber>RB1515S</PartNumber>
<Description>1 Piece 1515 Rail Button, Countersunk 10-32 Screw, and T-Nut</Description>
<Material Type="BULK">Delrin</Material>
<Finish>Polished</Finish>
<OuterDiameter Unit="in">0.49</OuterDiameter>
<InnerDiameter Unit="in">0.29</InnerDiameter>
<Height Unit="in">0.56</Height>
<BaseHeight Unit="in">0.1875</BaseHeight>
<FlangeHeight Unit="in">0.1875</FlangeHeight>
<ScrewHeight Unit="in">0.0000</ScrewHeight>
<DragCoefficient></DragCoefficient>
<Mass Unit="g">1.355</Mass>
<ScrewMass Unit="g">2.720</ScrewMass>
<NutMass Unit="g"></NutMass>
</RailButton>
</Components>
</OpenRocketComponent>

View File

@ -29,13 +29,6 @@ public class RailButtonConfig extends RocketComponentConfig {
public RailButtonConfig( OpenRocketDocument document, RocketComponent component, JDialog parent) {
super(document, component, parent);
// For DEBUG purposes
// if( component instanceof AxialStage ){
// System.err.println(" Dumping AxialStage tree info for devel / debugging.");
// System.err.println(component.toDebugTree());
// }
//// General and General properties
tabbedPane.insertTab( trans.get("RailBtnCfg.tab.General"), null, buttonTab( (RailButton)component ), trans.get("RailBtnCfg.tab.GeneralProp"), 0);
@ -59,6 +52,33 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(new UnitSelector(ODModel), "growx");
panel.add(new BasicSlider(ODModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Inner Diameter
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.InnerDiam")));
DoubleModel IDModel = new DoubleModel(component, "InnerDiameter", UnitGroup.UNITS_LENGTH, 0);
JSpinner IDSpinner = new JSpinner(IDModel.getSpinnerModel());
IDSpinner.setEditor(new SpinnerEditor(IDSpinner));
panel.add(IDSpinner, "growx");
panel.add(new UnitSelector(IDModel), "growx");
panel.add(new BasicSlider(IDModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
}
{ //// Base Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.BaseHeight")));
DoubleModel heightModel = new DoubleModel(component, "BaseHeight", UnitGroup.UNITS_LENGTH, 0);
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Flange Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.FlangeHeight")));
DoubleModel heightModel = new DoubleModel(component, "FlangeHeight", UnitGroup.UNITS_LENGTH, 0);
JSpinner heightSpinner = new JSpinner(heightModel.getSpinnerModel());
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
}
{ //// Height
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.TotalHeight")));
DoubleModel heightModel = new DoubleModel(component, "TotalHeight", UnitGroup.UNITS_LENGTH, 0);
@ -66,7 +86,7 @@ public class RailButtonConfig extends RocketComponentConfig {
heightSpinner.setEditor(new SpinnerEditor(heightSpinner));
panel.add(heightSpinner, "growx");
panel.add(new UnitSelector(heightModel), "growx");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap");
panel.add(new BasicSlider(heightModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
}
{ //// Angular Position:
@ -79,14 +99,17 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(new BasicSlider( angleModel.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
}
primary.add(panel, "grow, gapright 201p");
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
{ //// Position relative to:
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.PosRelativeTo")));
final EnumModel<AxialMethod> methodModel = new EnumModel<AxialMethod>(component, "AxialMethod", AxialMethod.axialOffsetMethods );
JComboBox<AxialMethod> relToCombo = new JComboBox<AxialMethod>( methodModel );
panel.add( relToCombo, "spanx, growx, wrap");
}
{ //// plus
panel.add(new JLabel(trans.get("RailBtnCfg.lbl.Plus")), "right");
DoubleModel offsetModel = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
@ -96,17 +119,13 @@ public class RailButtonConfig extends RocketComponentConfig {
panel.add(offsetSpinner, "growx");
panel.add(new UnitSelector(offsetModel), "growx");
panel.add(new BasicSlider(offsetModel.getSliderModel(
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
new DoubleModel(component.getParent(), "Length"))),
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
new DoubleModel(component.getParent(), "Length"))),
"w 100lp, wrap para");
}
primary.add(panel, "grow, gapright 201p");
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
}
//// Instance count
panel.add( instanceablePanel(rbc), "span, wrap");
panel.add(instanceablePanel(rbc), "span, wrap");
//// Material
panel.add(materialPanel(Material.Type.BULK),"span, wrap");

View File

@ -385,7 +385,7 @@ public class RocketComponentConfig extends JPanel {
}
protected JPanel instanceablePanel( Instanceable inst ){
JPanel panel = new JPanel( new MigLayout("fill"));
JPanel panel = new JPanel( new MigLayout("fill, insets 0") );
{ // Instance Count
panel.add(new JLabel(trans.get("RocketCompCfg.lbl.InstanceCount")));
IntegerModel countModel = new IntegerModel(component, "InstanceCount", 1);
@ -401,7 +401,11 @@ public class RocketComponentConfig extends JPanel {
separationSpinner.setEditor(new SpinnerEditor(separationSpinner));
panel.add(separationSpinner, "growx");
panel.add(new UnitSelector(separationModel), "growx");
panel.add(new BasicSlider(separationModel.getSliderModel(0, 0.001, 0.02)), "w 100lp, wrap para");
double maxSeparationDistance = 0.1;
if (component.getParent() != null && component.getParent().getLength() > 0) {
maxSeparationDistance = component.getParent().getLength();
}
panel.add(new BasicSlider(separationModel.getSliderModel(0, 0.001, maxSeparationDistance)), "w 100lp, wrap para");
}
return panel;
}

View File

@ -91,7 +91,7 @@ public class MotorChooserDialog extends JDialog implements CloseableDialog {
// Set the closeable dialog after all initialization
selectionPanel.setCloseableDialog(this);
GUIUtil.setDisposableDialogOptions(this, cancelButton);
GUIUtil.setWindowIcons(this);
}
public void setMotorMountAndConfig( FlightConfigurationId _fcid, MotorMount _mount ) {

View File

@ -25,7 +25,9 @@ import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.TypedKey;
@ -43,6 +45,8 @@ public class ComponentPresetChooserDialog extends JDialog {
private static final Translator trans = Application.getTranslator();
private final SwingPreferences preferences = (SwingPreferences) Application.getPreferences();
private final RocketComponent component;
private ComponentPresetTable componentSelectionTable;
@ -149,7 +153,7 @@ public class ComponentPresetChooserDialog extends JDialog {
scrollpane.setViewportView(componentSelectionTable);
panel.add(scrollpane, "grow, width 700lp, height 300lp, pushy, spanx, wrap rel");
panel.add(new JLabel(Chars.UP_ARROW + " " + trans.get("lbl.favorites")), "spanx, gapleft 5px, wrap para");
panel.add(new StyledLabel(String.format("<html>%s %s</html>", Chars.UP_ARROW, trans.get("lbl.favorites")), -1), "spanx, gapleft 5px, wrap para");
// Close buttons
@ -222,12 +226,14 @@ public class ComponentPresetChooserDialog extends JDialog {
foreDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterForeDiameter"));
final SymmetricComponent prevSym = curSym.getPreviousSymmetricComponent();
if (prevSym != null && foreDiameterColumnIndex >= 0) {
foreDiameterFilterCheckBox.setSelected(preferences.isMatchForeDiameter());
foreDiameterFilter = new ComponentPresetRowFilter(prevSym.getAftRadius() * 2.0, foreDiameterColumnIndex);
panel.add(foreDiameterFilterCheckBox, "wrap");
foreDiameterFilterCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
updateFilters();
preferences.setMatchForeDiameter(foreDiameterFilterCheckBox.isSelected());
}
});
}
@ -238,12 +244,14 @@ public class ComponentPresetChooserDialog extends JDialog {
aftDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterAftDiameter"));
final SymmetricComponent nextSym = curSym.getNextSymmetricComponent();
if (nextSym != null && aftDiameterColumnIndex >= 0) {
aftDiameterFilterCheckBox.setSelected(preferences.isMatchAftDiameter());
aftDiameterFilter = new ComponentPresetRowFilter(nextSym.getForeRadius() * 2.0, aftDiameterColumnIndex);
panel.add(aftDiameterFilterCheckBox, "wrap");
aftDiameterFilterCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
updateFilters();
preferences.setMatchAftDiameter(aftDiameterFilterCheckBox.isSelected());
}
});
}

View File

@ -77,9 +77,11 @@ public class ComponentPresetTable extends JTable {
if ( columnIndex != 0 ) {
return;
}
int selectedRow = ComponentPresetTable.this.getSelectedRow();
ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex);
Application.getComponentPresetDao().setFavorite(preset, presetType, (Boolean) aValue);
ComponentPresetTable.this.updateFavorites();
ComponentPresetTable.this.setRowSelectionInterval(selectedRow, selectedRow);
}
@Override

View File

@ -33,7 +33,7 @@ public abstract class ComponentPresetTableColumn extends TableColumn {
@Override
public Object getValueFromPreset( Set<String> favorites, ComponentPreset preset ) {
return Boolean.valueOf(favorites.contains(preset.preferenceKey()));
return favorites.contains(preset.preferenceKey());
}
}

View File

@ -295,26 +295,37 @@ public class ComponentRenderer {
final double ir = r.getInnerDiameter() / 2.0;
gl.glRotated(r.getAngleOffset()*180/Math.PI -90 , 1, 0, 0);
//Inner Diameter
glu.gluCylinder(q, ir, ir, r.getTotalHeight(), LOD, 1);
// Base Cylinder
if (r.getBaseHeight() > 0) {
glu.gluCylinder(q, or, or, r.getBaseHeight(), LOD, 1);
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
glu.gluDisk(q, 0, or, LOD, 2);
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
gl.glTranslated(0, 0, r.getBaseHeight());
glu.gluDisk(q, 0, or, LOD, 2);
} else { // Draw a closing cap if there is no base
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
glu.gluDisk(q, 0, ir, LOD, 2);
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
gl.glTranslated(0, 0, r.getBaseHeight());
}
// Inner Cylinder
glu.gluCylinder(q, ir, ir, r.getInnerHeight(), LOD, 1);
//Bottom Disc
glu.gluCylinder(q, or, or, r.getBaseHeight(), LOD, 1);
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
glu.gluDisk(q, 0, or, LOD, 2);
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
gl.glTranslated(0,0,r.getBaseHeight());
glu.gluDisk(q, 0, or, LOD, 2);
//Upper Disc
gl.glTranslated(0,0,r.getTotalHeight() - r.getFlangeHeight() * 2.0);
glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1);
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
glu.gluDisk(q, 0, or, LOD, 2);
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
gl.glTranslated(0,0,r.getFlangeHeight());
glu.gluDisk(q, 0, or, LOD, 2);
// Flange Cylinder
if (r.getFlangeHeight() > 0) {
gl.glTranslated(0, 0, r.getInnerHeight());
glu.gluCylinder(q, or, or, r.getFlangeHeight(), LOD, 1);
glu.gluQuadricOrientation(q, GLU.GLU_INSIDE);
glu.gluDisk(q, 0, or, LOD, 2);
glu.gluQuadricOrientation(q, GLU.GLU_OUTSIDE);
gl.glTranslated(0, 0, r.getFlangeHeight());
glu.gluDisk(q, 0, or, LOD, 2);
} else { // Draw a closing cap if there is no flange
gl.glTranslated(0, 0, r.getInnerHeight());
glu.gluDisk(q, 0, ir, LOD, 2);
}
}
}

View File

@ -418,18 +418,18 @@ public class BasicFrame extends JFrame {
button = new SelectColorButton(actions.getMoveDownAction());
panel.add(button, "sizegroup buttons, aligny 0%");
button = new SelectColorButton(actions.getEditAction());
button.setIcon(null);
button = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(button, actions.getEditAction());
button.setMnemonic(0);
panel.add(button, "sizegroup buttons, gaptop 20%");
button = new SelectColorButton(actions.getDuplicateAction());
button.setIcon(null);
button = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(button, actions.getDuplicateAction());
button.setMnemonic(0);
panel.add(button, "sizegroup buttons");
button = new SelectColorButton(actions.getDeleteAction());
button.setIcon(null);
button = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(button, actions.getDeleteAction());
button.setMnemonic(0);
panel.add(button, "sizegroup buttons");

View File

@ -12,6 +12,7 @@ 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;
@ -189,6 +190,35 @@ public class RocketActions {
return moveDownAction;
}
/**
* Tie an action to a JButton, without using the icon or text of the action for the button.
*
* For any smartass that wants to know why you don't just initialize the JButton with the action and then set the
* icon to null and set the button text: this causes a bug where the text of the icon becomes much smaller than is intended.
*
* @param button button to tie the action to
* @param action action to tie to the button
* @param text text to display on the button
*/
public static void tieActionToButtonNoIcon(JButton button, Action action, String text) {
button.setAction(action);
button.setIcon(null);
button.setText(text);
}
/**
* Tie an action to a JButton, without using the icon of the action for the button.
*
* For any smartass that wants to know why you don't just initialize the JButton with the action and then set the
* icon to null: this causes a bug where the text of the icon becomes much smaller than is intended.
*
* @param button button to tie the action to
* @param action action to tie to the button
*/
public static void tieActionToButtonNoIcon(JButton button, Action action) {
button.setAction(action);
button.setIcon(null);
}
//////// Helper methods for the actions

View File

@ -10,7 +10,6 @@ import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@ -98,365 +97,81 @@ public class SimulationPanel extends JPanel {
private final JButton plotButton;
private final JPopupMenu pm;
private final SimulationAction editSimulationAction;
private final SimulationAction runSimulationAction;
private final SimulationAction plotSimulationAction;
private final SimulationAction duplicateSimulationAction;
private final SimulationAction deleteSimulationAction;
public SimulationPanel(OpenRocketDocument doc) {
super(new MigLayout("fill", "[grow][][][][][][grow]"));
this.document = doc;
// Simulation actions
SimulationAction newSimulationAction = new NewSimulationAction();
editSimulationAction = new EditSimulationAction();
runSimulationAction = new RunSimulationAction();
plotSimulationAction = new PlotSimulationAction();
duplicateSimulationAction = new DuplicateSimulationAction();
deleteSimulationAction = new DeleteSimulationAction();
//////// The simulation action buttons
//////// The simulation action buttons ////////
//// New simulation button
{
JButton button = new SelectColorButton(trans.get("simpanel.but.newsimulation"));
//// Add a new simulation
button.setToolTipText(trans.get("simpanel.but.ttip.newsimulation"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Simulation sim = new Simulation(document.getRocket());
sim.setName(document.getNextSimulationName());
int n = document.getSimulationCount();
document.addSimulation(sim);
simulationTableModel.fireTableDataChanged();
simulationTable.clearSelection();
simulationTable.addRowSelectionInterval(n, n);
openDialog(false, sim);
}
});
this.add(button, "skip 1, gapright para");
}
JButton newButton = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(newButton, newSimulationAction, trans.get("simpanel.but.newsimulation"));
newButton.setToolTipText(trans.get("simpanel.but.ttip.newsimulation"));
this.add(newButton, "skip 1, gapright para");
//// Edit simulation button
editButton = new SelectColorButton(trans.get("simpanel.but.editsimulation"));
//// Edit the selected simulation
editButton = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(editButton, editSimulationAction, trans.get("simpanel.but.editsimulation"));
editButton.setToolTipText(trans.get("simpanel.but.ttip.editsim"));
editButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
editSimulation();
}
});
this.add(editButton, "gapright para");
//// Run simulations
runButton = new SelectColorButton(trans.get("simpanel.but.runsimulations"));
//// Re-run the selected simulations
runButton = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(runButton, runSimulationAction, trans.get("simpanel.but.runsimulations"));
runButton.setToolTipText(trans.get("simpanel.but.ttip.runsimu"));
runButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
runSimulation();
}
});
this.add(runButton, "gapright para");
//// Delete simulations button
deleteButton = new SelectColorButton(trans.get("simpanel.but.deletesimulations"));
//// Delete the selected simulations
deleteButton = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(deleteButton, deleteSimulationAction, trans.get("simpanel.but.deletesimulations"));
deleteButton.setToolTipText(trans.get("simpanel.but.ttip.deletesim"));
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteSimulation();
}
});
this.add(deleteButton, "gapright para");
//// Plot / export button
plotButton = new SelectColorButton(trans.get("simpanel.but.plotexport"));
// button = new SelectColorButton("Plot flight");
plotButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
plotSimulation();
}
});
plotButton = new SelectColorButton();
RocketActions.tieActionToButtonNoIcon(plotButton, plotSimulationAction, trans.get("simpanel.but.plotexport"));
this.add(plotButton, "wrap para");
//////// The simulation table
simulationTableModel = new ColumnTableModel(
//// Status and warning column
new Column("") {
private JLabel label = null;
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
// Initialize the label
if (label == null) {
label = new StyledLabel(2f);
label.setIconTextGap(1);
// label.setFont(label.getFont().deriveFont(Font.BOLD));
}
// Set simulation status icon
Simulation.Status status = document.getSimulation(row).getStatus();
label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status));
// Set warning marker
if (status == Simulation.Status.NOT_SIMULATED ||
status == Simulation.Status.EXTERNAL) {
label.setText("");
} else {
WarningSet w = document.getSimulation(row).getSimulatedWarnings();
if (w == null) {
label.setText("");
} else if (w.isEmpty()) {
label.setForeground(OK_COLOR);
label.setText(OK_TEXT);
} else {
label.setForeground(WARNING_COLOR);
label.setText(WARNING_TEXT);
}
}
return label;
}
@Override
public int getExactWidth() {
return 36;
}
@Override
public Class<?> getColumnClass() {
return JLabel.class;
}
},
//// Simulation name
//// Name
new Column(trans.get("simpanel.col.Name")) {
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
return document.getSimulation(row).getName();
}
@Override
public int getDefaultWidth() {
return 125;
}
@Override
public Comparator<String> getComparator() {
return new AlphanumComparator();
}
},
//// Simulation configuration
new Column(trans.get("simpanel.col.Configuration")) {
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount()){
return null;
}
Rocket rkt = document.getRocket();
FlightConfigurationId fcid = document.getSimulation(row).getId();
return descriptor.format( rkt, fcid);
}
@Override
public int getDefaultWidth() {
return 125;
}
},
//// Launch rod velocity
new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getLaunchRodVelocity();
}
},
//// Apogee
new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxAltitude();
}
},
//// Velocity at deployment
new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getDeploymentVelocity();
}
},
//// Deployment Time from Apogee
new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"),
trans.get("simpanel.col.OptimumCoastTime.ttip"),
UnitGroup.UNITS_SHORT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null || data.getBranchCount() == 0)
return null;
double val = data.getBranch(0).getOptimumDelay();
if ( Double.isNaN(val) ) {
return null;
}
return val;
}
},
//// Maximum velocity
new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxVelocity();
}
},
//// Maximum acceleration
new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxAcceleration();
}
},
//// Time to apogee
new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getTimeToApogee();
}
},
//// Flight time
new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getFlightTime();
}
},
//// Ground hit velocity
new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getGroundHitVelocity();
}
}
) {
private static final long serialVersionUID = 8686456963492628476L;
@Override
public int getRowCount() {
return document.getSimulationCount();
}
};
simulationTableModel = new SimulationTableModel();
// Override processKeyBinding so that the JTable does not catch
// key bindings used in menu accelerators
simulationTable = new ColumnTable(simulationTableModel) {
private static final long serialVersionUID = -5799340181229735630L;
@Override
protected boolean processKeyBinding(KeyStroke ks,
KeyEvent e,
int condition,
boolean pressed) {
return false;
}
};
ColumnTableRowSorter simulationTableSorter = new ColumnTableRowSorter(simulationTableModel);
simulationTable.setRowSorter(simulationTableSorter);
simulationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer());
simulationTableModel.setColumnWidths(simulationTable.getColumnModel());
pm = new JPopupMenu();
pm.add(new EditSimulationAction());
pm.add(new DuplicateSimulationAction());
pm.add(new DeleteSimulationAction());
pm.addSeparator();
pm.add(new RunSimulationAction());
pm.add(new PlotSimulationAction());
// Context menu
pm = new JPopupMenu();
pm.add(editSimulationAction);
pm.add(duplicateSimulationAction);
pm.add(deleteSimulationAction);
pm.addSeparator();
pm.add(runSimulationAction);
pm.add(plotSimulationAction);
// Mouse listener to act on double-clicks
@ -496,11 +211,14 @@ public class SimulationPanel extends JPanel {
});
simulationTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
private int previousRow = -1;
private int previousSelectedRow = -1;
private int previousSelectedRowCount = 0;
public void valueChanged(ListSelectionEvent event) {
if (simulationTable.getSelectedRow() != previousRow) {
if ((simulationTable.getSelectedRow() != previousSelectedRow) ||
(simulationTable.getSelectedRowCount() != previousSelectedRowCount)) {
updateButtonStates();
previousRow = simulationTable.getSelectedRow();
previousSelectedRow = simulationTable.getSelectedRow();
previousSelectedRowCount = simulationTable.getSelectedRowCount();
}
}
});
@ -532,6 +250,19 @@ public class SimulationPanel extends JPanel {
updateButtonStates();
}
private void newSimulation() {
Simulation sim = new Simulation(document.getRocket());
sim.setName(document.getNextSimulationName());
int n = document.getSimulationCount();
document.addSimulation(sim);
simulationTableModel.fireTableDataChanged();
simulationTable.clearSelection();
simulationTable.addRowSelectionInterval(n, n);
openDialog(false, sim);
}
private void plotSimulation() {
int selected = simulationTable.getSelectedRow();
if (selected < 0) {
@ -690,23 +421,11 @@ public class SimulationPanel extends JPanel {
}
private void updateButtonStates() {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
editButton.setEnabled(false);
runButton.setEnabled(false);
deleteButton.setEnabled(false);
plotButton.setEnabled(false);
} else {
if (selection.length > 1) {
plotButton.setEnabled(false);
} else {
plotButton.setEnabled(true);
}
editButton.setEnabled(true);
runButton.setEnabled(true);
deleteButton.setEnabled(true);
}
editSimulationAction.updateEnabledState();
deleteSimulationAction.updateEnabledState();
runSimulationAction.updateEnabledState();
plotSimulationAction.updateEnabledState();
duplicateSimulationAction.updateEnabledState();
}
/// when the simulation tab is selected this run outdated simulated if appropriate.
@ -778,7 +497,31 @@ public class SimulationPanel extends JPanel {
}
}
class EditSimulationAction extends AbstractAction {
private abstract static class SimulationAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public abstract void updateEnabledState();
}
class NewSimulationAction extends SimulationAction {
public NewSimulationAction() {
putValue(NAME, trans.get("simpanel.but.newsimulation"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_N);
this.putValue(SMALL_ICON, Icons.FILE_NEW);
}
@Override
public void actionPerformed(ActionEvent e) {
newSimulation();
}
@Override
public void updateEnabledState() {
setEnabled(true);
}
}
class EditSimulationAction extends SimulationAction {
public EditSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.edit"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
@ -790,9 +533,14 @@ public class SimulationPanel extends JPanel {
public void actionPerformed(ActionEvent e) {
editSimulation();
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() == 1);
}
}
class RunSimulationAction extends AbstractAction {
class RunSimulationAction extends SimulationAction {
public RunSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.run"));
putValue(SMALL_ICON, Icons.SIM_RUN);
@ -802,9 +550,14 @@ public class SimulationPanel extends JPanel {
public void actionPerformed(ActionEvent e) {
runSimulation();
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() > 0);
}
}
class DeleteSimulationAction extends AbstractAction {
class DeleteSimulationAction extends SimulationAction {
public DeleteSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.delete"));
putValue(MNEMONIC_KEY, KeyEvent.VK_D);
@ -816,9 +569,14 @@ public class SimulationPanel extends JPanel {
public void actionPerformed(ActionEvent e) {
deleteSimulation();
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() > 0);
}
}
class PlotSimulationAction extends AbstractAction {
class PlotSimulationAction extends SimulationAction {
public PlotSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.plot"));
putValue(SMALL_ICON, Icons.SIM_PLOT);
@ -828,9 +586,14 @@ public class SimulationPanel extends JPanel {
public void actionPerformed(ActionEvent e) {
plotSimulation();
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() == 1);
}
}
class DuplicateSimulationAction extends AbstractAction {
class DuplicateSimulationAction extends SimulationAction {
public DuplicateSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.duplicate"));
putValue(MNEMONIC_KEY, KeyEvent.VK_D);
@ -842,7 +605,12 @@ public class SimulationPanel extends JPanel {
public void actionPerformed(ActionEvent e) {
duplicateSimulation();
}
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() > 0);
}
}
public static class CellTransferable implements Transferable {
@ -955,6 +723,254 @@ public class SimulationPanel extends JPanel {
return tip;
}
}
private class SimulationTableModel extends ColumnTableModel {
private static final long serialVersionUID = 8686456963492628476L;
public SimulationTableModel() {
super(
//// Status and warning column
new Column("") {
private JLabel label = null;
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
// Initialize the label
if (label == null) {
label = new StyledLabel(2f);
label.setIconTextGap(1);
// label.setFont(label.getFont().deriveFont(Font.BOLD));
}
// Set simulation status icon
Simulation.Status status = document.getSimulation(row).getStatus();
label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status));
// Set warning marker
if (status == Simulation.Status.NOT_SIMULATED ||
status == Simulation.Status.EXTERNAL) {
label.setText("");
} else {
WarningSet w = document.getSimulation(row).getSimulatedWarnings();
if (w == null) {
label.setText("");
} else if (w.isEmpty()) {
label.setForeground(OK_COLOR);
label.setText(OK_TEXT);
} else {
label.setForeground(WARNING_COLOR);
label.setText(WARNING_TEXT);
}
}
return label;
}
@Override
public int getExactWidth() {
return 36;
}
@Override
public Class<?> getColumnClass() {
return JLabel.class;
}
},
//// Simulation name
//// Name
new Column(trans.get("simpanel.col.Name")) {
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
return document.getSimulation(row).getName();
}
@Override
public int getDefaultWidth() {
return 125;
}
@Override
public Comparator<String> getComparator() {
return new AlphanumComparator();
}
},
//// Simulation configuration
new Column(trans.get("simpanel.col.Configuration")) {
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount()) {
return null;
}
Rocket rkt = document.getRocket();
FlightConfigurationId fcid = document.getSimulation(row).getId();
return descriptor.format(rkt, fcid);
}
@Override
public int getDefaultWidth() {
return 125;
}
},
//// Launch rod velocity
new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getLaunchRodVelocity();
}
},
//// Apogee
new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxAltitude();
}
},
//// Velocity at deployment
new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getDeploymentVelocity();
}
},
//// Deployment Time from Apogee
new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"),
trans.get("simpanel.col.OptimumCoastTime.ttip"), UnitGroup.UNITS_SHORT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null || data.getBranchCount() == 0)
return null;
double val = data.getBranch(0).getOptimumDelay();
if (Double.isNaN(val)) {
return null;
}
return val;
}
},
//// Maximum velocity
new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxVelocity();
}
},
//// Maximum acceleration
new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getMaxAcceleration();
}
},
//// Time to apogee
new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getTimeToApogee();
}
},
//// Flight time
new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getFlightTime();
}
},
//// Ground hit velocity
new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) {
@Override
public Double valueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
FlightData data = document.getSimulation(row).getSimulatedData();
if (data == null)
return null;
return data.getGroundHitVelocity();
}
}
);
}
@Override
public int getRowCount() {
return document.getSimulationCount();
}
}
}

View File

@ -6,6 +6,9 @@ import javax.swing.ToolTipManager;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.components.BasicTree;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@SuppressWarnings("serial")
public class ComponentTree extends BasicTree {
@ -13,7 +16,21 @@ public class ComponentTree extends BasicTree {
public ComponentTree(OpenRocketDocument document) {
super();
this.setModel(new ComponentTreeModel(document.getRocket(), this));
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_A) && ((e.getModifiersEx() & KeyEvent.META_DOWN_MASK) != 0)) {
setSelectionInterval(1, getRowCount()); // Don't select the rocket (row 0)
}
}
@Override
public void keyReleased(KeyEvent e) { }
});
this.setCellRenderer(new ComponentTreeRenderer());
this.setDragEnabled(true);

View File

@ -1582,8 +1582,8 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
rbHeight.setValue(preset.get(ComponentPreset.HEIGHT));
rbHeight.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
}
if (preset.has(ComponentPreset.STANDOFF_HEIGHT)) {
rbStandoffHeight.setValue(preset.get(ComponentPreset.STANDOFF_HEIGHT));
if (preset.has(ComponentPreset.BASE_HEIGHT)) {
rbStandoffHeight.setValue(preset.get(ComponentPreset.BASE_HEIGHT));
rbStandoffHeight.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
}
if (preset.has(ComponentPreset.FLANGE_HEIGHT)) {
@ -1610,8 +1610,8 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
pcDiameter.setValue(preset.get(ComponentPreset.DIAMETER));
pcDiameter.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
}
if (preset.has(ComponentPreset.PARACHUTE_CD)) {
pcDragCoefficient.setValue(preset.get(ComponentPreset.PARACHUTE_CD));
if (preset.has(ComponentPreset.CD)) {
pcDragCoefficient.setValue(preset.get(ComponentPreset.CD));
pcDragCoefficient.setCurrentUnit(UnitGroup.UNITS_COEFFICIENT.getDefaultUnit());
}
setMaterial(materialChooser, preset, matHolder, Material.Type.SURFACE, ComponentPreset.MATERIAL);
@ -2132,7 +2132,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
props.put(ComponentPreset.TYPE, ComponentPreset.Type.RAIL_BUTTON);
props.put(ComponentPreset.OUTER_DIAMETER, rbOuterDia.getValue());
props.put(ComponentPreset.INNER_DIAMETER, rbInnerDia.getValue());
props.put(ComponentPreset.STANDOFF_HEIGHT, rbStandoffHeight.getValue());
props.put(ComponentPreset.BASE_HEIGHT, rbStandoffHeight.getValue());
props.put(ComponentPreset.FLANGE_HEIGHT, rbFlangeHeight.getValue());
props.put(ComponentPreset.DESCRIPTION, rbDescTextField.getText());
props.put(ComponentPreset.PARTNO, rbPartNoTextField.getText());
@ -2179,7 +2179,7 @@ public class PresetEditorDialog extends JDialog implements ItemListener {
props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
props.put(ComponentPreset.PARTNO, pcPartNoTextField.getText());
props.put(ComponentPreset.DESCRIPTION, pcDescTextField.getText());
props.put(ComponentPreset.PARACHUTE_CD, pcDragCoefficient.getValue());
props.put(ComponentPreset.CD, pcDragCoefficient.getValue());
Material material = (Material) materialChooser.getSelectedItem();
if (material != null) {
props.put(ComponentPreset.MATERIAL, material);

View File

@ -29,7 +29,7 @@ public class RailButtonShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
final RailButton btn = (RailButton)component;
final double baseHeight = btn.getStandoff();
final double baseHeight = btn.getBaseHeight();
final double innerHeight = btn.getInnerHeight();
final double flangeHeight = btn.getFlangeHeight();
@ -53,72 +53,73 @@ public class RailButtonShapes extends RocketComponentShape {
Path2D.Double path = new Path2D.Double();
Path2D.Double pathInvis = new Path2D.Double(); // Path for the invisible triangles
{// central pillar
final double drawWidth = outerDiameter;
final double drawHeight = outerDiameter*sinr;
final Point2D.Double center = new Point2D.Double( loc.x, loc.y );
Point2D.Double lowerLeft = new Point2D.Double( center.x - outerRadius, center.y-outerRadius*sinr);
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+baseHeightcos) ), false);
path.append( new Line2D.Double( (center.x+outerRadius), center.y, (center.x+outerRadius), (center.y+baseHeightcos) ), false);
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+baseHeightcos), drawWidth, drawHeight), false);
{// base cylinder
if (baseHeight > 0) {
final double drawWidth = outerDiameter;
final double drawHeight = outerDiameter * sinr;
final Point2D.Double center = new Point2D.Double(loc.x, loc.y);
Point2D.Double lowerLeft = new Point2D.Double(center.x - outerRadius, center.y - outerRadius * sinr);
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
// Invisible rectangle
double y_invis;
if (baseHeightcos >= 0) {
y_invis = center.y;
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + baseHeightcos)), false);
path.append(new Line2D.Double((center.x + outerRadius), center.y, (center.x + outerRadius), (center.y + baseHeightcos)), false);
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + baseHeightcos), drawWidth, drawHeight), false);
// Invisible rectangle
double y_invis;
if (baseHeightcos >= 0) {
y_invis = center.y;
} else {
y_invis = center.y + baseHeightcos;
}
pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(baseHeightcos)), false);
}
else {
y_invis = center.y + baseHeightcos;
}
pathInvis.append(new Rectangle2D.Double(center.x-outerRadius, y_invis, drawWidth, Math.abs(baseHeightcos)), false);
}
{// inner flange
{// inner cylinder
final double drawWidth = innerDiameter;
final double drawHeight = innerDiameter*sinr;
final Point2D.Double center = new Point2D.Double( loc.x, loc.y + baseHeightcos);
final Point2D.Double lowerLeft = new Point2D.Double( center.x - innerRadius, center.y-innerRadius*sinr);
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+innerHeightcos) ), false);
path.append( new Line2D.Double( (center.x+innerRadius), center.y, (center.x+innerRadius), (center.y+innerHeightcos) ), false);
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+innerHeightcos), drawWidth, drawHeight), false);
final double drawHeight = innerDiameter * sinr;
final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos);
final Point2D.Double lowerLeft = new Point2D.Double(center.x - innerRadius, center.y - innerRadius * sinr);
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + innerHeightcos)), false);
path.append(new Line2D.Double((center.x + innerRadius), center.y, (center.x + innerRadius), (center.y + innerHeightcos)), false);
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + innerHeightcos), drawWidth, drawHeight), false);
// Invisible rectangle
double y_invis;
if (innerHeightcos >= 0) {
y_invis = center.y;
}
else {
} else {
y_invis = center.y + innerHeightcos;
}
pathInvis.append(new Rectangle2D.Double(center.x-innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false);
pathInvis.append(new Rectangle2D.Double(center.x - innerRadius, y_invis, drawWidth, Math.abs(innerHeightcos)), false);
}
{// outer flange
final double drawWidth = outerDiameter;
final double drawHeight = outerDiameter*sinr;
final Point2D.Double center = new Point2D.Double( loc.x, loc.y+baseHeightcos+innerHeightcos);
final Point2D.Double lowerLeft = new Point2D.Double( center.x - outerRadius, center.y-outerRadius*sinr);
path.append( new Ellipse2D.Double( lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
path.append( new Line2D.Double( lowerLeft.x, center.y, lowerLeft.x, (center.y+flangeHeightcos) ), false);
path.append( new Line2D.Double( (center.x+outerRadius), center.y, (center.x+outerRadius), (center.y+flangeHeightcos) ), false);
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+flangeHeightcos), drawWidth, drawHeight), false);
{// flange cylinder
if (flangeHeight > 0) {
final double drawWidth = outerDiameter;
final double drawHeight = outerDiameter * sinr;
final Point2D.Double center = new Point2D.Double(loc.x, loc.y + baseHeightcos + innerHeightcos);
final Point2D.Double lowerLeft = new Point2D.Double(center.x - outerRadius, center.y - outerRadius * sinr);
path.append(new Ellipse2D.Double(lowerLeft.x, lowerLeft.y, drawWidth, drawHeight), false);
// Invisible rectangle
double y_invis;
if (flangeHeightcos >= 0) {
y_invis = center.y;
path.append(new Line2D.Double(lowerLeft.x, center.y, lowerLeft.x, (center.y + flangeHeightcos)), false);
path.append(new Line2D.Double((center.x + outerRadius), center.y, (center.x + outerRadius), (center.y + flangeHeightcos)), false);
path.append(new Ellipse2D.Double(lowerLeft.x, (lowerLeft.y + flangeHeightcos), drawWidth, drawHeight), false);
// Invisible rectangle
double y_invis;
if (flangeHeightcos >= 0) {
y_invis = center.y;
} else {
y_invis = center.y + flangeHeightcos;
}
pathInvis.append(new Rectangle2D.Double(center.x - outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false);
}
else {
y_invis = center.y + flangeHeightcos;
}
pathInvis.append(new Rectangle2D.Double(center.x-outerRadius, y_invis, drawWidth, Math.abs(flangeHeightcos)), false);
}
RocketComponentShape[] shapes = RocketComponentShape.toArray(new Shape[]{ path }, component);
@ -136,7 +137,7 @@ public class RailButtonShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
final RailButton btn = (RailButton)component;
final double baseHeight = btn.getStandoff();
final double baseHeight = btn.getBaseHeight();
final double innerHeight = btn.getInnerHeight();
final double flangeHeight = btn.getFlangeHeight();
@ -159,7 +160,9 @@ public class RailButtonShapes extends RocketComponentShape {
Path2D.Double path = new Path2D.Double();
// base
path.append( getRotatedRectangle( loc.z, loc.y, outerRadius, baseHeight, combined_angle_rad), false );
if (baseHeight > 0) {
path.append(getRotatedRectangle(loc.z, loc.y, outerRadius, baseHeight, combined_angle_rad), false);
}
{// inner
final double delta_r = baseHeight;
@ -167,11 +170,13 @@ public class RailButtonShapes extends RocketComponentShape {
final double delta_z = delta_r*sinr;
path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, innerRadius, innerHeight, combined_angle_rad), false);
}
{// outer flange
final double delta_r = baseHeight + innerHeight;
final double delta_y = delta_r*cosr;
final double delta_z = delta_r*sinr;
path.append( getRotatedRectangle( loc.z+delta_z, loc.y+delta_y, outerRadius, flangeHeight, combined_angle_rad), false);
{// flange
if (flangeHeight > 0) {
final double delta_r = baseHeight + innerHeight;
final double delta_y = delta_r * cosr;
final double delta_z = delta_r * sinr;
path.append(getRotatedRectangle(loc.z + delta_z, loc.y + delta_y, outerRadius, flangeHeight, combined_angle_rad), false);
}
}
return RocketComponentShape.toArray( new Shape[]{ path }, component);